diff --git a/README.md b/README.md index 1e239b2..0bf1878 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Rtutor is an application written in python to train yourself to use vim fast way - Repeat question on random moment if you answered it wrong. You have to learn! ## Usage -This application has no dependencies. Instead of cloning this git, you can just do wget or copy the raw source code of [rtutor.py](rtutor.py). +This application has no dependencies. Instead of cloning this git, you can just do wget or copy the raw source code of [rvimtutor.py](rvimtutor.py). ``` python3 rtutor.py ``` diff --git a/rtutor.py b/rtutor.py deleted file mode 100755 index 058929d..0000000 --- a/rtutor.py +++ /dev/null @@ -1,308 +0,0 @@ -#!/usr/bin/env python3 - -# RETOOR - -import sys -import termios -import tty -import random -import time -import select - -key_mapping = { - "[A": "up", - "[B": "down", - "[C": "right", - "[D": "left", - "2A": "shift+up", - "2B": "shift+down", - "2C": "shift+right", - "2D": "shift+left", - "5A": "ctrl+up", - "5B": "ctrl+down", - "5C": "ctrl+right", - "5D": "ctrl+left", - "\x17": "C-w", - "\x0f": "C-o", - "\x03": "C-c", - "\x07": "C-g", -} - - -def get_key(key_previous=None): - fd = sys.stdin.fileno() - old_settings = termios.tcgetattr(fd) - special_char = "\x1b" - if key_previous is None: - key_previous = special_char - try: - tty.setraw(fd) - key = sys.stdin.read(1) - if key in key_mapping: - return key_mapping[key] - if key == "[": - key += sys.stdin.read(1) - if key in key_mapping: - return key_mapping.get(key, key) - if key[-1] == "1": # shift plus special key - if sys.stdin.read(1) == ";": # ;followed by key - key = sys.stdin.read(2) - return key_mapping.get(key, key) - if key == special_char: - time.sleep(0.1) - if sys.stdin in select.select([sys.stdin], [], [], 0)[0]: - key += sys.stdin.read(2) - key = key_mapping.get(key, key) - - finally: - termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) - - return key - - -def clear_terminal(): - sys.stdout.write("\033[2J") - # Move cursor - sys.stdout.write("\033[H") - sys.stdout.flush() - - -class Randoms: - - input_choices = list("abcdefghijklmnopqrstuvwxyz") - word_choices = word_list = [ - "apple", - "banana", - "cherry", - "date", - "elderberry", - "fig", - "grape", - "honeydew", - "kiwi", - "lemon", - "mango", - "nectarine", - "orange", - "pear", - "quince", - "raspberry", - "strawberry", - "tangerine", - "ugli", - "vaccine", - "watermelon", - "xigua", - "yam", - "zucchini", - ] - - def __init__(self): - self.replace = {} - self.replace[""] = random.choice(self.input_choices) - self.replace[""] = random.choice(self.input_choices) - self.replace[""] = random.choice(self.input_choices) - self.replace[""] = random.randint(2, 5) - self.replace[""] = random.randint(2, 5) - self.replace[""] = random.randint(2, 5) - self.replace[""] = random.choice(self.word_choices) - self.replace[""] = random.choice(self.word_choices) - self.replace[""] = random.choice(self.word_choices) - - def apply(self, task): - task.question = task.base_question - task.keyboard_input = task.base_keyboard_input - for key, value in self.replace.items(): - task.question = task.question.replace(key, str(value)) - task.keyboard_input = task.keyboard_input.replace( - key, ",".join(list(str(value))) - ) - task.applied_random = ( - task.question != task.base_question - or task.keyboard_input != task.base_keyboard_input - ) - - -class Task: - - questions_total = 0 - - def __init__(self, question, keyboard_input): - Task.questions_total += 1 - self.question_number = Task.questions_total - self.base_question = question - self.base_keyboard_input = keyboard_input - self.question = question - self.keyboard_input = keyboard_input - self.success = False - self.tasks = [] - self.applied_random = False - self.first_time_executed = True - r = Randoms() - r.apply(self) - - def add_task(self, task): - self.tasks.append(task) - - def execute(self): - if not self.first_time_executed: - r = Randoms() - r.apply(self) - self.first_time_executed = False - print("{}".format(self.question)) - index = 0 - mistake = False - key_previous = None - for expected in self.keyboard_input.split(","): - key = get_key(key_previous) - key_previous = key - if key == "\x1b": - key = get_key(key_previous) - key_previous = key - if key == "C-c": - raise KeyboardInterrupt() - if key == "\x17": - print("CTRL+W") - else: - print(key, end="", flush=True) - if expected == key: - index += 1 - else: - mistake = True - - if mistake: - print('\n"{}" is incorrect.'.format(repr(key))) - print( - '\nExpected input: "{}".'.format( - self.keyboard_input.replace(",", "") - ) - ) - print("\nPress any key to continue...") - get_key(None) - break - if key == "q": - break - if not mistake: - self.success = True - print("") - print( - random.choice( - ["Great!", "Excelent!", "Awesome!", "Keep it up!", "Perfect!"] - ) - ) - print("") - self.success = all([task.execute() for task in self.tasks]) - time.sleep(0.40) - return self.success - - -tasks = [ - Task("Open terminal\n", ":,terminal,\r"), - Task("Delete from the cursor to the end of the word.", "d,e"), - Task("Delete from the cursor to the end of the line.", "d,$"), - Task("Delete from the cursor to the beginning of the next word.", "d,w"), - Task("Delete lines using a numeric value.", ",d,d"), - Task("Move backward in the search results.", "N"), - Task("Move forward in the search results.", "n"), - Task("Move to line number .", ",G"), - Task("Undo all changes on the current line.", "U"), - Task("Move to the end of the word.", "e"), - Task("Move to the beginning of the line.", "0"), - Task("Search backward for .", ":,?,,\r"), - Task("Search forward for .", ":,/,,\r"), - Task("Display the current location in the status bar.", "C-g"), - Task("Indent the selected text.", ">,>"), - Task("De-indent the selected text.", "<,<"), - Task("Save the document as .py.", ":,w, ,,.,p,y,\r"), - Task("Replace the first occurrence of with .", ":,s,/,,/,,/,g"), - Task( - "Replace all occurrences of with in the entire file.", - ":,%,s,/,,/,,/,g", - ), - Task( - "Replace all occurrences of with in the entire file, with confirmation for each change.", - ":,%,s,/,,/,,/,g,c", - ), - Task( - "Select the next five characters and save them to a file.", - "v,right,right,right,right,:,w", - ), - Task("Exit Vim.", ":,q"), - Task("Split the screen vertically.", ":,v,s,p,l,i,t,\r"), - Task("Split the screen horizontally.", ":,s,p,l,i,t,\r"), - Task("Merge the file .txt into the current file.", ":,r, ,,.,t,x,t,\r"), - Task( - "Move three words to the left without using numeric values.", - "ctrl+left,ctrl+left,ctrl+left", - ), - Task( - "Move three words to the right without using numeric values.", - "ctrl+right,ctrl+right,ctrl+right", - ), - Task("Return to the previous position.", "C-o"), - Task("Type .", ""), - Task("Indent the current line and the two lines below.", "v,down,down,>,>"), - Task("Enable case-sensitive search.", ":,s,e,t, ,n,o,i,c"), - Task("Enable case-insensitive search.", ":,s,e,t, ,i,c"), - Task("Copy the word under the cursor.", "y,w"), - Task("Replace the text under the cursor with .", "R,"), - Task("Insert text at the end of the line.", "A"), - Task("Insert text after the cursor.", "a"), - Task("Insert a new line below the current line.", "o"), - Task("Insert a new line above the current line.", "O"), - Task("Move to the beginning of the document.", "g,g"), - Task("Move to the end of the line.", "$"), - Task("Move to the end of the document.", "G"), - Task( - "Select the next four characters and copy them.", "v,right,right,right,right,y" - ), - Task("Switch to the next window.", "C-w,C-w"), - Task("Swap the position of the current window with another.", "C-w,r"), - Task("Copy the current line.", "y,y"), - Task("Copy all content.", "y"), - Task("Paste the copied content.", "p"), - Task("Replace the character under the cursor with ''.", "r,"), - Task("Delete the character under the cursor.", "x"), - Task("Delete the line under the cursor.", "d,d"), - Task("Cut the current line.", "c,c"), - Task("Type .", ""), -] - - -# shift select Move with>> -def main(): - questions_correct = [] - questions_incorrect = [] - question_count = 0 - durations = [] - while tasks: - clear_terminal() - if not durations: - avg_reaction_time = 0 - else: - avg_reaction_time = sum(durations) / len(durations) - num_correct = len(questions_correct) - num_incorrect = len(questions_incorrect) - avg_time = round(sum(durations) / len(durations), 2) if durations else 0 - print( - "Correct: {}\tIncorrect: {}\tAvg reaction time: {}".format( - num_correct, num_incorrect, avg_time - ) - ) - print("") - question_count += 1 - task = random.choice(tasks) - print("{}. ".format(question_count), end="") - time_start = time.time() - if task.execute(): - tasks.remove(task) - questions_correct.append(task) - else: - questions_incorrect.append(task) - time_end = time.time() - durations.append(time_end - time_start) - - -if __name__ == "__main__": - main() -