အခန်း 21 · animation 3 ခု

Chapter 20: File Handling (ဖိုင်များ ကိုင်တွယ်ခြင်း)

808 Coder မှ တင်ဆက်သည်

ဒီအခန်းပြီးရင်...

  • Text file နဲ့ binary file ကွာခြားချက်ကို ရှင်းပြနိုင်မယ်
  • open() ရဲ့ mode များ (r/w/a) ကို မှန်မှန်ကန်ကန် သုံးနိုင်မယ်
  • ဖိုင်ထဲ စာရေးခြင်း၊ စာဖတ်ခြင်း (read/readline/readlines) တို့ကို လုပ်နိုင်မယ်
  • with statement နဲ့ ဖိုင်ကို အလိုအလျောက် ပိတ်နိုင်မယ်
  • ဖိုင် ကူးယူခြင်း၊ ပေါင်းခြင်း၊ ဖျက်ခြင်းတို့ကို လုပ်နိုင်မယ်
  • ဖိုင်ကို အခြေခံတဲ့ စနစ်လေးတွေ (မှတ်တမ်းစနစ်၊ login စနစ်၊ to-do list) ရေးနိုင်မယ်

File Handling ဆိုတာ ဘာလဲ

အခု အချိန်ထိ ကျွန်တော်တို့ ရေးခဲ့တဲ့ program တွေက အချက်အလက်တွေကို memory (variable) ထဲမှာပဲ သိမ်းပါတယ်။ Program ပိတ်လိုက်တာနဲ့ အချက်အလက် အားလုံး ပျောက်သွားပါတယ်။ ဒါကြောင့် အချက်အလက်ကို ဖိုင် ထဲ သိမ်းဖို့ လိုပါတယ် — အသုံးပြုသူရဲ့ အချက်အလက်၊ မှတ်တမ်း (log)၊ setting တွေ သိမ်းဖို့အတွက်ပါ။ ဖိုင်ထဲ စာရေး/စာဖတ်လုပ်တာကို file handling လို့ ခေါ်ပါတယ်။

ဖိုင်မှာ အဓိက အမျိုးအစား နှစ်မျိုး ရှိပါတယ်။

  • Text file (.txt, .csv, .log) — လူ ဖတ်လို့ ရတဲ့ စာသားတွေ ပါဝင်တယ်။ Notepad နဲ့ ဖွင့်ကြည့်လို့ ရတယ်။
  • Binary file (.jpg, .pdf, .exe) — စာသားမဟုတ်တဲ့ အချက်အလက် (ဓာတ်ပုံ၊ ဗီဒီယို၊ program) တွေ ပါဝင်တယ်။ တိုက်ရိုက် ဖတ်လို့ မရဘူး။

ဒီအခန်းမှာ text file တွေကို အဓိက ကိုင်တွယ်ပါမယ်။ ဒါက အခြေခံအကျဆုံး၊ အသုံးအများဆုံးမို့ပါ။

မှတ်ချက် — မြန်မာစာ ပါတဲ့ ဖိုင်တွေ ဖွင့်/ရေးတဲ့အခါ open() မှာ encoding="utf-8" လို့ ထည့်ပေးပါ။ ကွန်ပျူတာ တိုင်းမှာ မြန်မာစာ မှန်မှန်ကန်ကန် အလုပ်လုပ်စေဖို့ပါ။ အောက်က ဥပမာတွေမှာ ဒါကို ပုံမှန် ထည့်သုံးထားပါတယ်။

Reference

  • Reading/writing files — ဖိုင်ဖတ်/ဖိုင်ရေး အပြည့်အစုံ လမ်းညွှန်
  • Input/output — Python ရဲ့ input/output သင်ခန်းစာ

ဖိုင်ဖွင့်နည်း — open() နဲ့ Mode များ

ဖိုင်နဲ့ အလုပ်လုပ်ဖို့ ပထမဆုံး open() နဲ့ ဖွင့်ရပါတယ်။ ဒုတိယ argument က mode — ဖိုင်ကို ဘယ်လို သုံးမလဲ ဆိုတာပါ။

file = open("example.txt", "mode")

အသုံးအများဆုံး mode သုံးမျိုးကို ဇယားနဲ့ မှတ်ထားပါ။

Mode အဓိပ္ပာယ် ဖိုင် မရှိရင်
"r" read — ဖတ်ဖို့ သက်သက် (default) FileNotFoundError တက်တယ်
"w" write — ရေးဖို့ (အဟောင်းကို ဖျက်ပြီး အသစ်ရေး) အသစ် ဖန်တီးပေးတယ်
"a" append — အဟောင်းရဲ့ နောက်ဆက်တွဲရေး အသစ် ဖန်တီးပေးတယ်

သတိပြုရန် — "w" mode နဲ့ ဖွင့်လိုက်တာနဲ့ ဖိုင်ထဲက အကြောင်းအရာ အဟောင်းအားလုံး ချက်ချင်း ပျက်သွားပါတယ်။ အဟောင်းကို ထိန်းထားချင်ရင် "a" (append) သုံးပါ။ ဒီအမှားက beginner တွေ အဖြစ်အများဆုံး အမှားပါ — "w" နဲ့ "a" ကို မရောထွေးပါစေနဲ့။

Mode ကို မထည့်ရင် default "r" (ဖတ်ဖို့) ဖြစ်ပါတယ်။

မှတ်ချက် — ဖိုင်နာမည်ကို "diary.txt" လို အတိုချုံး ရေးရင်၊ ဖိုင်ကို program run နေတဲ့ လက်ရှိ folder ထဲမှာ ရှာပါတယ် (ဒါကို relative path လို့ ခေါ်ပါတယ်)။ ဖိုင် ဘယ်နား ရောက်သွားလဲ မသိရင်၊ program ဖိုင်နဲ့ အတူ folder တစ်ထဲမှာ ရှိနေလား စစ်ကြည့်ပါ။ Folder အတိအကျ သတ်မှတ်ချင်ရင် "data/diary.txt" လို လမ်းကြောင်း အပြည့်အစုံ ရေးနိုင်ပါတယ်။

Reference


ဖိုင်ထဲ စာရေးခြင်း

write() method နဲ့ စာသားတွေ ရေးပြီး၊ ပြီးရင် close() နဲ့ ပိတ်ရပါတယ်။

file = open("diary.txt", "w", encoding="utf-8")
file.write("တနင်္လာ: Python စသင်တယ်။\n")
file.write("အင်္ဂါ: for loop လေ့ကျင့်တယ်။\n")
file.close()
print("ရေးပြီးပါပြီ!")

diary.txt ဆိုတဲ့ ဖိုင်အသစ် ဖန်တီးပြီး စာကြောင်း နှစ်ကြောင်း ရေးသွားပါတယ်။ သတိထားရမှာက write() က စာကြောင်း အသစ်ကို အလိုအလျောက် မဆင်းပေးပါဘူး — ကိုယ်တိုင် "\n" ထည့်ရပါတယ်။

အခု append mode နဲ့ ဆက်ရေးကြည့်ပါ။

file = open("diary.txt", "a", encoding="utf-8")
file.write("ဗုဒ္ဓဟူး: function တွေ လေ့လာတယ်။\n")
file.close()

အခု diary.txt ထဲမှာ စာကြောင်း သုံးကြောင်း ရှိသွားပါပြီ — အဟောင်း နှစ်ကြောင်း မပျက်ဘဲ၊ အသစ် တစ်ကြောင်း နောက်က ဆက်တွဲသွားတာပါ။ "w" သုံးခဲ့ရင် အဟောင်း နှစ်ကြောင်း ပျောက်ပြီး ဒီတစ်ကြောင်းတည်း ကျန်မှာပါ။

အသုံးပြုသူရိုက်ထည့်တာကို ဖိုင်ထဲ သိမ်းတဲ့ ပုံစံလည်း အဖြစ်များပါတယ်။

with open("ideas.txt", "w", encoding="utf-8") as f:
    while True:
        idea = input("စိတ်ကူး ထည့်ပါ ('done' ဆို ရပ်မယ်): ")
        if idea.lower() == "done":
            break
        f.write(idea + "\n")
print("သိမ်းပြီးပါပြီ!")

Sample run:

စိတ်ကူး ထည့်ပါ ('done' ဆို ရပ်မယ်): ဆိုင်ကယ် ပြင်တတ်ချင်တယ်
စိတ်ကူး ထည့်ပါ ('done' ဆို ရပ်မယ်): မုန့်ဟင်းခါး ချက်နည်းသင်မယ်
စိတ်ကူး ထည့်ပါ ('done' ဆို ရပ်မယ်): done
သိမ်းပြီးပါပြီ!

မှတ်ချက် — close() မေ့သွားရင် ရေးထားတာ ဖိုင်ထဲ အပြည့်အဝ မရောက်ဘဲ ကျန်နေတတ်ပါတယ်။ ဒါကြောင့် ဖိုင်နဲ့ အလုပ်ပြီးတိုင်း ပိတ်ဖို့ မမေ့ပါနဲ့။ (နောက်မှာ with ဆိုတဲ့ မေ့မရအောင် လုပ်ပေးတဲ့ နည်းကို လေ့လာပါမယ်။)

Reference

  • Reading/writing files — ဖိုင်ထဲ စာရေးနည်း အသေးစိတ်
  • Input/output — write() method အသုံးပြုပုံ

ဖိုင်ထဲက စာဖတ်ခြင်း — read(), readline(), readlines()

စာဖတ်ဖို့ နည်းလမ်း သုံးမျိုး ရှိပါတယ်။ အရင်ဆုံး နမူနာဖိုင် တစ်ခု ဖန်တီးထားမယ် ဆိုပါစို့ (poem.txt ထဲမှာ စာကြောင်း သုံးကြောင်း ရှိတယ်)။

# --- read() — တစ်ခုလုံး တစ်ခါတည်း ဖတ်မယ် ---
with open("poem.txt", "r", encoding="utf-8") as f:
    all_text = f.read()
    print("--- read() ---")
    print(all_text)

# --- readline() — တစ်ကြောင်းချင်း ဖတ်မယ် ---
with open("poem.txt", "r", encoding="utf-8") as f:
    print("--- readline() ---")
    print(f.readline(), end="")
    print(f.readline(), end="")

# --- readlines() — စာကြောင်းတွေကို list အဖြစ် ဖတ်မယ် ---
with open("poem.txt", "r", encoding="utf-8") as f:
    print("--- readlines() ---")
    lines = f.readlines()
    print(lines)
    print("စာကြောင်း အရေအတွက်:", len(lines))

Output:

--- read() ---
လရောင်
ကြယ်ရောင်
မိုးရောင်

--- readline() ---
လရောင်
ကြယ်ရောင်
--- readlines() ---
['လရောင်\n', 'ကြယ်ရောင်\n', 'မိုးရောင်\n']
စာကြောင်း အရေအတွက်: 3

သုံးမျိုးလုံးရဲ့ ကွာခြားချက်ကို မှတ်ထားပါ။

  • read() — ဖိုင်တစ်ခုလုံးကို string တစ်ခု အဖြစ် ပြန်ပေးတယ်။ ဖိုင် သေးရင် အဆင်ပြေတယ်။
  • readline() — တစ်ကြောင်းတည်း ဖတ်တယ်။ ခေါ်တိုင်း နောက်တစ်ကြောင်းကို ဆက်ဖတ်တယ်။
  • readlines() — စာကြောင်းတိုင်းကို list ထဲ ထည့်ပေးတယ်။ loop ပတ်ဖို့ အဆင်ပြေတယ်။

ဖိုင်ကြီးတွေကို ဖတ်တဲ့အခါ for line in file: လို့ တိုက်ရိုက် loop ပတ်တာက memory သက်သာဆုံး နည်းပါ။

with open("poem.txt", "r", encoding="utf-8") as f:
    for line in f:
        print("ကဗျာ:", line.strip())

Output:

ကဗျာ: လရောင်
ကဗျာ: ကြယ်ရောင်
ကဗျာ: မိုးရောင်

Reference

  • Reading/writing files — စာဖတ်နည်း သုံးမျိုး အသေးစိတ်
  • Input/output — read/readline/readlines ရှင်းလင်းချက်

with Statement — ဖိုင်ကို အလိုအလျောက် ပိတ်ပေးတာ

အပေါ်က ဥပမာတွေမှာ with open(...) as f: လို့ သုံးထားတာ သတိထားမိမယ် ထင်ပါတယ်။ ဒါကို context manager လို့ ခေါ်ပါတယ်။ Block ပြီးသွားတာနဲ့ ဖိုင်ကို အလိုအလျောက် ပိတ်ပေးပါတယ် — close() ခေါ်ဖို့ မလိုတော့ဘူး။

အရေးကြီးဆုံး အချက်က — block ထဲမှာ exception ဖြစ်သွားရင်တောင် ဖိုင်ကို သေချာပေါက် ပိတ်ပေးတာပါ။ အရင် အခန်းက finally နဲ့ ကိုယ်တိုင် ရေးရတဲ့ ပုံစံရဲ့ အဆင်ပြေတဲ့ ဗားရှင်းလို့ မှတ်နိုင်ပါတယ်။

# ရိုးရိုး နည်းလမ်း — close() မေ့တတ်တယ်
f = open("data.txt", "w", encoding="utf-8")
f.write("အချက်အလက်")
f.close()

# with နည်းလမ်း — အလိုအလျောက် ပိတ်ပေးတယ်၊ အမှားလည်း စိတ်ချရတယ်
with open("data.txt", "w", encoding="utf-8") as f:
    f.write("အချက်အလက်")

အကျင့်လုပ်ပါ — ဖိုင်ဖွင့်တိုင်း with သုံးပါ။ ဒါဟာ Python programmer တိုင်းရဲ့ စံအလေ့အကျင့် (best practice) ပါ။

The with statement always closes the file without with f = open(...) ERROR! file left OPEN (leaked) X with open(...) as f: with-block ERROR! file auto-CLOSED no leak, guaranteed
with statement က error တက်ရင်တောင် ဖိုင် အလိုအလျောက် ပိတ်ပေးပုံ

Reference


tell() နဲ့ read(size) — ဖိုင်ထဲ သွားလာခြင်း

ဖိုင်ကို ဖတ်နေတုန်း Python က "အခု ဘယ်နေရာရောက်နေပြီလဲ" ဆိုတာကို မှတ်ထားပါတယ်။ ဒါကို file pointer လို့ ခေါ်ပါတယ်။

  • read(size) — size အရေအတွက်လောက် စာလုံး ဖတ်တယ်။
  • tell() — အခု pointer ဘယ်နေရာမှာ ရှိလဲ ပြန်ပေးတယ်။
with open("abc.txt", "w", encoding="utf-8") as f:
    f.write("ABCDEFGH")

with open("abc.txt", "r", encoding="utf-8") as f:
    print(f.read(3))
    print("လက်ရှိ နေရာ:", f.tell())
    print(f.read(3))
    print("လက်ရှိ နေရာ:", f.tell())

Output:

ABC
လက်ရှိ နေရာ: 3
DEF
လက်ရှိ နေရာ: 6

ပထမ read(3) က "ABC" ကို ဖတ်ပြီး pointer ကို နေရာ 3 ကို ရွှေ့သွားတယ်။ ဒုတိယ read(3) က "DEF" ကို ဖတ်တယ်။ ဒီလို pointer ရွေ့သွားတာကြောင့် ဖိုင်ကို အပိုင်းလိုက် ဖတ်တာ၊ ကျော်ဖတ်တာ လုပ်နိုင်ပါတယ်။

The file pointer moves as you read A 0 B 1 C 2 D 3 E 4 F 5 pos read(3) -> 'ABC' tell() = 3 read(3) again -> 'DEF', tell() = 6
read(size) နဲ့ tell() က file pointer ရွှေ့ပုံ

Reference


ဖိုင်ထဲက အချက်အလက် ရေတွက်ခြင်းနဲ့ ရှာဖွေခြင်း

ဖိုင်ထဲက စာကို ဖတ်တတ်ပြီဆိုရင်၊ နောက်တစ်ဆင့်က အဲဒီစာကို လေ့လာခြင်း ပါ။ စာကြောင်း ဘယ်လောက်ရှိလဲ၊ စကားလုံး ဘယ်လောက်ပါလဲ ရေတွက်တာ၊ စကားလုံး တစ်ခု ဘယ်စာကြောင်းမှာ ပါလဲ ရှာဖွေတာတို့ပါ။

စာကြောင်း၊ စကားလုံး၊ စာလုံး ရေတွက်ခြင်း

with open("poem.txt", "r", encoding="utf-8") as f:
    lines = f.readlines()

line_count = len(lines)
word_count = sum(len(line.split()) for line in lines)
char_count = sum(len(line) for line in lines)

print("စာကြောင်း:", line_count)
print("စကားလုံး:", word_count)
print("စာလုံး:", char_count)

Output (poem.txt မှာ စာကြောင်း သုံးကြောင်း ရှိတဲ့အခါ):

စာကြောင်း: 3
စကားလုံး: 3
စာလုံး: 21

ဘယ်လို အလုပ်လုပ်လဲ။ line.split() က စာကြောင်းတစ်ကြောင်းကို စကားလုံးတွေ ခွဲပေးပါတယ်။ sum(...) က စာကြောင်းတိုင်းရဲ့ ရလဒ်ကို ပေါင်းပေးပါတယ်။ ဒီနည်းက စာစီစာကုံး စစ်တာ၊ စာရွက်စာတမ်း အရှည် တိုင်းတာတာမှာ သုံးပါတယ်။

ဖိုင်ထဲမှာ စကားလုံး ရှာဖွေခြင်း

keyword = input("ရှာမယ့် စကားလုံး: ")
found = False

with open("poem.txt", "r", encoding="utf-8") as f:
    for num, line in enumerate(f, start=1):
        if keyword in line:
            print(f"စာကြောင်း {num} မှာ တွေ့တယ်: {line.strip()}")
            found = True

if not found:
    print("မတွေ့ပါ။")

Sample run:

ရှာမယ့် စကားလုံး: ကြယ်
စာကြောင်း 2 မှာ တွေ့တယ်: ကြယ်ရောင်

enumerate(f, start=1) က စာကြောင်းတိုင်းကို နံပါတ်တပ်ပေးပါတယ် (start=1 မို့ 1 ကနေ စပါတယ်)။ keyword in line က စကားလုံး ပါမပါ စစ်ပါတယ်။ Log file ထဲမှာ error ရှာတာ၊ မှတ်တမ်းထဲမှာ နာမည် ရှာတာတို့မှာ ဒီပုံစံကို သုံးပါတယ်။

မှတ်ချက် — စာလုံး အကြီး/အသေး ကွဲပြားတာကို ဂရုမစိုက်ဘဲ ရှာချင်ရင် နှစ်ဖက်လုံးကို lower() နဲ့ နှိမ့်ပြီးမှ နှိုင်းယှဉ်ပါ။ ဥပမာ if keyword.lower() in line.lower():

Reference

  • Reading/writing files — ဖိုင်အချက်အလက် လေ့လာခြင်း
  • Input/output — readlines() နဲ့ loop ပတ်နည်း

FileNotFoundError ကိုင်တွယ်ခြင်း

မရှိတဲ့ ဖိုင်ကို "r" mode နဲ့ ဖွင့်မိရင် FileNotFoundError တက်ပါတယ်။ အရင် အခန်းက သင်ခန်းစာကို ဒီမှာ လက်တွေ့ သုံးရပါပြီ။

try:
    with open("report.txt", "r", encoding="utf-8") as f:
        print(f.read())
except FileNotFoundError:
    print("report.txt ဖိုင် မတွေ့ပါ! နာမည် မှန်မမှန် စစ်ပါ။")

Output (ဖိုင် မရှိတဲ့အခါ):

report.txt ဖိုင် မတွေ့ပါ! နာမည် မှန်မမှန် စစ်ပါ။

Program crash မဖြစ်ဘဲ ယဉ်ကျေးတဲ့ message ပြသွားပါတယ်။ ဖိုင်ဖွင့်တဲ့ program တိုင်းမှာ ဒီလို ကာကွယ်ထားတာ အကျင့်ကောင်းပါ။

Reference

  • Try...Except — FileNotFoundError ကိုင်တွယ်နည်း
  • Reading/writing files — ဖိုင်အမှား ကိုင်တွယ်ခြင်း

ဖိုင် ကူးယူခြင်းနဲ့ ပေါင်းခြင်း

ဖိုင် ကူးယူခြင်း

ဖိုင်တစ်ခုရဲ့ အကြောင်းအရာကို နောက်တစ်ခုထဲ ကူးဖို့ — ပထမ ဖိုင်ကို ဖတ် ("r")၊ ဒုတိယ ဖိုင်ကို ရေး ("w")၊ တစ်ကြောင်းချင်း ကူးပါ။

with open("poem.txt", "r", encoding="utf-8") as src, \
     open("poem_copy.txt", "w", encoding="utf-8") as dst:
    for line in src:
        dst.write(line)
print("ကူးပြီးပါပြီ!")

with တစ်ခုတည်းမှာ ဖိုင် နှစ်ခု တွဲဖွင့်လို့ ရပါတယ်။ တစ်ကြောင်းချင်း ကူးတာမို့ ဖိုင်ကြီးရင်တောင် memory မကုန်ပါဘူး။

ဖိုင် နှစ်ခု ပေါင်းခြင်း

with open("morning.txt", "r", encoding="utf-8") as f1, \
     open("evening.txt", "r", encoding="utf-8") as f2:
    morning = f1.read()
    evening = f2.read()

with open("whole_day.txt", "w", encoding="utf-8") as out:
    out.write(morning + "\n" + evening)
print("ဖိုင်နှစ်ခု ပေါင်းပြီးပါပြီ!")

နှစ်ခုလုံးကို ဖတ်ပြီး၊ တတိယ ဖိုင်တစ်ခုထဲ အတူတူ ရေးထည့်လိုက်တာပါ။ Log file တွေ ပေါင်းတာ၊ ရက်စွဲ အလိုက် ခွဲထားတဲ့ မှတ်တမ်းတွေ စုတာမှာ ဒီနည်းကို သုံးပါတယ်။

"w" overwrites, "a" appends mode "w" Hello write("Hi") Hi old content erased! mode "a" Hello write("Hi") HelloHi added at the end
write mode (ဖျက်ရေးထပ်) နဲ့ append mode (အဆုံးမှာ ဆက်ထည့်) ကွာခြားချက်

Reference

  • Reading/writing files — ဖိုင်များစွာ တွဲကိုင်တွယ်နည်း
  • Input/output — ဖိုင် method များ

ဖိုင်ဖျက်ခြင်း — os.remove()

ဖိုင် ဖျက်ဖို့ os module ရဲ့ remove() ကို သုံးပါတယ်။ ဒါပေမဲ့ မရှိတဲ့ ဖိုင်ကို ဖျက်မိရင် error တက်မှာမို့၊ အရင် os.path.exists() နဲ့ စစ်တာ အကျင့်ကောင်းပါ။

import os

filename = "old_notes.txt"
if os.path.exists(filename):
    os.remove(filename)
    print(filename, "ကို ဖျက်ပြီးပါပြီ။")
else:
    print(filename, "ဆိုတဲ့ ဖိုင် မရှိပါ။")

Output (ဖိုင် ရှိတဲ့အခါ):

old_notes.txt ကို ဖျက်ပြီးပါပြီ။

သတိပြုရန် — ဖျက်လိုက်တဲ့ ဖိုင်က recycle bin ထဲ မရောက်ဘဲ အပြီးတိုင် ပျောက်သွားပါတယ်။ os.remove() မခေါ်ခင် ဖိုင်နာမည် သေချာစစ်ပါ။ အရေးကြီးဖိုင်တွေဆို အရင် backup ကူးထားတာ ပိုစိတ်ချရပါတယ်။

Reference


Mini System ၁ — ကျောင်းသား မှတ်တမ်းစနစ် (Student Report Card System)

အခု သင်ထားတာတွေကို စုပြီး စနစ်လေး တစ်ခု တည်ဆောက်ကြည့်ရအောင်။ ကျောင်းသားတွေရဲ့ အမည်၊ ဘာသာရပ်၊ အမှတ်တွေကို ဖိုင်ထဲ သိမ်းမယ့် စနစ်ပါ။

def save_record():
    name = input("ကျောင်းသား အမည်: ")
    subject = input("ဘာသာရပ်: ")
    marks = input("အမှတ်: ")
    with open("report_card.txt", "a", encoding="utf-8") as f:
        f.write(f"{name},{subject},{marks}\n")
    print("မှတ်တမ်း သိမ်းပြီးပါပြီ!\n")

def show_records():
    print("\n--- မှတ်တမ်းအားလုံး ---")
    try:
        with open("report_card.txt", "r", encoding="utf-8") as f:
            for line in f:
                name, subject, marks = line.strip().split(",")
                print(f"အမည်: {name} | ဘာသာရပ်: {subject} | အမှတ်: {marks}")
    except FileNotFoundError:
        print("မှတ်တမ်း မရှိသေးပါ။ အရင် ထည့်ပါ။")
    print("----------------------\n")

def find_record():
    keyword = input("ရှာမယ့် အမည်: ")
    found = False
    try:
        with open("report_card.txt", "r", encoding="utf-8") as f:
            for line in f:
                name, subject, marks = line.strip().split(",")
                if keyword.lower() in name.lower():
                    print(f"တွေ့ပြီ: {name} | {subject} | {marks}")
                    found = True
    except FileNotFoundError:
        print("မှတ်တမ်း မရှိသေးပါ။")
    if not found:
        print("မတွေ့ပါ။\n")

def report_system():
    while True:
        print("1. မှတ်တမ်းထည့်မယ်")
        print("2. အားလုံးကြည့်မယ်")
        print("3. ရှာမယ်")
        print("4. ထွက်မယ်")
        choice = input("ရွေးပါ: ")
        if choice == "1":
            save_record()
        elif choice == "2":
            show_records()
        elif choice == "3":
            find_record()
        elif choice == "4":
            print("နှုတ်ဆက်ပါတယ်!")
            break
        else:
            print("1-4 အတွင်း ရွေးပေးပါ!\n")

report_system()

ဒီမှာ သင်ထားတဲ့ အရာအားလုံး ပါဝင်ပါတယ် — append mode နဲ့ ရေးတာ၊ with နဲ့ ဖတ်တာ၊ FileNotFoundError ကိုင်တွယ်တာ၊ ကော်မာ (,) နဲ့ ခွဲထားတဲ့ format ကို split(",") နဲ့ ပြန်ခွဲတာ။ ဒီ format ကို CSV ပုံစံ လို့ ခေါ်ပြီး၊ တကယ့် လုပ်ငန်းတွေမှာ အသုံးအများဆုံးပါ။

Sample run:

1. မှတ်တမ်းထည့်မယ်
2. အားလုံးကြည့်မယ်
3. ရှာမယ်
4. ထွက်မယ်
ရွေးပါ: 1
ကျောင်းသား အမည်: မောင်မောင်
ဘာသာရပ်: သင်္ချာ
အမှတ်: 85
မှတ်တမ်း သိမ်းပြီးပါပြီ!

Reference

  • Reading/writing files — ဖိုင်ကို အခြေခံတဲ့ program များ
  • User input — menu စနစ်အတွက် input ကိုင်တွယ်နည်း

Mini System ၂ — Login စနစ်

အကောင့်ဖွင့် (register) ပြီး ပြန်ဝင် (login) လို့ရတဲ့ စနစ်လေးပါ။ အချက်အလက်ကို accounts.txt ဖိုင်ထဲ သိမ်းပါတယ်။

def create_account():
    username = input("အသုံးပြုသူ အမည်: ")
    password = input("စကားဝှက်: ")
    with open("accounts.txt", "a", encoding="utf-8") as f:
        f.write(f"{username},{password}\n")
    print("အကောင့် ဖွင့်ပြီးပါပြီ!\n")

def sign_in():
    username = input("အမည်: ")
    password = input("စကားဝှက်: ")
    try:
        with open("accounts.txt", "r", encoding="utf-8") as f:
            for line in f:
                saved_user, saved_pass = line.strip().split(",")
                if saved_user == username and saved_pass == password:
                    print(f"ကြိုဆိုပါတယ်၊ {username}!\n")
                    return
        print("အမည် သို့မဟုတ် စကားဝှက် မှားနေပါတယ်။\n")
    except FileNotFoundError:
        print("အကောင့် မရှိသေးပါ။ အရင် ဖွင့်ပါ။\n")

def login_system():
    while True:
        print("1. အကောင့်ဖွင့်မယ်")
        print("2. ဝင်မယ်")
        print("3. ထွက်မယ်")
        choice = input("ရွေးပါ: ")
        if choice == "1":
            create_account()
        elif choice == "2":
            sign_in()
        elif choice == "3":
            break
        else:
            print("1-3 အတွင်း ရွေးပေးပါ!\n")

login_system()

မှတ်ထားသင့်တာက — ဒီ program က ဖိုင်ထဲက စာကြောင်းတိုင်းကို လိုက်ဖတ်ပြီး အမည်+စကားဝှက် ကိုက်ညီတာ တွေ့တာနဲ့ ချက်ချင်း return ထွက်သွားတာပါ။ မတွေ့ရင် loop ဆုံးပြီး "မှားနေပါတယ်" လို့ ပြပါတယ်။

သတိပြုရန် — လုံခြုံရေး အရေးကြီး: ဒီဥပမာမှာ စကားဝှက်ကို ဖိုင်ထဲ အတိုင်း (plaintext) သိမ်းထားတာပါ။ ဒါဟာ သင်ယူဖို့ သက်သက်သာ အဆင်ပြေပြီး၊ တကယ့် application တွေမှာ လုံးဝ လုပ်လို့ မရပါဘူး — ဖိုင်ကို တစ်စုံတစ်ယောက် ဖွင့်ကြည့်လိုက်တာနဲ့ စကားဝှက်တွေ အားလုံး ပေါ်ကုန်မှာပါ။ တကယ့် လုပ်ငန်းမှာ စကားဝှက်ကို တိုက်ရိုက် မသိမ်းဘဲ၊ hash လုပ်ပြီး သိမ်းရပါတယ် (ဥပမာ bcrypt၊ scrypt လို library တွေ သုံးပြီး)။ Hash ဆိုတာ စကားဝှက်ကို ပြန်ဖော် မရအောင် ပြောင်းထားတဲ့ ပုံစံပါ — စနစ်က ရိုက်ထည့်တဲ့ စကားဝှက်ကို hash ပြန်လုပ်ပြီး တိုက်စစ်တာပါ။ Password နဲ့ ပတ်သက်တဲ့ တကယ့် project လုပ်တဲ့အခါ ဒီအချက်ကို မမေ့ပါနဲ့။

Reference

  • Reading/writing files — ဖိုင်ထဲ အချက်အလက် သိမ်းနည်း
  • User input — အသုံးပြုသူ အချက်အလက် ရယူနည်း

Mini System ၃ — To-Do List စီမံခန့်ခွဲမှု

နေ့စဉ် လုပ်စရာတွေကို မှတ်ထားတဲ့ စနစ်ပါ။ [ ] ဆိုတာ မပြီးသေးဘူး၊ [x] ဆိုတာ ပြီးပြီ လို့ အမှတ်အသားလုပ်ပါတယ်။

def add_task():
    task = input("လုပ်စရာ အသစ်: ")
    with open("tasks.txt", "a", encoding="utf-8") as f:
        f.write(f"[ ] {task}\n")
    print("ထည့်ပြီးပါပြီ!\n")

def show_tasks():
    print("\n--- လုပ်စရာများ ---")
    try:
        with open("tasks.txt", "r", encoding="utf-8") as f:
            lines = f.readlines()
            if not lines:
                print("(လုပ်စရာ မရှိပါ)")
            for i, line in enumerate(lines, start=1):
                print(f"{i}. {line.strip()}")
    except FileNotFoundError:
        print("(လုပ်စရာ မရှိပါ)")
    print("-------------------\n")

def finish_task():
    try:
        with open("tasks.txt", "r", encoding="utf-8") as f:
            tasks = f.readlines()
    except FileNotFoundError:
        print("လုပ်စရာ မရှိသေးပါ။\n")
        return

    for i, task in enumerate(tasks, start=1):
        print(f"{i}. {task.strip()}")
    try:
        num = int(input("ပြီးသွားတဲ့ နံပါတ်: ")) - 1
    except ValueError:
        print("နံပါတ် ထည့်ပေးပါ!\n")
        return
    if 0 <= num < len(tasks):
        if tasks[num].startswith("[ ]"):
            tasks[num] = tasks[num].replace("[ ]", "[x]", 1)
            with open("tasks.txt", "w", encoding="utf-8") as f:
                f.writelines(tasks)
            print("ပြီးသွားပြီအဖြစ် အမှတ်အသားလုပ်ပြီးပါပြီ!\n")
        else:
            print("ဒါက ပြီးသားပါ။\n")
    else:
        print("နံပါတ် မှားနေပါတယ်။\n")

def todo_system():
    while True:
        print("1. လုပ်စရာ ထည့်မယ်")
        print("2. ကြည့်မယ်")
        print("3. ပြီးပြီလို့ မှတ်မယ်")
        print("4. ထွက်မယ်")
        choice = input("ရွေးပါ: ")
        if choice == "1":
            add_task()
        elif choice == "2":
            show_tasks()
        elif choice == "3":
            finish_task()
        elif choice == "4":
            break
        else:
            print("1-4 အတွင်း ရွေးပေးပါ!\n")

todo_system()

ဒီမှာ နည်းပညာ အသစ် တစ်ခု ပါဝင်ပါတယ် — finish_task() မှာ ဖိုင်တစ်ခုလုံးကို readlines() နဲ့ ဖတ်ပြီး၊ list ထဲမှာ ပြင်ဆင်ပြီး၊ "w" mode နဲ့ ပြန်ရေးတာပါ။ ဖိုင်ထဲက အကြောင်းအရာကို ပြင်ဆင်ချင်ရင် ဒါဟာ အသုံးအများဆုံး ပုံစံပါ — ဖတ် → memory ထဲ ပြင် → ပြန်ရေး။

Sample run:

1. လုပ်စရာ ထည့်မယ်
2. ကြည့်မယ်
3. ပြီးပြီလို့ မှတ်မယ်
4. ထွက်မယ်
ရွေးပါ: 2

--- လုပ်စရာများ ---
1. [ ] စာအုပ် ဝယ်မယ်
2. [ ] Python လေ့ကျင့်မယ်
-------------------

Reference

  • Reading/writing files — ဖိုင်ပြင်ဆင်နည်း (read-modify-write)
  • User input — menu စနစ် input ကိုင်တွယ်နည်း

လေ့ကျင့်ခန်းများ

  1. [လွယ်ကူ] နေ့စဉ် မှတ်တမ်း — အသုံးပြုသူကို ဒီနေ့ ဖြစ်ပျက်ခဲ့တာတွေ ရိုက်ထည့်ခိုင်းပြီး journal.txt ထဲ append mode ("a") နဲ့ သိမ်းတဲ့ program ရေးပါ။ ရက်စွဲနဲ့အတူ သိမ်းပါ။ (Hint: input() နဲ့ ရက်စွဲ တောင်းပါ။)

  2. [အလတ်စား] စကားလုံး ရေတွက်စက် — ဖိုင်နာမည် တစ်ခုတောင်းပြီး၊ အဲဒီဖိုင်ထဲက စာကြောင်း အရေအတွက်၊ စကားလုံး အရေအတွက်၊ စာလုံး အရေအတွက်တို့ကို ရေတွက်ပြပါ။ FileNotFoundError ကို try/except နဲ့ ကိုင်တွယ်ပါ။

  3. [အလတ်စား] စကားလုံး ရှာဖွေသူ — ဖိုင်နာမည် + ရှာမယ့် စကားလုံး တောင်းပြီး၊ တွေ့တဲ့ စာကြောင်း နံပါတ်တွေကို ပြတဲ့ program ရေးပါ။ enumerate(file, start=1) သုံးပါ။ မတွေ့ရင် "မတွေ့ပါ" လို့ ပြပါ။

  4. [ခက်ခဲ] ကျောင်းသား မှတ်တမ်းစနစ် အဆင့်မြှင့် — အပေါ်က report card စနစ်ကို အခြေခံပြီး၊ ပျမ်းမျှ အမှတ် တွက်ပြတဲ့ menu (option 4: "ပျမ်းမျှကြည့်မယ်") တစ်ခု ထပ်ထည့်ပါ။ အမှတ်တွေကို float() နဲ့ ပြောင်းပြီး ပျမ်းမျှ တွက်ပါ။

  5. [ခက်ခဲ] ဖိုင် အရန်သိမ်းစက် (backup) — ဖိုင်နာမည် တစ်ခုတောင်းပြီး၊ ဥပမာ notes.txt ဆိုရင် backup_notes.txt ဖြစ်ရမယ်။ မူရင်းဖိုင် မရှိရင် သင့်တော်တဲ့ message ပြပါ။