Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
iakovlev.org

Тренажёр

Я написал программу на питоне, которая представляет из себя тренажер по запоминанию английских слов.
Есть стандартная библиотека curses - низкоуровневая библиотека управления терминалом для Unix-подобных операционных систем, позволяющая создавать приложения с текстовым интерфейсом пользователя, написанная на си.
В питоне есть модуль с аналогичным названием, который использует api-функции из этой библиотеки. Документацию можно почитать тут

Тренажер работает по следующему алгоритму:
При первом запуске появится меню, с помощью которого нужно выбрать один из тематических словарей.
Каждый такой тематический словарь представляет из себя текстовой файл, каждая строка которого состоит из пары слов, разделенных точкой с запятой. Вместо одного слова можно поставить произвольное количество слов, слева - английский вариант, справа - русский, например:

 adjective ; прилагательное
 adverb ; наречие
 arrow ; стрела
 backfires ; ответка, неприятное последствие, отдача
 blank ; пустой, пробел
 bullet ; пуля
 had brought ; привез
 

При запуске тренажер инициализирует несколько переменных:
 настройка языка - либо eng, либо ru
 стартовое число вопросов, минимум - 3
 число вариантов ответа на один вопрос, минимум - 3
 время для ответа на один вопрос, в секундах, минимум - 1
 
Настройка языка - от этого параметра зависит направление перевода - с английского на русский или наоборот.
Стартовое число вопросов - минимальное значение равно трем, дальше его можно увеличивать в процессе тренировки до бесконечности.
Число вариантов ответа на один вопрос, минимум - 3. Обычно 3-х вариантов ответа достаточно.
Время для ответа на один вопрос, в секундах, минимум - 1. Его можно поставить с большим запасом, это уже зависит от ваших личных предпочтений.
Т.е. эти настройки вы можете настраивать каждый раз перед запуском тренажера.

После запуска у вас появляется слово на выбранном языке и три варианта ответа, один из вариантов ответа правильный. Нужно выбрать правильный вариант ответа с помощью управляющих стрелок либо клавиши пробел. Выбрав правильный ответ, можно либо нажать на клавишу enter, либо просто ждать.

После того, как будет пройден весь список, будет показан результат - либо ошибки, либо все правильно. В первом случае будут показаны те слова, в которых вы допустили ошибку, с правильными вариантами переводов. Во втором случае будут показаны все слова вместе с переводом
Далее вы можете пройти весь список еще раз, при этом те же слова будут перетасованы в ином порядке.

Вы можете выбрать один из двух вариантов прохождения теста. В первом случае слова берутся с начала текстового файла по порядку от начала текстового файла, и очередное слово - или несколько слов - могут быть добавлены каждый раз, когда вы проходите тест. Добавление слова выполняется с помощью клавиши плюс,
Второй вариант позволяет вам выбрать произвольный набор слов, для этого нужно перейти в режим выбора с помощью клавиши '/', слова выбираются из списка с помощью клавиши пробел.

Код можно скачать тут .


 import random
 import curses
 
 def settings():
     lang = {'eng':[0,1], 'ru':[1,0], }
     language = 'eng'    # настройка языка - либо eng, либо ru
     count_questions = 3 # стартовое число вопросов, минимум - 3
     variants = 3        # число вариантов ответа на один вопрос, минимум - 3
     time_for_answer = 3 # время для ответа на один вопрос, в секундах, минимум - 1
     return lang, language, variants, count_questions, time_for_answer
 
 def get_from_file():
     lines = None
     with open('words.txt') as f:
         lines = f.readlines()
     
     words = []
     for line in lines:
         word = []
         _words = line.split(';')
         for w in _words:
             word.append(w.strip())
         if len(word) == 2:
             words.append(word)    
 
     return words
 
 # рандомная инициализация данных
 def get_words(words, variants, count_questions, read_from_file):
     if read_from_file is True:
         _words = get_from_file()
         words = _words[:count_questions]
     count = 0
     check_answers = []
     words_index = []
     while True:
         rnd = random.randint(0, count_questions-1)
         if rnd not in words_index:
             words_index.append(rnd)
         if len(words_index) == count_questions:
             break
 
     words_rnd = []
     for i in words_index:
         check_answers.append(0)
         _rnd = []
         while True:
             rnd = random.randint(0, count_questions-1)
             if rnd not in _rnd:
                 _rnd.append(rnd)
             if len(_rnd) == variants:
                 if i not in _rnd:
                     _rnd = []
                 else:    
                     words_rnd.append(_rnd)
                     break
 
     return words, words_index, words_rnd, check_answers
 
 # добавление 
 def add_word(words, count_questions):
     _words = get_from_file()
     for _word in _words:
         if _word not in words:
             words.append(_word)
             count_questions += 1
             break
     return words, count_questions
 
 def print_answers(words, index, rnd, check_answers, answerbox, right_answers):
     answerbox.clear()
     answerbox.box()
     count = 0
     count_error = 0
     for i in index:
         if check_answers[count] == 0:
             answerbox.addstr(3 + count_error, 1, str(words[index[count]]))
             count_error += 1
         count += 1    
     for i in index:
         check_answers.append(0)
     if count_error > 0:
         answerbox.addstr(1,1, " Ответы : " + str(right_answers) + ' из ' + str(len(words)))
         answerbox.addstr(2,1, " Ошибки в словах : ")
     else:
         answerbox.addstr(1,1, " Ошибок нет ! ")
         answerbox.addstr(2,1, " Все ответы правильные : " + str(right_answers) + ' из ' + str(len(words)))
         count = 0    
         count_error = 0
         for i in index:
             if check_answers[count] == 1:
                 answerbox.addstr(3 + count_error, 1, str(words[index[count]]))
                 count_error += 1
             count += 1    
     check_answers = []
 
     answerbox.refresh()
     return check_answers
 
 
 # проверяем ответ для текущей строки, перерисовываем экран вариантов ответа
 def next_word(word_index, words, index, rnd,  position, answerbox, right_answers, 
               resultbox, stdscr, check_answers, variants, count_questions, questionbox):
     _time2 = 0
 
     answerbox.clear()
     answerbox.box()
 
     count = 0
     ii = 0
     rnd_count = []
     _found = 0
     for i in index:
         if count == word_index:
             ii = i
             if i == rnd[count][position]:
                 right_answers += 1
                 check_answers[count] = 1
                 _found = 1
         count += 1    
 
     position = 0    
     word_index += 1
 
     #################################### итог ########################################### 
     if word_index == len(words):
         word_index = 0
         check_answers = print_answers(words, index, rnd, check_answers, answerbox, right_answers)
         resultbox.clear()
         resultbox.box()
         resultbox.refresh()
         resultbox.addstr(1,3, " Продолжить - нажмите пробел")
         resultbox.addstr(2,3, " Добавить новое слово - клавиша + ")
         # resultbox.addstr(3,3, " Выход - клавиша ENTER")
         questionbox.clear()
         questionbox.box()
         questionbox.refresh()
 
         while True:
             next_key = resultbox.getch()
             key = key if next_key == -1 else next_key
             if key == ord(' '):
                 break
             if key == 43:
                 #count_questions += 1
                 words, count_questions = add_word(words, count_questions)
                 break
 
         resultbox.clear()
         resultbox.box()
         resultbox.refresh()
         answerbox.clear()
         answerbox.box()
         answerbox.refresh()
         right_answers = 0
         words, index, rnd, check_answers = get_words(words, variants, count_questions, False)
 
     return _time2, word_index, position, right_answers, check_answers, words, \
     index, rnd, count_questions
 
 
 # перерисовываем курсор
 def redraw_cursor(words, index, rnd, position, word_index, answerbox, questionbox, \
 lang, language, resultbox):
     questionbox.addstr(1,3, '                                                            ')
     questionbox.addstr(1,3, words[index[word_index]][lang[language][0]])
     resultbox.addstr(3,3, '                                                            ')
     resultbox.addstr(3,3, " Выход - клавиша ESC")
 
     _count = 0    
     for i in index:
         if _count == word_index:
             count = 0
             for j in rnd[_count]:
                 if count == position:
                     mode = curses.A_REVERSE
                 else:
                     mode = curses.A_NORMAL
                 msg = "%s" % (words[j][lang[language][1]])
                 answerbox.addstr(1 + count, 1, msg, mode)
                 count += 1
         _count += 1    
 
 def get_key(answerbox, position, key, word_index, words, index, rnd, right_answers, 
             resultbox, stdscr, variants, check_answers):
 
     ok = 0
     next_key = answerbox.getch()
     key = key if next_key == -1 else next_key
 
     if key == curses.KEY_DOWN:
         position += 1
         if position == variants:
             position = 0
     if key == ord(' '):
         position += 1
         if position == variants:
             position = 0
     if key == curses.KEY_UP:
         position -= 1
         if position < 0:
             position = variants - 1
     if key == curses.KEY_LEFT:
         pass
     if key == curses.KEY_RIGHT:
         pass
     if key in [curses.KEY_ENTER, ord("\n")]:
         ok = 1
     if key == 27: # выход - esc
         curses.endwin()
         quit()
 
     return key, position, ok    
 
 def main():
     stdscr = curses.initscr()
     curses.start_color()
 
     curses.noecho()    # не печатать на экране
     curses.cbreak()    # не ждать ввода
     curses.curs_set(0) # не показывать курсор
 
     questionbox = curses.newwin(3,100,5,1) # высота окна, ширина окна, y-координата, x-координата
     questionbox.box()
 
     resultbox = curses.newwin(5,100,0,1)
     resultbox.box()
 
     answerbox = curses.newwin(30, 100, 8, 1)
     answerbox.box()
     answerbox.keypad(1)
     answerbox.timeout(100) # секунда состоит из 10 тиков по 100 миллисекунд
 
     lang, language, variants, count_questions, time_for_answer = settings()
     words, index, rnd, check_answers = get_words([], variants, count_questions, True)
 
     _time1 = 0 
     _time2 = 0 
     word_index = 0
     position = 0
     right_answers = 0
 
     resultbox.addstr(1,3, 
     " Список из " + str(count_questions) + ' слов, ' + ' вариантов перевода - ' + str(variants))
     resultbox.addstr(2,3, " Время на ответ в секундах - " + str(time_for_answer))
     resultbox.addstr(3,3, " Начать тест - нажмите любую клавишу")
     resultbox.getch()
 
     key = curses.KEY_RIGHT 
 
     while True:
         resultbox.refresh()
         questionbox.refresh()
         key, position, ok = get_key(answerbox, position, key, word_index, words, index,
             rnd, right_answers, resultbox, stdscr, variants, check_answers)
         if ok != 1:
             _time1 += 1
             if _time1 == 10:
                 _time1 = 0
                 _time2 += 1    
         if _time2 == time_for_answer or ok == 1:
             _time2, word_index, position, right_answers, check_answers, words, index, rnd, count_questions = \
             next_word(word_index, words, index, rnd, position, answerbox, right_answers, resultbox, stdscr,\
             check_answers, variants, count_questions, questionbox)
         redraw_cursor(words, index, rnd, position, word_index, answerbox, questionbox, lang, \
         language, resultbox)
         key = 0
 
 main()
 
 


Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье