Примечание: это не решение проблемы «Сетка изображения персонажа» от Automate the Boring Stuff. Вместо этого это расширение этой проблемы просто ради понимания вложенных циклов, списков внутри списков и перебора значений для печати изображения на экране.
Спасибо всем, кто нашел время, чтобы просмотреть это. Следует ли мне больше комментировать код, чтобы его было легче читать? Есть ли способы сократить эту программу, чтобы она работала быстрее? Я все еще новичок в программировании.
# This is an expanded version of the Character Picture Grid
# problem from Al Sweigart's book, Automate the Boring Stuff With Python.
# This function takes in user input to determine what direction to print
# the arrow.
rightArrow = [['.', '.', '.', '.', '.', '.'],
['.', 'O', 'O', '.', '.', '.'],
['O', 'O', 'O', 'O', '.', '.'],
['O', 'O', 'O', 'O', 'O', '.'],
['.', 'O', 'O', 'O', 'O', 'O'],
['O', 'O', 'O', 'O', 'O', '.'],
['O', 'O', 'O', 'O', '.', '.'],
['.', 'O', 'O', '.', '.', '.'],
['.', '.', '.', '.', '.', '.']]
def printArrow(list):
rowLength = len(list[0]) # length of x plane coordinates
columnLength = len(list) # length of y plane coordinates
print('Welcome to Arrow Pointer v1.0!')
while True:
#main program loop
print('nnType in one of the following:nnup, down, left, right, or end to exit the program.')
#user determines direction of arrow to be printed
userInput = input()
if userInput.lower() == 'right':
for i in range(columnLength):
for j in range(rowLength):
#first loop iterates through main list
#nested loop iterates through inner list elements
print(list[i][j] + ' ', end='')
print('n')
if userInput.lower() == 'left':
for i in range(columnLength):
for j in range(rowLength - 1, -1, -1):
#iterate backwards to print arrow in opposite direction
print(list[i][j] + ' ', end='')
print('n')
if userInput.lower() == 'down':
for i in range(rowLength):
for j in range(columnLength):
print(list[j][i] + ' ', end='')
print('n')
if userInput.lower() == 'up':
for i in range(rowLength-1, -1, -1):
for j in range(columnLength-1, -1, -1):
print(list[j][i] + ' ', end='')
print('n')
if userInput.lower() == 'end':
quit()
printArrow(rightArrow)
1 ответ
- Начнем с основ. Всегда используйте if
__name__ == "__main__": printArrow(rightArrow)
вместо прямого вызова вашей функции (printArrow(rightArrow)
), чтобы избежать его запуска при импорте функции в будущем из другого модуля. - Функция называется
printArrow
должен печатать стрелку, а не запрашивать у пользователя ввод, печатать стрелку и управлять ходом программы. Разделите его на def print_arrow (список, направление), main () и т. Д. - Вместо использования
quit()
который контролирует глобальный поток выполнения, вы можете использовать простойreturn
когда внутри функции. Чище и следует за SRP. - Именование! В python мы обычно не используем camelCase для функций; используйте вместо этого: print_arrow. То же самое для таких переменных, как
rowLength
->row_length
. - Передайте свой код через черный цвет или что-то подобное, чтобы он был красиво отформатирован (black.vercel.app/), иначе обнаружатся небольшие человеческие «ошибки» 🙂
- Константы в Python по соглашению используют весь верхний регистр и их не нужно передавать в функции (единственное исключение, когда глобальные переменные обычно приемлемы). Так что используйте
rightArrow
->RIGHT_ARROW
а такжеdef printArrow(list):
->def printArrow():
. - Используйте комментарии для важных вещей (те, которые я не могу тривиально вывести из самого кода). Что это за произвольное количество пробелов?
' '
? Поместите это в константу и прокомментируйте, почему так много, если это имеет значение. Например,SEPARATOR = ' '
. - Есть повторение кода, не могли бы вы поместить это в функцию
def _print_arrow_auxiliary(x_start: int, x_end: int, x_step: int, y_start: int, y_end: int, y_step: int) -> None:
?
for i in range(rowLength-1, -1, -1):
for j in range(columnLength-1, -1, -1):
print(list[j][i] + ' ', end='')
print('n')
- Это дело вкуса, но подсказка типов ваших функций дает вам много преимуществ (понятный код, лучшие особенности и предложения IDE и т. Д.) …
def printArrow(list):
->def printArrow(list: List[List[str]]) -> None:
.
Спасибо за ответ. Есть несколько вещей, по которым я нуждаюсь в разъяснении. Я не понимаю следующую строку: имя == «главный«: printArrow (rightArrow). Также, ваше второе замечание о разделении функции на print_arrow (список, направление), main () и т. д. Какова цель main () в этом контексте?
— Рамза
Ответ на первый вопрос здесь, это базовый язык Python, поэтому я предлагаю вам потратить немного времени и убедиться, что вы его поняли! Что касается функций разделения, в целом мы стараемся следовать СЕРП, каждая функция должна делать только одно. Таким образом, print_arrow должен делать только это, печатать стрелку, не иметь основного цикла программы или запрашивать у пользователя ввод. Существует соглашение о наличии функции с именем main (), которая имеет основной цикл программы.
— микельвир
Спасибо! Последний вопрос: как вы определили, что в моем коде есть константы? Я не знаю разницы между константой и переменной в Python. Я знаю, что в JavaScript это объявление либо var, const, либо let, но, насколько мне известно, каждая переменная в Python является переменной.
— Рамза
Ну да. В Python нет констант. То есть нет способа заставить переменную быть на самом деле постоянной и никогда не изменяться. Однако мы, как «ответственные программисты», используем некоторые переменные, которые мы собираемся использовать в качестве констант. Если мы хотим показать, что переменная предназначена для использования в качестве константы, в Python мы используем все прописные буквы, такие как SOME_CONSTANT. В вашем случае, например, rightArrow используется, но никогда не изменяется, поэтому давайте сделаем это явным, используя соглашение об именах для констант!
— микельвир