Ачааллж байна...
Энэ хичээлд шинэ бичлэг байхгүй. Ганц ч шинэ функц, ганц ч шинэ түлхүүр үг сурахгүй.
Тэгвэл яагаад энэ хичээл байна вэ?
Учир нь та одоо хэдэн арван тусдаа чадвартай болсон — comprehension, sorted, lambda, set, dictionary, .get(), type hint, JSON, CSV — гэвч тэдгээрийг НЭГ ДОР, БОДИТ ӨГӨГДӨЛ ДЭЭР ажиллуулж үзээгүй. Тусдаа чадвар нь тусдаа хэрэгсэл. Программ бол тэдгээрийн ХАМТЫН АЖИЛЛАГАА.
Мөн бодит өгөгдөл нь сурах бичгийн өгөгдлөөс ТЭС ӨӨР байдаг. Сурах бичигт өгөгдөл цэвэрхэн, бүрэн, зөв төрөлтэй байдаг. Бодит өгөгдөл нь:
Талбар нь дутуу байна
Утга нь хоосон string байна
Тоо нь string болж ирсэн байна
Нэрэнд илүү зай байна
Ижил зүйл өөр өөрөөр бичигдсэн байна ("Хоол", "хоол", "ХООЛ")
Гэнэтийн None байна
Энэ хичээлийн зорилго бол тийм өгөгдөлтэй айхгүй, эмх цэгцтэй ажиллах чадвар олгох явдал. Тэгээд дараагийн хичээлд бид зарлагын бүртгэл бичихэд бүх зүйл бэлэн байна.
Мэргэжлийн тогооч хоол хийж эхлэхээсээ өмнө юу хийдэг вэ?
Тэр шууд тогоо руу орц хийдэггүй. Эхлээд бэлтгэл хийдэг: ногоог угаана, муудсаныг хаяна, хальсыг нь арилгана, ижил хэмжээгээр хэрчинэ, тус тусад нь савлана. Франц хэлээр үүнийг mise en place гэдэг — "бүх зүйлээ байрандаа тавих."
Тэр бэлтгэл хийсний дараа л жинхэнэ хоол хийх ажил эхэлдэг. Мөн тэр үед бүх зүйл хурдан, алдаагүй явдаг.
Өгөгдөлтэй ажиллах нь яг ижил. Эхлээд цэвэрлэ, дараа нь боловсруул. Хэрэв та бохир өгөгдөл дээр шууд тооцоолол хийвэл — тооцоолол бүрд if шалгалт, try/except, хувиргалт бичих хэрэгтэй болно. Код нь эмх замбараагүй болно.
Харин эхлээд цэвэрлэвэл — үлдсэн бүх код нь цэвэрхэн өгөгдөлтэй ажиллана, тиймээс энгийн болно.
Дүрэм: ЦЭВЭРЛЭХ ба БОЛОВСРУУЛАХ хоёрыг САЛГА.
Ажиллах өгөгдөл бэлдье. VS Code-оор zarlaga.json нэртэй файл үүсгэж, дараах агуулгыг хийнэ үү. Энэ нь ЗОРИУДААР бохир — бодит амьдралын өгөгдөл яг ийм байдаг.
json
[
{"ner": "Ном", "dun": 15000, "angilal": "боловсрол"},
{"ner": " Автобус ", "dun": "1000", "angilal": "Тээвэр"},
{"ner": "Хоол", "dun": 8500, "angilal": "хоол"},
{"ner": "Дэвтэр", "dun": 3000},
{"ner": "Такси", "dun": "4500", "angilal": "тээвэр"},
{"ner": "", "dun": 2000, "angilal": "бусад"},
{"ner": "Кофе", "dun": 6000, "angilal": "ХООЛ"},
{"ner": "Ном", "dun": 22000, "angilal": "Боловсрол"}
]Асуудлуудыг тоочъё:
" Автобус " — эхэн, төгсгөлд илүү зай
"1000", "4500" — тоо нь string болж ирсэн
"Дэвтэр" — angilal талбар БАЙХГҮЙ
"" — нэр нь хоосон
"Тээвэр", "тээвэр" — ижил ангилал, өөр үсгээр
"хоол", "ХООЛ" — мөн адил
Хэрэв та энэ өгөгдөл дээр шууд тооцоолол хийвэл юу болохыг харъя.
python
import json
with open("zarlaga.json", "r", encoding="utf-8") as f:
zarlaguud = json.load(f)
niit = sum(z["dun"] for z in zarlaguud)
print(f"Нийт: {niit}")Traceback (most recent call last):
File "main.py", line 6, in <module>
niit = sum(z["dun"] for z in zarlaguud)
TypeError: unsupported operand type(s) for +: 'int' and 'str'unsupported operand type(s) for +: 'int' and 'str' — "тоо ба текстийг нэмж болохгүй." Зарим dun нь string байгаа тул sum унасан.
Одоо ангилалаар бүлэглэж үзье:
python
angilal_dun: dict[str, int] = {}
for z in zarlaguud:
angilal = z["angilal"]
angilal_dun[angilal] = angilal_dun.get(angilal, 0) + z["dun"]
print(angilal_dun)Traceback (most recent call last):
File "main.py", line 4, in <module>
angilal = z["angilal"]
KeyError: 'angilal'KeyError: 'angilal' — "Дэвтэр"-т тэр талбар байхгүй.
Хоёр удаа унасан. Хэрэв бид тэдгээрийг гараар нөхөх гэж оролдвол:
python
for z in zarlaguud:
angilal = z.get("angilal", "бусад")
dun = int(z["dun"])
angilal_dun[angilal] = angilal_dun.get(angilal, 0) + dunАжиллана... гэхдээ үр дүн нь БУРУУ:
{'боловсрол': 15000, 'Тээвэр': 1000, 'хоол': 8500, 'бусад': 5000, 'тээвэр': 4500, 'ХООЛ': 6000, 'Боловсрол': 22000}Долоон ангилал гарч ирлээ, гэтэл үнэндээ дөрөв л байна. "Тээвэр" ба "тээвэр" тусдаа тоологдож, "хоол" ба "ХООЛ" тусдаа тоологдсон.
Мөн .get("angilal", "бусад") ба int(z["dun"]) гэсэн засварууд нь loop дотор байна. Хэрэв та өөр газарт дахин loop бичвэл — тэдгээрийг ДАХИН бичих хэрэгтэй болно. Давхардал үүснэ, нэгийг мартах эрсдэл гарна.
Энэ бол цэвэрлэлт ба боловсруулалтыг холиход гардаг асуудал.
Одоо зөв аргаар хийе. Эхлээд цэвэрлэх функц бичье. Түүний ганц үүрэг: бохир өгөгдлийг цэвэр, найдвартай хэлбэрт оруулах.
python
import json
def zarlaga_tseverlekh(tureg: dict[str, str | int]) -> dict[str, str | int] | None:
ner = str(tureg.get("ner", "")).strip()
if not ner:
return None
turug_dun = tureg.get("dun", 0)
try:
dun = int(turug_dun)
except (ValueError, TypeError):
return None
if dun <= 0:
return None
angilal = str(tureg.get("angilal", "бусад")).strip().lower()
if not angilal:
angilal = "бусад"
return {"ner": ner, "dun": dun, "angilal": angilal}Функцийг мөр мөрөөр нь задалъя. Энэ бол хичээлийн гол код.
ner = str(tureg.get("ner", "")).strip()
Гурван зүйл нэг мөрөнд. .get("ner", "") нь талбар байхгүй бол хоосон string өгнө (KeyError -ээс хамгаална). str(...) нь ямар ч төрөл ирсэн ч string болгоно (хэрэв тоо ирсэн бол ч ажиллана). .strip() нь эхэн, төгсгөлийн ЗАЙГ арилгана — " Автобус " → "Автобус".
if not ner: return None
Нэр хоосон бол — энэ бичлэг ХҮЧИНГҮЙ. None буцаана.
Анзаараарай, буцаах hint нь dict[...] | None — Бүлэг 4.3-ын union. Функц нь "цэвэрлэсэн бичлэг ЭСВЭЛ юу ч биш" буцаана. Дуудагч түүнийг шалгах ёстой гэдгийг гарчиг нь хэлж байна.
try: dun = int(turug_dun) except (ValueError, TypeError): return None
int() нь string-ийг тоо болгоно ("1000" → 1000). Гэвч хэрэв утга нь "тэнэг" эсвэл None байвал — алдаа гарна. Тиймээс try/except -ээр хамгаалж, бүтэлгүйтвэл бичлэгийг хаяна.
(ValueError, TypeError) гэсэн tuple нь "эдгээрийн аль нэг нь гарвал" гэсэн үг. ValueError нь int("тэнэг") үед, TypeError нь int(None) үед гарна. Хоёуланг нь нэг блокт барьж байна.
if dun <= 0: return None
Тэг эсвэл сөрөг зарлага нь утгагүй. Хаяна.
angilal = str(tureg.get("angilal", "бусад")).strip().lower()
Хамгийн чухал мөр. .get("angilal", "бусад") нь талбар байхгүй бол "бусад" өгнө. .strip() нь зай арилгана. .lower() нь ЖИЖИГ ҮСЭГ болгоно — "Тээвэр", "тээвэр", "ТЭЭВЭР" бүгд "тээвэр" болно.
Энэ бол нормчлол (normalization) гэж нэрлэгддэг үйлдэл: ижил зүйлийг ижил хэлбэрт оруулах. Түүнгүйгээр бүлэглэлт бүхэлдээ буруу гарна.
return {"ner": ner, "dun": dun, "angilal": angilal}
ШИНЭ dictionary буцаана. Анхны бохир dictionary-г ӨӨРЧИЛӨӨГҮЙ гэдгийг анзаараарай — бид шинийг үүсгэсэн. Энэ нь чухал: эх өгөгдөл хэвээрээ үлдэнэ, шаардлагатай бол буцаж харж болно.
python
def bukhniig_tseverlekh(
tureg_uguudul: list[dict[str, str | int]],
) -> list[dict[str, str | int]]:
tsever: list[dict[str, str | int]] = []
for tureg in tureg_uguudul:
bichlelg = zarlaga_tseverlekh(tureg)
if bichlelg is not None:
tsever.append(bichlelg)
return tsever
with open("zarlaga.json", "r", encoding="utf-8") as f:
tureg_uguudul = json.load(f)
zarlaguud = bukhniig_tseverlekh(tureg_uguudul)
print(f"Түүхий: {len(tureg_uguudul)} бичлэг")
print(f"Цэвэр: {len(zarlaguud)} бичлэг")
print()
for z in zarlaguud:
print(z)Түүхий: 8 бичлэг
Цэвэр: 7 бичлэг
{'ner': 'Ном', 'dun': 15000, 'angilal': 'боловсрол'}
{'ner': 'Автобус', 'dun': 1000, 'angilal': 'тээвэр'}
{'ner': 'Хоол', 'dun': 8500, 'angilal': 'хоол'}
{'ner': 'Дэвтэр', 'dun': 3000, 'angilal': 'бусад'}
{'ner': 'Такси', 'dun': 4500, 'angilal': 'тээвэр'}
{'ner': 'Кофе', 'dun': 6000, 'angilal': 'хоол'}
{'ner': 'Ном', 'dun': 22000, 'angilal': 'боловсрол'}Бүх асуудал шийдэгдлээ.
" Автобус " → "Автобус" (зай арилсан)
"1000" → 1000 (тоо болсон)
"Дэвтэр" → angilal: "бусад" (дутуу талбар нөхөгдсөн)
"" (хоосон нэр) → ХАЯГДСАН (8 бичлэгээс 7 үлдсэн)
"Тээвэр", "тээвэр" → хоёулаа "тээвэр"
"хоол", "ХООЛ" → хоёулаа "хоол"
Одоо zarlaguud нь найдвартай. Түүн дээр ажиллах бүх код нь: dun нь ҮРГЭЛЖ тоо, ner нь ҮРГЭЛЖ хоосон биш string, angilal нь ҮРГЭЛЖ байгаа, ҮРГЭЛЖ жижиг үсэгтэй гэдэгт итгэж чадна.
if bichlelg is not None: гэсэн шалгалтыг анзаараарай — Бүлэг 4.3-ын дүрэм. Цэвэрлэх функц нь None буцааж болно, тиймээс шалгаж байна.
Comprehension-оор ч бичиж болно, гэхдээ zarlaga_tseverlekh -ийг хоёр удаа дуудах болно (Түвшин 1-ийн guided build-ийн сургамж). Тиймээс энгийн loop нь энд ЗӨВ сонголт.
Цэвэр өгөгдөл дээр ажиллах нь ямар байдгийг харъя.
Нийт дүн:
python
niit = sum(z["dun"] for z in zarlaguud)
print(f"Нийт зарлага: {niit:,} төгрөг")Нийт зарлага: 60,000 төгрөгЯмар ч int() байхгүй. Ямар ч try/except байхгүй. Ганц мөр.
{niit:,} гэсэн f-string-ийн формат заагч нь мянгатын тусгаарлагч нэмдэг: 60000 → 60,000. Жижиг зүйл, гэхдээ тайлан уншихад маш их тусална.
Ангилалаар шүүх:
python
tseevriin_zarlaga = [z for z in zarlaguud if z["angilal"] == "тээвэр"]
for z in tseevriin_zarlaga:
print(f"{z['ner']}: {z['dun']:,}")Автобус: 1,000
Такси: 4,500Comprehension нь "Тээвэр" ба "тээвэр" -ийг андуурахгүй, учир нь цэвэрлэлт нь тэднийг аль хэдийн нэгтгэсэн.
Дүнгээр шүүх:
python
tom_zarlaga = [z for z in zarlaguud if z["dun"] > 5000]
print(f"5000-аас дээш: {len(tom_zarlaga)} бичлэг")
for z in tom_zarlaga:
print(f" {z['ner']}: {z['dun']:,}")5000-аас дээш: 4 бичлэг
Ном: 15,000
Хоол: 8,500
Кофе: 6,000
Ном: 22,000Эрэмбэлэх:
python
erembelsen = sorted(zarlaguud, key=lambda z: z["dun"], reverse=True)
print("Хамгийн үнэтэй 3 зарлага:")
for baiirlal, z in enumerate(erembelsen[:3], start=1):
print(f" {baiirlal}. {z['ner']} — {z['dun']:,}")Хамгийн үнэтэй 3 зарлага:
1. Ном — 22,000
2. Ном — 15,000
3. Хоол — 8,500sorted + lambda (Бүлэг 3.5), slicing [:3] (Бүлэг 2.4), enumerate (Бүлэг 2.3) — гурван бүлгийн мэдлэг нэг мөрөнд.
Одоо хамгийн түгээмэл, хамгийн хэрэгтэй үйлдэл рүү орно: бүлэглэж, нийлбэр гаргах.
python
def angilalaar_buleglekh(zarlaguud: list[dict[str, str | int]]) -> dict[str, int]:
dun_bulgeer: dict[str, int] = {}
for z in zarlaguud:
angilal = z["angilal"]
dun_bulgeer[angilal] = dun_bulgeer.get(angilal, 0) + z["dun"]
return dun_bulgeer
bulgeer = angilalaar_buleglekh(zarlaguud)
print(bulgeer){'боловсрол': 37000, 'тээвэр': 5500, 'хоол': 14500, 'бусад': 3000}Дөрвөн ангилал. Долоо биш. Цэвэрлэлт нь ажиллалаа.
dun_bulgeer.get(angilal, 0) + z["dun"] — Түвшин 1-ийн guided build-аас танил хэв маяг. "Байвал утгыг нь ав, байхгүй бол тэгээс эхэл, дараа нь нэм."
Одоо гоё тайлан хэвлэе:
python
niit = sum(bulgeer.values())
print("=" * 40)
print("АНГИЛАЛААР")
print("=" * 40)
for angilal, dun in sorted(bulgeer.items(), key=lambda h: h[1], reverse=True):
khuvi = dun / niit * 100
print(f"{angilal:<12} {dun:>10,} ({khuvi:>5.1f}%)")
print("=" * 40)
print(f"{'НИЙТ':<12} {niit:>10,}")
print("=" * 40)========================================
АНГИЛАЛААР
========================================
боловсрол 37,000 ( 61.7%)
хоол 14,500 ( 24.2%)
тээвэр 5,500 ( 9.2%)
бусад 3,000 ( 5.0%)
========================================
НИЙТ 60,000
========================================Гоё харагдаж байна. Хэдэн шинэ формат заагч ашигласан тул тайлбарлая.
{angilal:<12} — "зүүн тийш зэрэгцүүл, 12 тэмдэгт өргөн." Багана эгнэнэ.{dun:>10,} — "баруун тийш зэрэгцүүл, 10 тэмдэгт өргөн, мянгатын таслалтай."{khuvi:>5.1f} — "баруун тийш, 5 өргөн, нэг оронтой бутархай."
Эдгээр нь f-string-ийн формат заагчид. Тэдгээрийг цээжлэх шаардлагагүй — хэрэгтэй үедээ хайж олж болно. Гэхдээ тайлан гоё харагдуулахад маш их тусалдаг гэдгийг мэдэж байгаарай.
sorted(bulgeer.items(), key=lambda h: h[1], reverse=True) — dictionary-г УТГААР нь эрэмбэлж байна. .items() нь tuple өгдөг, h[1] нь тэр tuple-ийн хоёр дахь элемент буюу дүн. Бүлэг 5.1-ийн tuple мэдлэг ажиллаж байна.
python
buk_angilal: set[str] = {z["angilal"] for z in zarlaguud}
print(f"Ангилалууд: {sorted(buk_angilal)}")
buk_ner: set[str] = {z["ner"] for z in zarlaguud}
print(f"Өвөрмөц бараа: {len(buk_ner)} төрөл")Ангилалууд: ['боловсрол', 'бусад', 'тээвэр', 'хоол']
Өвөрмөц бараа: 6 төрөлSet comprehension (Бүлэг 2.2, 5.2). "Ном" хоёр удаа байсан ч нэг л удаа тоологдсон.
python
def bараа_khaikh(
zarlaguud: list[dict[str, str | int]], ner: str
) -> list[dict[str, str | int]]:
ner_tsever = ner.strip().lower()
return [z for z in zarlaguud if z["ner"].lower() == ner_tsever]
nom_zarlaga = bараа_khaikh(zarlaguud, " НОМ ")
print(f"'Ном' -той холбоотой {len(nom_zarlaga)} зарлага:")
for z in nom_zarlaga:
print(f" {z['dun']:,} ({z['angilal']})")
print(f"Нийт: {sum(z['dun'] for z in nom_zarlaga):,}")'Ном' -той холбоотой 2 зарлага:
15,000 (боловсрол)
22,000 (боловсрол)
Нийт: 37,000Хайх функц нь ОРОЛТЫГ Ч ЦЭВЭРЛЭЖ байгааг анзаараарай — ner.strip().lower(). Учир нь хэрэглэгч " НОМ " гэж бичиж болно. Цэвэрлэлт нь зөвхөн файлын өгөгдөлд биш, ХЭРЭГЛЭГЧИЙН ОРОЛТОД Ч хамаарна.
Энэ бол чухал зарчим: хилийн цэг бүрд цэвэрлэ. Өгөгдөл гаднаас ирэх бүрд (файл, хэрэглэгч, интернэт) — түүнийг цэвэрлээд дараа нь дотогш оруул.
Бүх зүйлийг нэгтгэе.
python
# main.py
# Зарлагын өгөгдөл цэвэрлэх ба шинжлэх
import json
def zarlaga_tseverlekh(tureg: dict[str, str | int]) -> dict[str, str | int] | None:
ner = str(tureg.get("ner", "")).strip()
if not ner:
return None
try:
dun = int(tureg.get("dun", 0))
except (ValueError, TypeError):
return None
if dun <= 0:
return None
angilal = str(tureg.get("angilal", "бусад")).strip().lower()
if not angilal:
angilal = "бусад"
return {"ner": ner, "dun": dun, "angilal": angilal}
def uguudul_achaalakh(zam: str) -> list[dict[str, str | int]]:
try:
with open(zam, "r", encoding="utf-8") as f:
tureg = json.load(f)
except FileNotFoundError:
print(f"Файл олдсонгүй: {zam}")
return []
except json.JSONDecodeError as alda:
print(f"Файл эвдэрсэн: {alda}")
return []
tsever: list[dict[str, str | int]] = []
for bichlelg in tureg:
tseverkhen = zarlaga_tseverlekh(bichlelg)
if tseverkhen is not None:
tsever.append(tseverkhen)
khassan = len(tureg) - len(tsever)
if khassan > 0:
print(f"Анхаар: {khassan} хүчингүй бичлэгийг алгаслаа.")
return tsever
def angilalaar_buleglekh(zarlaguud: list[dict[str, str | int]]) -> dict[str, int]:
dun_bulgeer: dict[str, int] = {}
for z in zarlaguud:
angilal = z["angilal"]
dun_bulgeer[angilal] = dun_bulgeer.get(angilal, 0) + z["dun"]
return dun_bulgeer
def tailan_khevlekh(zarlaguud: list[dict[str, str | int]]) -> None:
if not zarlaguud:
print("Зарлага байхгүй байна.")
return
niit = sum(z["dun"] for z in zarlaguud)
bulgeer = angilalaar_buleglekh(zarlaguud)
erembelsen = sorted(zarlaguud, key=lambda z: z["dun"], reverse=True)
print("=" * 44)
print("ЗАРЛАГЫН ТАЙЛАН")
print("=" * 44)
print(f"Бичлэгийн тоо: {len(zarlaguud)}")
print(f"Нийт дүн: {niit:,} төгрөг")
print(f"Дундаж: {niit // len(zarlaguud):,} төгрөг")
print()
print("АНГИЛАЛААР")
print("-" * 44)
for angilal, dun in sorted(bulgeer.items(), key=lambda h: h[1], reverse=True):
khuvi = dun / niit * 100
print(f" {angilal:<14} {dun:>10,} ({khuvi:>5.1f}%)")
print()
print("ХАМГИЙН ҮНЭТЭЙ 3")
print("-" * 44)
for baiirlal, z in enumerate(erembelsen[:3], start=1):
print(f" {baiirlal}. {z['ner']:<12} {z['dun']:>10,}")
print("=" * 44)
zarlaguud = uguudul_achaalakh("zarlaga.json")
tailan_khevlekh(zarlaguud)Ажиллуулна уу:
Анхаар: 1 хүчингүй бичлэгийг алгаслаа.
============================================
ЗАРЛАГЫН ТАЙЛАН
============================================
Бичлэгийн тоо: 7
Нийт дүн: 60,000 төгрөг
Дундаж: 8,571 төгрөг
АНГИЛАЛААР
--------------------------------------------
боловсрол 37,000 ( 61.7%)
хоол 14,500 ( 24.2%)
тээвэр 5,500 ( 9.2%)
бусад 3,000 ( 5.0%)
ХАМГИЙН ҮНЭТЭЙ 3
--------------------------------------------
1. Ном 22,000
2. Хоол 8,500
3. Ном 15,000Түр зогсъё — "Хамгийн үнэтэй 3" дээр Хоол нь Ном -оос ӨМНӨ гарч байна, гэтэл 8,500 нь 15,000-аас бага. Тэр буруу.
Зөв гаралт нь:
ХАМГИЙН ҮНЭТЭЙ 3
--------------------------------------------
1. Ном 22,000
2. Ном 15,000
3. Хоол 8,500Дээр би гаралтыг гараар бичихдээ алдсан — код нь зөв, sorted(..., reverse=True) нь буурах дарааллаар зөв эрэмбэлнэ. Энэ бол ЯГ ТИЙМ ШАЛТГААНААР та гаралтыг ТААМАГЛАХГҮЙ, харин ажиллуулж ХАРАХ ёстой гэдгийн жишээ юм.
Гаднаас ирсэн өгөгдөлтэй ажиллах бүрд эдгээрийг бод:
1. Талбар байхгүй байж болох уу? → .get(key, default)
2. Утга нь хоосон байж болох уу? → if not utga: ...
3. Тоо нь string байж болох уу? → int() / float() + try/except
4. Илүү зай байж болох уу? → .strip()
5. Ижил зүйл өөр үсгээр бичигдсэн үү? → .lower() (нормчлол)
6. Утга нь утгагүй байж болох уу? (сөрөг үнэ, ирээдүйн огноо) → шалгалт нэмнэ
7. None байж болох уу? → is None шалгалт
Эдгээрийг ЦЭВЭРЛЭХ ФУНКЦ дотор нэг дор шийд. Дараа нь бүх код цэвэр өгөгдөлтэй ажиллана.
Хэрэв сонирхвол: zarlaga.json файлд илүү олон бохир бичлэг нэмээд, цэвэрлэх функц бүгдийг зөв боловсруулж байгаа эсэхийг шалгаарай. Жишээ нь:
json
{"ner": "Тест", "dun": "тэнэг", "angilal": "хоол"},
{"ner": "Тест2", "dun": -500, "angilal": "хоол"},
{"ner": "Тест3", "dun": null, "angilal": "хоол"}Гурвуулаа хаягдах ёстой. Хэрэв программ унавал — цэвэрлэх функцэд юу дутуу байгааг олж, нөхөөрэй.
Мөн хүсвэл: цэвэрлэсэн өгөгдлийг CSV болгож экспортлоод (өмнөх хичээлийн DictWriter, encoding="utf-8-sig"), Excel-д нээж, диаграм зурж үзээрэй.
1. Цэвэрлэлт ба боловсруулалтыг холих
python
for z in zarlaguud:
dun = int(z.get("dun", 0))
angilal = z.get("angilal", "бусад").lower()
...Ажиллана, гэхдээ энэ логик нь loop БҮРД давтагдана. Нэг газарт .lower() мартвал — чимээгүй алдаа. Засвар: цэвэрлэх функцийг ТУСАД нь бич, нэг удаа ажиллуул.
2. Нормчлол мартах
python
bulgeer["Тээвэр"] = 1000
bulgeer["тээвэр"] = 4500Хоёр өөр ангилал болно. Дундаж, нийлбэр бүгд буруу. .lower() -ыг мартаж болохгүй.
3. Эх өгөгдлийг өөрчлөх
python
def tseverlekh(z: dict) -> dict:
z["angilal"] = z["angilal"].lower() # ЭХ өгөгдлийг өөрчиллөө!
return zБүлэг 5.3-аас санаж байгаа байх: dictionary нь mutable, түүнийг өөрчилвөл эх өгөгдөл өөрчлөгдөнө. Хэрэв дараа нь түүхий өгөгдөл хэрэгтэй болвол — алга. Засвар: ШИНЭ dictionary буцаа.
4. int() -г хамгаалалтгүй дуудах
python
dun = int(z["dun"])ValueError: invalid literal for int() with base 10: 'тэнэг'invalid literal for int() гэдэг нь "энэ текстийг тоо болгож чадсангүй" гэсэн үг. try/except ValueError -ээр хамгаал.
5. Хоосон жагсаалт дээр хуваах
python
dundaj = niit / len(zarlaguud)ZeroDivisionError: division by zeroХэрэв бүх бичлэг хаягдвал жагсаалт хоосон болно. if not zarlaguud: return -ээр хамгаал.
6. Хаягдсан бичлэгийг чимээгүй өнгөрөх
Цэвэрлэлт нь бичлэг хаяхад — ХЭЛ. print(f"Анхаар: {khassan} хүчингүй бичлэгийг алгаслаа.") Хэрэглэгч мэдэх эрхтэй.
ЦЭВЭРЛЭХ ба БОЛОВСРУУЛАХ хоёрыг САЛГА. Эхлээд өгөгдлийг найдвартай хэлбэрт оруул, дараа нь түүн дээр ажилла.
Цэвэрлэх функц нь нэг бичлэг авч, цэвэрлэсэн бичлэг ЭСВЭЛ None буцаана: -> dict[...] | None.
Цэвэрлэлтийн стандарт алхмууд:
.get(key, default) — талбар байхгүй байж болно
.strip() — илүү зай
.lower() — нормчлол, ижил зүйлийг ижил болгоно
int() + try/except (ValueError, TypeError) — төрөл хувиргах
if not utga: return None — хүчингүй бичлэг хаях
Нормчлол мартвал бүлэглэлт бүхэлдээ буруу гарна — "Тээвэр" ба "тээвэр" тусдаа тоологдоно.
ШИНЭ dictionary буцаа, эх өгөгдлийг өөрчилж болохгүй.
Хилийн цэг бүрд цэвэрлэ: файл, хэрэглэгчийн оролт, интернэт — гаднаас ирэх бүх өгөгдөл.
Цэвэр өгөгдөл дээр боловсруулалт нь ХЯЛБАР: sum(z["dun"] for z in zarlaguud) — ямар ч хувиргалт, ямар ч шалгалтгүй.
Бүлэглэх хэв маяг: bulgeer[key] = bulgeer.get(key, 0) + utga.
f-string формат заагчид тайланг гоё болгоно: {dun:,} (мянгатын таслал), {ner:<12} (зүүн зэрэгцүүлэлт), {khuvi:.1f} (бутархай).
Гаралтыг ТААМАГЛАХГҮЙ — АЖИЛЛУУЛЖ ХАР.
Дараагийн хичээлээр Түвшин 2 дуусна. Бид хамтдаа зарлагын бүртгэлийн программ бичнэ: зарлага нэмэх, жагсаах, нийт дүн гаргах, ангилалаар шүүх — бүгд JSON файлд хадгалагдаж, программ хаагдсаны дараа ч үлдэнэ. Тэр бол Курс 1-ийн хийх ажлын жагсаалтын жинхэнэ ӨВ ЗАЛГАМЖЛАГЧ: ижил санаа, гэхдээ бүрэн type hint-тэй, файлд хадгалагддаг, цэвэрлэх давхаргатай, мэргэжлийн бүтэцтэй.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.