Наверное, у многих новичков бывало такое, когда ты смотришь решение какой-то задачи в Интернете или на уроке, читаешь чужой код и кажется что всё максимально просто и понятно. Но вот приступаю к решению такой же задачи самостоятельно, впадаешь в ступор. Что делать, с чего начать и т. д. Хотя казалась бы было всё было понятно. Знакомое чувство? С ним сталкивается каждый, кто только начинает изучать программирование. Поэтому сегодня я расскажу как решать зачади по программированию на языке Python, да и любом другом языке. Меня зовут Макс. Я один из авторов YouTube-канала PyLounge. Поехали!
Во-первых, ты должен чётко понимать, что от тебя требуется.
Как нельзя лучше сделать это тебе поможет декомпозиция. Декомпозиция — это когда ты разбиваешь одну большую сложную задачу на несколько мелких простых задача. При этом в момент дробления задачи не пытайся думать о программной реализации и программировании вообще. Старайся думать как ТЫ бы решал эту задачу, ты сам, будучи человеком. Опиши свои человеческие действия на каждом этапе. Перед этим вдумчиво прочитай текст задачи. Можно даже читать вслух. Часто проговаривание вслух помогает восприятию. И начинай декомпозировать с человеческой точки зрения.
Допустим перед нами стоит задача:
Написать функцию, которая получает из текстового файла словарь с настройками графики для игры.
Файл имеет следующий вид:
Начинаем смотреть на задачу глазами обычного человека. Вот у меня на Рабочем столе лежит текстовый файл. Чтобы мне прочитать содержимое файла его надо открыть. Соответственно это и есть первый пункт наше алгоритма — Открыть файл.
Далее я глазами вижу первую строчку файла. Здесь через пробел записаны два слова. Так как в файле записаны настройки графики то, очевидно, в каждой строчке хранится пара «название опции — её значение». Например, Разрешение 1920×1080. Соответственно я, будучи человеком, мысленно читаю первую строчку. Дальше мне нужно отделить «ключ настройки» от её значения. Как я будучи человеком понимаю, что в этой строчке два разных слова? Как я понимаю, что здесь не одно слово? Слова разделены между собой пробелами. Значит слово до пробела ключ, после значение. Это и есть следующий этап нашего алгоритма — читаем строку и делим её, за разделитель принимаем символ пробела. Затем первую половину строки заносим в ключ, вторую в значение.
Далее я будучи человеком, опускаю взгляд на следующую строку и повторяю описанное выше действие. Потом следующую и следующую. До тех пор, пока в файле не закончатся строки. Это и есть следующий шаг — по очереди обрабатывать каждую строчку из файла.
Теперь у меня в голове (или в переменной типа dict (словарь)) имеется вся нужная информация. По аналогии с функцией мы возвращаем словарь с данными. Потом я закрываю файл. Вот у нас и есть по сути готовый алгоритм:
1. Открыть файл.
2. Читаем строку из файла.
3. Делим её на две части через символ пробела.
4. Записываем первую часть строки в «ключ», а второю в «значение ключа» (например, ключ vsync — значение ключа off).
5. Аналогичным образом по очереди обрабатываем каждую следующую строку. Пока строчки в файл не кончатся.
6. Закрываем файл.
7. Сообщаем результат.
Можно для себя набросать псевдокод. То есть описание каждого шага алгоритма не на конкретно языке программирования, а абстрактно, на русском. Также неплохим вариантом может являться нарисовать блок-схему.
Псевдокод — это изложенные простым языком шаги алгоритма. Иными словами, это пошаговый план решения задачи. Если вы и так чётко понимаете процесс или задача относительно простая, то псевдокод и схему можно пропустить.
Теперь когда у нас имеется алгоритм, надо задать себе два вопроса:
1. Что мы имеем на вход (входящие данные).
2. Что мы имеем на выходе.
Снова смотри с позиции обычного человека. Чтобы я, будучи человеком, смог открыть какой-то файл и прочитать его, я должен знать где он лежит. Значит на вход мы и наша функция получает путь до файла.
Также в условии уже сказано, что мы должны сформировать словарь настроек. Значит словарь с ключами и значениями (куда сохраняются данные из файла) мы и должны вернуть из функции (вывести результат).
Теперь пытаемся переложить это на программный код. Также построчно всё проговаривая:
import os
def read_settings_file(file_name):
settings = dict()
file = open(file_name, 'r')
for row in file.readlines():
key, value = row.split(' ')
settings[key] = value
file.close()
return settings
print(read_settings_file('D://game_settings.txt')
Очень важно давать осмысленные и понятные названия переменным и функция. Это помогает делать код более читаемым и ты сам не запутаешься, если откроешь его спустя неделю. Рекомендую посмотреть наше видео «4 Совета Которые Помогут Сделать Твой Код Лучше».
Также стоит подумать, какие ошибки у нас могут возникнуть. Опять таки, задаём себе вопросы, например:
1. Что делать если файл не будет существовать?
Надо сделать проверку, добавить обработку такой ситуации.
2. Что случится если структура файла будет другой?
3. Кодировка файла будет
нестандартной?
Нужно придумать как можно больше таких вопросов. И ответить на
каждый из них, реализовав программное решение с помощью исключений, сообщений
об ошибках и т.д.
Теперь когда у нас есть рабочее решение на руках, надо подумать, как его можно улучшить. То есть надо провести рефакторинг кода и сделать решение более эффективным.
Рефакторинг — это процесс улучшения кода, когда мы переписываем какие-то участки кода, которые можно сделать лучше.
При рефакторинге можно задавать себе следующие вопросы:
1. Можно ли
получить этот результат как-то иначе? Какие еще подходы есть?
2. Понятно ли
это решение с первого взгляда?
3. Можно ли
использовать результат или метод для какой-то другой задачи?
4. Можно ли
улучшить производительность решения?
5. Как эту
задачу решают другие люди?
Никогда не пренебрегай внутренним диалогом с собой. Составляй план, блок-схему и т. д. Многие люди не делают этого, им кажется, что это бесполезная трата времени. Но на самом деле именно в этом и кроется ключевой момент в решении любой задачи.
В нашем случае мы могли бы работать с файлом через менеджер контекста, чтобы явно не вызывать функцию close () и метод readlines (). И применить к значением настроек функцию strip (), что бы не оставлять в строке символы переноса, табуляции и т. д. В случае с Python можно ещё и аннотации типов добавить:
from typing import Optional, Dict
import os
def read_settings_file(file_name:str) -> Optional[str]:
if not os.path.exists(file_name):
return None
settings:Dict[str, str] = dict()
with open(file_name, 'r') as file:
for row in file:
key, value = row.split(' ')
settings[key] = value.strip()
return settings
print(read_settings_file('D://game_settings.txt')
К слову, очень важно смотреть, как другие решали подобную задачу. Так читая чужой код вы набираетесь опыта и вырабатываете надсмотренность. В чужом коде можно подсмотреть интересные решения, которые затем взять себе на вооружение.
Я в своё время очень часто смотрел чужие решения, сравнивал их со своим и это сильно мне помогло. Главное не смотреть ответ сразу) А именно сравнивать своё решение с чужим, если сам ну никак не можешь сделать.
Я привел пример простой задачи. Но более сложная задача будет отличаться лишь количеством этапов и инструментами, которые будет необходимо применить.
Запомните, умение решать задачи — это навык. Чем больше практики, тем лучше вам это будет удаваться. Если вы хотите много раз подтягиваться, то надо подтягиваться. Если вы хотите научиться быстро бегать, то надо бегать. Если вы хотите научиться решать задачи по программированию, то надо решать задачи. Истина всегда на поверхности.
Также есть чуть более подробная видеоверсия этой статьи на YouTube:
Лучшие комментарии
Вы кажется порталом ошиблись, это не habr.
Если хотели прорекламиться на СГ в блогах, то написали бы статью с обзором игр, где обучают основам программированию ( ну или решают похожие задачи ), а в конце уже могли бы дать ссылку на свой Ютуб канал с фразой в духе " вот мы и разобрали самые популярные игровые подходы к программированию. Если они вас заинтересовали и вы хотите глубже понять программирование, то добро пожаловать на мой Ютуб канал ".
Убери блог из раздела кино и сериалы