ይህ ትምህርት ገና ወደ አማርኛ አልተተረጎመም፤ ስለዚህ በእንግሊዝኛ ቀርቧል። የእንግሊዝኛውን ገጽ ክፈቱ
JSON
CSV is right for flat tables, but the contact book from lesson 4.9 is a dict, and a ledger is a list of dicts. JSON saves lists and dicts as text and loads them back. By the end of this lesson you'll save the contact book to a file, keep Amharic readable in it, and know the two things that change on the way back.
Saving a dict
is a text format for nested data: dicts, lists, strings, numbers, true, false, and
null. Almost every language and website can read it. Python's json module turns your
data into JSON text, which is called
it, and turns JSON text back into data:
import json
contacts = {"Selam": "0900 000 003", "Abel": "0900 000 001"}
with open("contacts.json", "w", encoding="utf-8") as f:
json.dump(contacts, f)
with open("contacts.json", encoding="utf-8") as f:
loaded = json.load(f)
print(loaded)
print(loaded == contacts)In the editor, press Escape then Tab to move on.
writes the data to an open file as JSON;
reads it back as a new dict. Look at contacts.json in Files: it looks a lot like
Python, but JSON always uses double quotes. json.dumps() and json.loads(), with an
s for string, do the same with a string instead of a file.
Amharic in JSON
Save a contact whose name is in Amharic, and JSON does something you might not expect. Predict:
ውጤቱን ገምቱ
Decide before you look. Guessing wrong is how this sticks.
import json
print(json.dumps("ሰላም"))Python prints
"\u1230\u120b\u121d"
By default, json.dumps writes every character beyond the basic English letters, digits, and symbols as a \u escape, its code point in hex. 1230 is ሰ, from lesson 6.3. The quotes are JSON's own: a JSON string always has them.
By default, json writes every character beyond the basic English letters, digits,
and symbols as \u and its code point in hex, the escape from lesson 6.3: \u1230 is
ሰ. It's still correct JSON and loads back as ሰላም, but a person can't read the file. ensure_ascii=False keeps the characters as they
are, and indent=2 puts each item on its own line:
import json
contacts = {"ሰላም": "0900 000 003", "Abel": "0900 000 001"}
with open("contacts.json", "w", encoding="utf-8") as f:
json.dump(contacts, f, ensure_ascii=False, indent=2)
print(json.loads(json.dumps("ሰላም")) == "ሰላም")In the editor, press Escape then Tab to move on.
Open contacts.json in Files. This is the line to remember for saving:
json.dump(data, f, ensure_ascii=False, indent=2), with encoding="utf-8" on the
open().
What changes on the way back
JSON has fewer types than Python. Strings, numbers, and lists come back as they were,
and True, False, and None are saved as true, false, and null and come back as
True, False, and None. Two things change. Predict:
ውጤቱን ገምቱ
Decide before you look. Guessing wrong is how this sticks.
import json
data = {1: "a", "t": (1, 2)}
print(json.loads(json.dumps(data)))Python prints
{'1': 'a', 't': [1, 2]}JSON object keys are always strings, so the key 1 comes back as '1'. JSON has no tuples, only arrays, which load as lists.
If you picked the first answer, you expected JSON to give back exactly what you saved.
If you picked the second, you caught the tuple but not the key. In JSON, a dict's keys
are always strings, so 1 comes back as '1'; and JSON has no tuples, so (1, 2)
comes back as the list [1, 2]. That bites when you save a dict with number keys:
ጥያቄ
You save {2026: "Meskerem"} as JSON and load it back as data. Which lookup works?
Some values can't be saved at all. Python's datetime module has a date type for
calendar dates (lesson 8.6 shows more): date(2026, 10, 1) is 1 October 2026, and its
.isoformat() method gives it as text, "2026-10-01". JSON has no dates, so saving a
date raises a TypeError; save its text instead:
import json
from datetime import date
paid = date(2026, 10, 1)
try:
print(json.dumps({"date": paid}))
except TypeError as e:
print(e)
print(json.dumps({"date": paid.isoformat()}))In the editor, press Escape then Tab to move on.
except ... as e (lesson 7.3) gives the error a name, and print(e) shows its message.
Sets can't be saved either; turn one into a list first. That's why Birr Ledger (lesson
8.9) keeps each date as text like "2026-10-01".
So when do you use which? CSV is for flat tables that people may open in a
spreadsheet, one row per record, every value text. JSON is for nested data, like a list
of dicts whose values are lists, and it keeps numbers, true/false, and null as
types. A ledger of expense dicts is JSON's job.
መልመጃ
A contact book that remembers
Load contacts.json (an empty dict if the file isn't there), ask for a name and a
number, save the dict back with ensure_ascii=False, indent=2, and list the contacts
in order. The Input box has ሀና, then 0900 000 002.
Name: ሀና
Number: 0900 000 002
Abel: 0900 000 001
ሀና: 0900 000 002Your code
import json
# Load contacts.json, or start with {} if it doesn't exist
contacts = {}
name = input("Name: ")
number = input("Number: ")
contacts[name] = number
# Save contacts back to contacts.json, then list them in orderIn the editor, press Escape then Tab to move on.
One answer per line, given to input() in order.
ፋይሎች1 starting file
contacts.json
{
"Abel": "0900 000 001"
}
መፍትሄውን አሳይHide the solution
This is one way to solve it, not the only one. If yours prints the same thing, it works.
import json
try:
with open("contacts.json", encoding="utf-8") as f:
contacts = json.load(f)
except FileNotFoundError:
contacts = {}
name = input("Name: ")
number = input("Number: ")
contacts[name] = number
with open("contacts.json", "w", encoding="utf-8") as f:
json.dump(contacts, f, ensure_ascii=False, indent=2)
for name in sorted(contacts):
print(f"{name}: {contacts[name]}")ዋና ዋና ነጥቦች
- JSON saves dicts and lists as text:
json.dump(data, f)writes,json.load(f)reads;dumpsandloadswork with strings. - Save with
json.dump(data, f, ensure_ascii=False, indent=2)so Amharic stays readable. - Keys always come back as strings, and tuples as lists:
d[1]becomesd["1"]. - CSV for flat tables; JSON for nested data like a list of dicts.