156 lines
5 KiB
Python
156 lines
5 KiB
Python
import csv
|
|
import os
|
|
import pickle
|
|
import random
|
|
import sys
|
|
import termios
|
|
import tty
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
class Flashcards:
|
|
def __init__(self):
|
|
self.cards = {}
|
|
self.selected_category = None
|
|
self.current_cards = None
|
|
self.current_card_index = 0
|
|
self.side = 0 # 0 = korean, 1 = eng
|
|
|
|
self.difficult_cards = []
|
|
self.difficult_pickle_path = "difficult_cards.pkl"
|
|
self.load_difficult_cards()
|
|
|
|
def save_difficult_cards(self):
|
|
with open(self.difficult_pickle_path, "wb") as f:
|
|
pickle.dump(self.difficult_cards, f)
|
|
|
|
def load_difficult_cards(self):
|
|
if Path(self.difficult_pickle_path).exists():
|
|
with open(self.difficult_pickle_path, "rb") as f:
|
|
self.difficult_cards = pickle.load(f)
|
|
|
|
@staticmethod
|
|
def get_key():
|
|
fd = sys.stdin.fileno()
|
|
old_settings = termios.tcgetattr(fd)
|
|
|
|
try:
|
|
tty.setraw(fd)
|
|
return sys.stdin.read(1)
|
|
finally:
|
|
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
|
|
|
|
@staticmethod
|
|
def clear():
|
|
print("\033[2J\033[H", end="")
|
|
|
|
def main(self):
|
|
self.parse_cards()
|
|
self.select_category()
|
|
self.loop()
|
|
|
|
def select_category(self):
|
|
self.current_card_index = 0
|
|
self.side = 0
|
|
self.clear()
|
|
print("Categories")
|
|
print('============================')
|
|
for idx, category in enumerate(list(self.cards.keys())):
|
|
print(f"[{idx}] {category}")
|
|
|
|
if len(self.difficult_cards) > 0:
|
|
print('[d] Difficult Cards')
|
|
|
|
print("\n")
|
|
resp = input("Select a Category: ")
|
|
|
|
if resp == 'd':
|
|
self.selected_category = "Difficult Cards"
|
|
self.current_cards = random.sample(self.difficult_cards, len(self.difficult_cards))
|
|
else:
|
|
self.selected_category = list(self.cards.keys())[int(resp)]
|
|
self.current_cards = random.sample(self.cards[self.selected_category], len(self.cards[self.selected_category]))
|
|
|
|
def parse_cards(self):
|
|
for root, dirs, files in os.walk("."):
|
|
for file_name in files:
|
|
file_path = os.path.join(root, file_name)
|
|
if '.tsv' in file_path:
|
|
with open(file_path, 'r') as f:
|
|
reader = csv.reader(f, delimiter="\t")
|
|
for idx, row in enumerate(reader):
|
|
if idx == 0:
|
|
self.cards[row[0]] = []
|
|
self.cards[row[0]].append(row[1:])
|
|
|
|
self.cards = dict(sorted(self.cards.items()))
|
|
|
|
def loop(self):
|
|
while True:
|
|
self.card_screen()
|
|
|
|
key = self.get_key()
|
|
if key == "k":
|
|
self.flip_card()
|
|
elif key == "j":
|
|
self.flip_card()
|
|
elif key == "l":
|
|
self.next_card()
|
|
elif key == "h":
|
|
self.prev_card()
|
|
elif key == "d":
|
|
self.add_difficult_card()
|
|
elif key == "x":
|
|
self.rm_difficult_card()
|
|
elif key == "c":
|
|
self.select_category()
|
|
elif key == "q":
|
|
break
|
|
|
|
def next_card(self):
|
|
if self.current_card_index < len(self.current_cards) - 1:
|
|
self.current_card_index += 1
|
|
|
|
def prev_card(self):
|
|
if self.current_card_index > 0:
|
|
self.current_card_index -= 1
|
|
|
|
def add_difficult_card(self):
|
|
if self.current_cards[self.current_card_index] not in self.difficult_cards:
|
|
print("adding card...")
|
|
self.save_difficult_cards()
|
|
self.difficult_cards.append(self.current_cards[self.current_card_index])
|
|
|
|
def rm_difficult_card(self):
|
|
print("removing card...")
|
|
self.save_difficult_cards()
|
|
discarded = self.current_cards.pop(self.current_card_index)
|
|
self.difficult_cards.remove(discarded)
|
|
if self.current_card_index > len(self.difficult_cards) - 1:
|
|
self.current_card_index = len(self.difficult_cards) - 1
|
|
if len(self.difficult_cards) == 0:
|
|
self.current_card_index = 0
|
|
self.side = 0
|
|
self.select_category()
|
|
|
|
def card_screen(self):
|
|
self.clear()
|
|
print(f"{self.selected_category} | {self.current_card_index + 1}/{len(self.current_cards)} | DC {len(self.difficult_cards)} {'*' if self.current_cards[self.current_card_index] in self.difficult_cards else ''}")
|
|
print('----------------------------------------------\n')
|
|
print(self.current_cards[self.current_card_index][self.side])
|
|
|
|
print('\n\n\n\n')
|
|
print('vim keys to move cards | q: quit | c: change category')
|
|
print('d: add to difficult cards | x: remove from difficult cards')
|
|
|
|
def flip_card(self):
|
|
if self.side == 0:
|
|
self.side = 1
|
|
else:
|
|
self.side = 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
f = Flashcards()
|
|
f.main()
|