2015-11-04 4 views
-1

Здесь у меня есть код, который дает студентам математическую викторину и сохраняет их оценки в текстовом файле. Теперь я пытаюсь добавить в свой код, чтобы он мог сохранить последние три оценки учащегося до их имени. Для этого я знаю, что мне придется использовать 2D-массивы, но я изо всех сил пытаюсь добавить оператор if в свой код, который по существу говорит: «Если имя в словаре, сохраните оценку, чтобы назвать». Как мне это сделать?Как определить, существует ли значение в словаре?

Вот мой код:

import random 
import sys 

def get_input_or_quit(prompt, quit="Q"): 
    prompt += " (Press '{}' to exit) : ".format(quit) 
    val = input(prompt).strip() 
    if val.upper() == quit: 
     sys.exit("Goodbye") 
    return val 

def prompt_bool(prompt): 
    while True: 
     val = get_input_or_quit(prompt).lower() 
     if val == 'yes': 
      return True 
     elif val == 'no': 
      return False 
     else: 
     print ("Invalid input '{}', please try again".format(val)) 


def prompt_int_small(prompt='', choices=(1,2)): 
    while True: 
     val = get_input_or_quit(prompt) 
     try: 
      val = int(val) 
      if choices and val not in choices: 
       raise ValueError("{} is not in {}".format(val, choices)) 
      return val 
     except (TypeError, ValueError) as e: 
       print(
        "Not a valid number ({}), please try again".format(e) 
        ) 

def prompt_int_big(prompt='', choices=(1,2,3)): 
    while True: 
     val = get_input_or_quit(prompt) 
     try: 
      val = int(val) 
      if choices and val not in choices: 
       raise ValueError("{} is not in {}".format(val, choices)) 
      return val 
     except (TypeError, ValueError) as e: 
       print(
        "Not a valid number ({}), please try again".format(e) 
        ) 

role = prompt_int_small("Are you a teacher or student? Press 1 if you are a student or 2 if you are a teacher") 
if role == 1: 
    score=0 
    name=input("What is your name?") 
    print ("Alright",name,"welcome to your maths quiz." 
      " Remember to round all answers to 5 decimal places.") 
    level_of_difficulty = prompt_int_big("What level of difficulty are you working at?\n" 
           "Press 1 for low, 2 for intermediate " 
            "or 3 for high\n") 


    if level_of_difficulty == 3: 
     ops = ['+', '-', '*', '/'] 
    else: 
     ops = ['+', '-', '*'] 

    for question_num in range(1, 11): 
     if level_of_difficulty == 1: 
      max_number = 10 
     else: 
      max_number = 20 

     number_1 = random.randrange(1, max_number) 
     number_2 = random.randrange(1, max_number) 

     operation = random.choice(ops) 
     maths = round(eval(str(number_1) + operation + str(number_2)),5) 
     print('\nQuestion number: {}'.format(question_num)) 
     print ("The question is",number_1,operation,number_2) 
     answer = float(input("What is your answer: ")) 
     if answer == maths: 
      print("Correct") 
      score = score + 1 
     else: 
      print ("Incorrect. The actual answer is",maths) 

    if score >5: 
     print("Well done you scored",score,"out of 10") 
    else: 
     print("Unfortunately you only scored",score,"out of 10. Better luck next time") 

    class_number = prompt_int_big("Before your score is saved ,are you in class 1, 2 or 3? Press the matching number") 

    filename = (str(class_number) + "txt") 
    with open(filename, 'a') as f: 
     f.write("\n" + str(name) + " scored " + str(score) + " on difficulty level " + str(level_of_difficulty) + "\n") 
    with open(filename) as f: 
     lines = [line for line in f if line.strip()] 
     lines.sort() 

    if prompt_bool("Do you wish to view previous results for your class"): 
     for line in lines: 
      print (line) 
    else: 
     sys.exit("Thanks for taking part in the quiz, your teacher should discuss your score with you later") 
if role == 2: 
    class_number = prompt_int_big("Which class' scores would you like to see? Press 1 for class 1, 2 for class 2 or 3 for class 3") 
    filename = (str(class_number) + "txt") 

    f = open(filename, "r") 
    lines = [line for line in f if line.strip()] 
    lines.sort() 
    for line in lines: 
     print (line) 

Вот раздел, в котором я пытаюсь добавить, если заявление:

class_number = prompt_int_big("Before your score is saved ,are you in class 1, 2 or 3? Press the matching number") 

    filename = (str(class_number) + "txt") 
    with open(filename, 'a') as f: 
     f.write("\n" + str(name) + " scored " + str(score) + " on difficulty level " + str(level_of_difficulty) + "\n") 
    with open(filename) as f: 
     lines = [line for line in f if line.strip()] 
     lines.sort() 
+0

Вместо утверждения '' 'if''', почему бы не использовать блок' '' try''' '' 'except KeyError'''? – Erik

+0

Что вы имеете в виду? – Ibrahim

+0

'if dict.get (key):' будет возвращать ложный тип 'None', если ключ не находится в dict. Альтернативно, 'if key в dict.keys():'? –

ответ

2

Если можно просто сделать 'в'

if 'Name' in Variable: 
    do stuff 

Переменная может быть списком или словарем.

+0

Я бы сделал 'Variable.keys()' ... – Tgsmith61591

+2

@ Tgsmith61591, это неправильный способ сделать это, потому что 'keys()' будет генерировать список - это не только ненужная работа, но и тестирование списка медленнее чем тестирование словаря. –

+0

@MarkRansom очень интересно. Я понятия не имел, что сработало – Tgsmith61591

0

Поскольку вы все равно прочитать содержимое файла обратно в lines, если ваша конечная цель состоит в том, чтобы показать три последние результаты, я предпочел бы подойти к нему путем извлечения информации из там внутри prompt_bool("Do you wish to view previous results for your class") секции вдоль линий:

if prompt_bool("Do you wish to view previous results for your class"): 
    scores_shown=0 
    for line in lines[::-1]: 
    if name==line.split(' scored ')[0].strip(): 
     print(line) 
     scores_shown+=1 
     if scores_shown>=3: 
     break 

Это не будет совместить оценки так же, как и словарь.

Вы можете заполнить словарь списков оценки делать что-то вроде этого:

if name in d: 
    d[name].append(score) 
else: 
    d[name]=[score] 

вы могли бы даже иметь вложенный список, чтобы включить уровень сложности, например: d[name]=[[score,level_of_difficulty]] сделать первый элемент списка, а затем d[name].append([score,level_of_difficulty]) для последующих позиций в словаре d.

Код не удался, если у кого-то есть имя, которое включает строку ' scored '.

На боковой ноте prompt_int_big и prompt_int_small идентичны, за исключением кортежа choices. Чтобы избежать дублирования кода, я бы установил один из них по умолчанию prompt_int, а при использовании другого - просто добавьте его в качестве аргумента, используя гибкость вашего кода; например. prompt_int(choices=(1,2,3)) или prompt_int("my prompt",(1,2,3,4)). Также "txt" может быть заменен на ".txt", чтобы некоторые операционные системы могли понять тип файла.

Смежные вопросы