У меня есть программа, которая дает игроку случайный штат США, запрашивает его столицу и ведет счет. Это продолжается до тех пор, пока игрок не решит прекратить игру. В конце он выводит как количество правильных ответов, так и количество неправильных ответов.
Я принял во внимание некоторые советы, которые я получил в других своих сообщениях, и поместил словарь в основную функцию (у меня он был раньше в отдельной функции), но мне было интересно, есть ли более эффективный способ выполнить цикл while, который является основой игры, и если бы я преобразовал диктовку в список, это хороший способ решить эту проблему.
MIN = 0
MAX = 49
import random
def main():
stateDict = {'Alabama': 'Montgomery',
'Alaska': 'Juneau',
'Arizona': 'Phoenix',
'Arkansas': 'Little Rock',
'California': 'Sacramento',
'Colorado': 'Denver',
'Connecticut': 'Hartford',
'Delaware': 'Dover',
'Florida': 'Tallahassee',
'Georgia': 'Atlanta',
'Hawaii': 'Honolulu',
'Idaho': 'Boise',
'Illinois': 'Springfield',
'Indiana': 'Indianapolis',
'Iowa': 'Des Moines',
'Kansas': 'Topeka',
'Kentucky': 'Frankfort',
'Louisiana': 'Baton Rouge',
'Maine': 'Augusta',
'Maryland': 'Annapolis',
'Massachusetts': 'Boston',
'Michigan': 'Lansing',
'Minnesota': 'Saint Paul',
'Mississippi': 'Jackson',
'Missouri': 'Jefferson City',
'Montana': 'Helena',
'Nebraska': 'Lincoln',
'Nevada': 'Carson City',
'New Hampshire': 'Concord',
'New Jersey': 'Trenton',
'New Mexico': 'Santa Fe',
'New York': 'Albany',
'North Carolina': 'Raleigh',
'North Dakota': 'Bismarck',
'Ohio': 'Columbus',
'Oklahoma': 'Oklahoma City',
'Oregon': 'Salem',
'Pennsylvania': 'Harrisburg',
'Rhode Island': 'Providence',
'South Carolina': 'Columbia',
'South Dakota': 'Pierre',
'Tennessee': 'Nashville',
'Texas': 'Austin',
'Utah': 'Salt Lake City',
'Vermont': 'Montpelier',
'Virginia': 'Richmond',
'Washington': 'Olympia',
'West Virginia': 'Charleston',
'Wisconsin': 'Madison',
'Wyoming': 'Cheyenne'}
statesList = list(stateDict)
correct = 0
incorrect = 0
again = 'y'
while (again == 'y'):
num = random.randint(MIN,MAX)
state = statesList[num]
print('n' + state)
ans = input("nEnter the capital of this state: ")
if (ans == stateDict[state]):
correct += 1
print("Correct")
again = input("Type y to play again, anything else to stop: ")
else:
incorrect += 1
print("Incorrect")
again = input("Type y to play again, anything else to stop: ")
print("nYou have",correct,"correct answers")
print("nYou have",incorrect,"incorrect answers")
main()
1 ответ
Вы на правильном пути в нескольких отношениях — например, помещая все поведение / действия в функции. Тем не менее, константы хороши на верхнем уровне, и одно из преимуществ их размещения — это возможность читателю сосредоточиться на алгоритме без визуальной тяжести большой структуры данных.
Не заставляйте пользователя беспокоиться о заглавных буквах: данные в нижнем регистре, а затем использовать встроенные строковые методы Python для написания географических названий с заглавной буквы для представления пользователю.
Мнения по этому поводу расходятся, но я рекомендую использовать естественный язык в качестве основного (а не единственного) руководства при выборе переменных: например, в большинстве контекстов
capitals
это лучшее имя, чем stateDict
; states
лучше чем
statesList
. Иногда суффикс типа данных может устранять неоднозначность имен, но не делает это вашим первым импульсом.
Случайная библиотека включает в себя choice()
функция, поэтому вам не нужно MIN
, MAX
.
Я рекомендую пользователям в интерактивных программах менее болтливые сообщения. Как только пользователь поймет основы (компьютер печатает состояние, пользователь вводит заглавную букву), ему не нужны подробные инструкции. Безжалостное вырезание текста — достоинство в таких ситуациях.
Гнездо main()
звоните по условию, показанному ниже. Этот механизм сделает ваши скрипты доступными для импорта, упрощения отладки и автоматического тестирования, если вам это когда-нибудь понадобится.
Когда вы обнаружите, что создаете несколько тесно связанных переменных (correct
а также incorrect
), подумайте, можете ли вы объединить их в структуру данных. Иногда такой подход предполагает дальнейший рефакторинг для упрощения кода (например, путем уменьшения ветвления if-else). На иллюстрации ниже я начал с того, что сосредоточился на объединении правильных / неправильных подсчетов, но это вдохновило на другие упрощения в представлении общих результатов.
import random
# Your dict, but lowercase.
capitals = {
'alabama': 'montgomery',
'alaska': 'juneau',
...
}
def main():
# Setup.
states = tuple(capitals)
tally = {True: 0, False: 0}
results = {True: 'Correct', False: 'Incorrect'}
result=""
# Quiz loop.
print('State capitals quiz:')
while True:
# Get user reply.
state = random.choice(states)
ans = input(f'{result}{state.title()}? ').lower()
if ans in ('', 'q', 'quit'):
break
# Tally result.
res = ans == capitals[state]
tally[res] += 1
result = results[res] + '. '
# Print overall results.
fmt="Results:n- {}: {}n- {}: {}"
args = (results[True], tally[True], results[False], tally[False])
print(fmt.format(*args))
if __name__ == '__main__':
main()
Наконец, люди, которые проходят викторины, обычно хотят видеть правильные ответы. Вы можете сразу же распечатать правильный результат в ответ на неправильный ответ. Или вы можете отслеживать все состояния с плохими ответами и печатать правильные ответы в конце.
Множество очень хороших моментов — спасибо!
— am2021
Хороший ответ, +1. Два небольших предложения: 1. Переместите конечные пробелы из значений в
results
к аргументу f-строки дляinput
при назначенииans
. 2. Назначитьans
кinput(...).lower()
чтобы команды выхода с заглавной буквы работали.— рискованный пингвин
В основном хорошо, хотя твой
fmt
не следует жестко кодировать правильные и неправильные строки — они у вас есть в результатах.— Райндериен