ailiteracynepal 🇳🇵
Text size

Chapter 02 · Section III · 30 min read

Reading and writing files: CSV, JSON, and text

Data lives in files. Three formats — plain text, CSV, JSON — cover almost every file you will touch in this track. Learn to move data in and out of all three and the rest of the course can begin.

Until now every list, dictionary, and table in this chapter has lived inside the program — typed by hand into a notebook cell, gone the moment you close the kernel. Real data does not live inside programs. It lives in files: a CSV someone exported from a bank account, a JSON file an API returned, a plain text log of receipts you typed last week. This section is about getting that data into your program — and getting your program’s results back out, into something you can email, share, or open in Excel.

Three formats cover most of what you will meet

In four courses of building, three file formats will account for almost every file you touch:

  1. Plain text — a .txt file, a .log file, a Markdown note. Lines of characters and nothing more.
  2. CSV — Comma-Separated Values. A spreadsheet flattened into text. One row per line, columns separated by commas. Almost every export from Excel, Sheets, NEPSE, or a bank statement comes out as CSV.
  3. JSON — JavaScript Object Notation. Nested data with named fields. Almost every API response on the modern internet is JSON.

Plain text is the easiest. CSV is the most common. JSON is the most expressive. We will do them in that order.

Where files live

Before you open a file, you have to know where it is. A program runs in a current working directory — usually the folder you opened in VS Code, or wherever your notebook is saved.

A small piece of practice: in your building-ai-notes folder, make a new folder called data. We will put example files in there. When you write open("data/prices.csv"), Python looks for a folder called data inside the current working directory, and inside it, a file called prices.csv.

If you ever get a FileNotFoundError, it almost always means: the file is not where you think it is, or you are not where you think you are. Both are fixable in thirty seconds once you understand the question.

Reading and writing plain text

The simplest case. A file called data/notes.txt with two lines:

Bought sabji from Lokanthali — Rs 380
Diesel for the bike — Rs 600

To read the whole file as one string:

with open("data/notes.txt") as f:
    contents = f.read()

print(contents)

To read it line by line — usually what you want for anything more than tiny files:

with open("data/notes.txt") as f:
    for line in f:
        print(line.strip())

.strip() removes the trailing newline character that comes with each line.

To write a file:

with open("data/output.txt", "w") as f:
    f.write("Hello from a Python program.\n")

A few things to carry forward:

  • The with open(...) as f: pattern is the right way to open a file in modern Python. When the indented block ends, Python automatically closes the file. You do not need to remember to do it yourself.
  • The second argument is the mode. "r" is read (the default), "w" is write (and silently overwrites any existing file with that name), "a" is append (add to the end). When you are first using "w", double-check the path. Overwriting a file you wanted to keep is a real and unhappy beginner experience.

Reading a CSV

Almost every dataset you will work with in Course 02 onwards arrives as a CSV. A small example. Put this in data/prices.csv:

date,close
2026-06-23,2105.4
2026-06-24,2128.9
2026-06-25,2117.3
2026-06-26,2134.7

The first line is the header: it names the columns. Every line after is a row, with comma-separated values matching the column order.

Python has a built-in csv module. The friendliest tool in it is DictReader, which reads each row as a dictionary keyed by the header columns — exactly the list-of-dictionaries shape from Section 1:

import csv

with open("data/prices.csv") as f:
    reader = csv.DictReader(f)
    rows = list(reader)

print(rows[0])              # {'date': '2026-06-23', 'close': '2105.4'}
print(rows[0]["close"])     # '2105.4'

Notice the price came back as a string ('2105.4'), not a number. CSV is a text format — everything inside it is text. If you want to do arithmetic, you convert:

for row in rows:
    row["close"] = float(row["close"])

After this, rows[0]["close"] is the number 2105.4 and you can sum it, average it, plot it.

To write a CSV, the inverse:

import csv

summaries = [
    {"date": "2026-06-23", "summary": "Up 1.1%"},
    {"date": "2026-06-24", "summary": "Up 1.1%"},
]

with open("data/summaries.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=["date", "summary"])
    writer.writeheader()
    writer.writerows(summaries)

The newline="" is a small Windows-specific quirk that prevents blank lines between rows. Include it; you will not need to think about it again.

Reading and writing JSON

JSON is what almost every web API returns. It looks a lot like a Python dictionary — and in fact Python’s json module converts between the two almost effortlessly.

A small example. Put this in data/profile.json:

{
  "name": "AI Literacy Nepal",
  "tracks": ["learning", "building", "professionals"],
  "active": true,
  "learners": 1240
}

To read it:

import json

with open("data/profile.json") as f:
    profile = json.load(f)

print(profile["name"])      # "AI Literacy Nepal"
print(profile["tracks"])    # ['learning', 'building', 'professionals']

After json.load(...), profile is just a regular Python dictionary. The keys, lists, numbers, and booleans all map across without effort.

To write JSON, the inverse:

import json

result = {
    "vendor": "Khalti",
    "total_today": 5450,
    "transaction_count": 2,
}

with open("data/result.json", "w") as f:
    json.dump(result, f, indent=2)

The indent=2 argument is a kindness to anyone (including you) who later opens the file in an editor — it formats the JSON across multiple lines instead of cramming it onto one. Strictly optional, but always worth including.

Two close cousins that work on strings rather than files:

  • json.loads(s) (note the s) — parse a JSON string into a Python object.
  • json.dumps(obj) — serialize a Python object into a JSON string.

You will use these constantly in Course 04 when language models return JSON in their replies.

A small end-to-end example

Putting the chapter together. Read prices from a CSV, compute the average, write a JSON summary:

import csv
import json

with open("data/prices.csv") as f:
    rows = list(csv.DictReader(f))

for row in rows:
    row["close"] = float(row["close"])

average = sum(r["close"] for r in rows) / len(rows)

summary = {
    "instrument": "NEPSE Index",
    "average_close": round(average, 2),
    "days_observed": len(rows),
}

with open("data/summary.json", "w") as f:
    json.dump(summary, f, indent=2)

print(summary)

Read that program. Every piece in it comes from this chapter: a list of dictionaries (the rows), a loop (the type conversion), a built-in function (sum, len, round), file reading (CSV), file writing (JSON). It is the smallest realistic version of a data pipeline — read, transform, write — and it is exactly what most of your Course 02 and Course 03 work will look like.

Check your understanding

Quick check

You read a CSV with csv.DictReader and immediately try `rows[0]['close'] + 100`. Python raises a TypeError. Why?

Quick check

A junior engineer writes: with open('config.json', 'w') as f: f.write('{updated}') What is dangerous about this code?

What comes next — and a small reflection

This chapter is the end of Course 01’s “plain Python” arc. You can hold data in shapes, move it through loops and functions, and read and write it to disk. Almost every program you write for the rest of the track is some recombination of those three.

Chapter 3 takes a step up. We move from plain Python lists to NumPy arrays (faster), from plain Python dictionaries to pandas DataFrames (more powerful), and from print statements to matplotlib plots (charts you can actually look at). These three libraries are the numerical toolkit of every working data person in the world — including everyone building AI.

Before you turn the page, look back at the small problem you wrote down in Section 1. You can now almost certainly read its data — whatever form it takes — into a Python program. That is not a small thing.