Thuta Learning
ရှာဖွေရန်
ProjectsProgrammingbeginner

Task Tracker Project - Part 3

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

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • Task Tracker Project - Part 3 ကို လက်တွေ့ project ထဲမှာ အသုံးချတတ်မယ်
  • ကိုယ်တိုင် code ရေးပြီး run ကြည့်တတ်မယ်
  • Project တစ်ခုလုံးကို အဆင့်လိုက် ဆောက်တတ်မယ်

ခဏလေး ဒီလိုပဲ စဉ်းစားကြည့်

ဒီနောက်ဆုံးအဆင့်မှာ Part 2 ကရ app ကို run တိုင်း data ပျောက်နေတာကို ဖြေရှင်းဖို့ File I/O သုံးပြီး task list ကို disk ပေါ် save/load လုပ်ပါမယ်။ display format ကို consistent ဖြစ်အောင် Formatter ဆိုတဲ့ module တစ်ခု ခွဲထုတ်ပြီး module method (self.line) အနေနဲ့ ရေးပါမယ် - modules concept ကို practical အသုံးချတာပါ။ App ကို run တဲ့အခါ welcome message နဲ့ command list ကို ပြသကာ user experience ကို ပိုကောင်းအောင် ပြင်ဆင်ပါမယ်။ ဒီအဆင့်ပြီးရင် Ruby ရဲ့ class, module, file handling, block, iterator concept တွေကို အကုန်ပေါင်းစပ်ထားတဲ့ small command-line project တစ်ခုကို ပိုင်ဆိုင်ပြီးသားပါ။

လက်တွေ့ ဆောက်ကြည့်မယ်

Formatter module ကို def self.line(task, index) method နဲ့ ရေးပြီး status icon (✔ ဒါမှမဟုတ် space) နဲ့ index, title ကို string တစ်ခုအနေနဲ့ ပြန်ပေးပါ - list_tasks method ထဲမှာ ဒီ module method ကို ခေါ်သုံးအောင် ပြင်ပါ။ TaskTracker class ထဲမှာ save(filename) method ကို ထည့်ပြီး File.open(filename, "w") do |f| block နဲ့ task တစ်ခုချင်းစီကို "title|done" format နဲ့ file ထဲ ရေးပါ။ load(filename) method ကတော့ File.exist? နဲ့ file ရှိမရှိ စစ်ပြီး ရှိရင် File.readlines နဲ့ line တစ်ကြောင်းချင်းစီကို split("|") နဲ့ ခွဲကာ Task object အသစ်တွေ ပြန်တည်ဆောက်ပါ။ App စတင်တဲ့အခါ tracker.load ကို အရင်ခေါ်ပြီး exit command ရောက်ရင် tracker.save ကို ခေါ်ကာ data ကို ထိန်းသိမ်းပါ။ နောက်ဆုံး command list ကို ပြသမယ့် help message တစ်ခု app စဖွင့်ချိန် ပြပါ။

Code နမူနာ

ruby
module Formatter
  def self.line(task, index)
    status = task.done ? "✔" : " "
    "#{index}. [#{status}] #{task.title}"
  end
end

class TaskTracker
  def save(filename = "tasks.txt")
    File.open(filename, "w") do |f|
      @tasks.each { |t| f.puts "#{t.title}|#{t.done}" }
    end
  end

  def load(filename = "tasks.txt")
    return unless File.exist?(filename)
    @tasks = File.readlines(filename).map do |line|
      title, done = line.strip.split("|")
      task = Task.new(title)
      task.done = (done == "true")
      task
    end
  end

  def list_tasks
    @tasks.each_with_index { |task, i| puts Formatter.line(task, i + 1) }
  end
end

tracker = TaskTracker.new
tracker.load
puts "Task Tracker - commands: list / add <title> / done <no> / exit"

loop do
  print "> "
  input = gets.chomp
  break if input == "exit"
  # Part 2 ရဲ့ case/when logic ကို ဒီနေရာမှာ ဆက်သုံးပါ
end
tracker.save
You should see
App ကို ပိတ်ပြီး ပြန်ဖွင့်တဲ့အခါ tasks.txt ထဲက data ကို load လုပ်ပြီး ယခင် task list အတိုင်း ပြန်တွေ့ရပါမယ်။

၅ မိနစ် စမ်းကြည့်

save format ကို "title|done" အစား CSV style "title,done,priority" အဖြစ် ပြောင်းပြီး priority attribute ကိုပါ save/load ထဲ ထည့်သွင်းအောင် 5 minutes အတွင်း စမ်းကြည့်ပါ။

သတိလေးတစ်ချက်

File.open block ပြီးရင် Ruby က file ကို auto-close လုပ်ပေးပါတယ် - ဒါပေမဲ့ save/load ကို frequent ခေါ်နေတဲ့ loop ထဲမှာ ထည့်ခြင်းမလုပ်ဘဲ လိုအပ်တဲ့အချိန်မှသာ ခေါ်ဖို့ သတိထားပါ။

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • load method ထဲမှာ File.exist? စစ်ဆေးဖို့ မေ့သွားပြီး file မရှိသေးတဲ့အချိန် app ပထမဆုံးအကြိမ် run ချိန် error တက်တတ်ပါတယ်
  • split("|")ကနေ ရလာတဲ့ done ဟာ "true"/"false" string ဖြစ်နေတာကို မသတိထားဘဲ boolean အဖြစ် တိုက်ရိုက်သုံးမိပြီး logic မှားတတ်ပါတယ်

အခု ကိုယ်တိုင် စမ်းကြည့်

save format ကို "title|done" အစား CSV style "title,done,priority" အဖြစ် ပြောင်းပြီး priority attribute ကိုပါ save/load ထဲ ထည့်သွင်းအောင် 5 minutes အတွင်း စမ်းကြည့်ပါ။

You'll know it worked when: App ကို ပိတ်ပြီး ပြန်ဖွင့်တဲ့အခါ tasks.txt ထဲက data ကို load လုပ်ပြီး ယခင် task list အတိုင်း ပြန်တွေ့ရပါမယ်။

Task Tracker Project - Part 3 | Thuta Learning