Техническая часть самая простая

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

Худшее, что вы можете сделать, — это начать избавляться от проблемы, как только она появится. Именно здесь большинство программистов-новичков застревают и сдаются. Вспомните школьные годы, когда вам приходилось делать письменные оценки. Обычно газета [или наблюдатель] сообщает вам, сколько времени у вас есть на планирование и сколько нужно отвести на написание. То же самое и с программированием.

Каждая проблема — это оболочка для ряда более мелких проблем, которые необходимо решить. Техническая часть всегда самая простая, если вы четко разработали четкий план решения проблемы.

«Если бы у меня был только час, чтобы срубить дерево, я бы потратил первые 45 минут, затачивая свой топор».

- Абрахам Линкольн.

Чтобы продемонстрировать это, мы собираемся вместе решить проблему кодирования. Проблемы с кодированием — хороший способ развить вашу способность продумывать программы. Чем больше вы будете знакомиться с различными типами проблем, тем значительно улучшится ваша способность решать проблемы. Таким образом, важно, чтобы вы постоянно ставили себя в ситуации для решения новых проблем — даже если это всего на 15–30 минут в день.

Постановка задачи: Алфавит Ранголи

Примечание. Эта задача взята из HackerRank.

Вам задано целое число N. Ваша задача — напечатать алфавит ранголи размера N. (Ранголи — это форма индийского народного искусства, основанная на создании узоров.)

Различные размеры алфавита ранголи показаны ниже:

#size 3

----c----
--c-b-c--
c-b-a-b-c
--c-b-c--
----c----

#size 5

--------e--------
------e-d-e------
----e-d-c-d-e----
--e-d-c-b-c-d-e--
e-d-c-b-a-b-c-d-e
--e-d-c-b-c-d-e--
----e-d-c-d-e----
------e-d-e------
--------e--------

В центре ранголи есть первая буква алфавита а, а на границе есть буква алфавита (в алфавитном порядке).

Входные данные для функции представляют собой одну строку, содержащую size — размер ранголи. Ваша функция должна возвращать строку, состоящую из каждой строки ранголи, разделенных символом новой строки (\n).

#Шаг 1 — Найдите время, чтобы понять проблему

Первым шагом к решению любой проблемы является понимание решаемой проблемы. Это означает, что вы можете полностью сформулировать проблему своими словами.

Не расстраивайтесь, если у вас не получается, это часть процесса понимания. Когда вы сталкиваетесь с чем-то, что не можете четко сформулировать, это означает, что в вашем понимании есть пробел. Если вы хотите иметь возможность решить проблему, вам нужно заполнить пробел.

Это означает, что вы должны задавать вопросы.

Когда вы работаете над проблемой в одиночку, вы должны задать себе больше вопросов, чтобы уточнить, что именно вы не понимаете — вы также можете использовать Google, чтобы получить лучшее представление о том, что именно вы не понимаете в конкретном вопросе. часть. Если вы работаете с командой или консультируете кого-то, то это ваш шанс задать им вопросы, чтобы заполнить пробелы в вашем понимании.

Суть в том, что вам нужно не торопиться, чтобы полностью понять проблему, с которой вы столкнулись. Это принесет вам пользу в долгосрочной перспективе и значительно упростит процесс решения проблем.

Приложение:

Учитывая нашу проблему с алфавитом Ранголи, первое, что нам нужно сделать, это понять, какую проблему мы пытаемся решить. Вот как я выразился своими словами.

Учитывая входные данные для определения размера, мы должны создать функцию, которая возвращает алфавит ранголи, который представляет собой художественную форму индийского народа, основанную на создании узоров.

Обратите внимание, что я четко описал, что мы ожидаем от функции и что ожидается на выходе. Это потому, что на высоком уровне мне нравится думать о решении проблем, как о получении определенного ввода и преобразовании его в определенный результат. На данный момент функция сопоставления — это черный ящик, но наш следующий шаг — разобрать, что происходит в черном ящике.

Еще одна вещь, которую мне нравится делать на этом этапе, — это рисовать свои собственные примеры с некоторыми пользовательскими входными данными, чтобы лучше понять, что произойдет. Например, мы знаем, что это алфавит ранголи, а в алфавите всего 26 букв, но что произойдет, если будет передан размер больше 26? К счастью, на этот вопрос для нас был дан ответ в брифе, но если бы это было не так, нам пришлось бы выяснять, что может произойти, задавая вопросы.

Примечание: помните, что Python при нарезке не учитывает конечное число, поэтому при передаче 27 будут приниматься первые 26 букв.

Вот пример моего рисунка:

Я бы нарисовал несколько из них, чтобы лучше укрепить свое понимание.

#Шаг 2 — Разбейте проблему на части

Любая проблема состоит из множества мелких проблем. Разбиение большой проблемы на более мелкие проблемы, которые необходимо решить, делает решение более крупной задачи менее пугающим.

Все, что нужно сделать, когда решены более мелкие проблемы, — это соединить их вместе. Это приведет к решению большей проблемы, если вы тщательно продумаете входные и выходные данные на каждом этапе.

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

Приложение:

Сначала я решил задачу Ранголи на бумаге, проработав факты того, что я разработал в приведенном выше примере. Когда у меня появилась ясность в отношении фактов, я разбил их на этапы следующим образом:

# Description of facts for size=4
- we need to get the first n letters of the alphabet so we need access to the full alphabet
- the center value for the first line is always the nth value and it's padded with "-"; what's the length of the padding? 
- the middle line always has the first letter of the alphabet as the middle value and the boundary is always the nth letter
   --> from L-R: the middle line starts at an and works its way back to a then from a it goes back to N.
   --> all the letters have a "-" instead of a space between them
   --> this means the length of all the lines is the length of the middle line; We must know the length of the middle line before we can draw the other lines. 
- split the rangoli into halves that is seperated by the middle line. 
- the top line of the upper starts with n in the middle. the next line has n - 1 in the middle and to the left of it is n and to the right of it is n. the next line has n-2 in the middle with the sequence going n-1 then n to the left, and n-1 then n to the right. The next line has n-3 in the middle with the sequence going n-2, n-1, then n to the left and n-2, n-1, then n to the right. Let's sketch this. 

- we can seperate the upper half into halves again by drawing a line down the center. This would mean we have a left and a right side

- the left have is going from n to n-i in reverse order and the right side is going from n-i to n
- the lower half is literaly the same thing as the upper half but its flipped upside down. 

Теперь, когда у меня есть факты, я могу спроектировать шаги.

The steps
1. store the letters in the alphabet
2. get the first n letters of the alphabet
3. draw the middle line
4. get the length of the middle line
5. draw the left side of the upper half and join it to the right side - join the values together by "-" and center n-i and make sure the line is length of middle with the other values made up with "-". 
6. flip the upper half upside down to draw the bottom half
7. put it all together

Я разбил проблему на 7 более мелких задач, не используя никаких технических терминов. Следующим шагом будет выяснить, как вы будете технически реализовывать каждый шаг.

Это означает, что можно углубиться в решение этой проблемы, потому что я не вдавался в подробности. Например, я только что написал «нарисовать среднюю линию». Как мне нарисовать среднюю линию? Я не углублялся в это решение, так как уже решал подобные задачи, поэтому у меня есть четкое представление о том, как нарисовать среднюю линию (т. е. чтобы нарисовать среднюю линию, нужно соединить обратную сторону первых n буквы до первых n букв (не считая а) символом «-».

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

#Шаг 3 — Выполнение

Теперь вы решили задачу на бумаге. Все, что вам нужно сделать, это реализовать то же самое решение, которое вы написали на бумаге, но перевести его в код.

Здесь в игру вступает ваше знание языка программирования. В зависимости от вашей среды вы можете найти в Google способы сделать определенные вещи, например, как перевернуть строку или как взять первые n букв строки.

Поскольку у вас уже есть структура решения проблемы, вам не нужно прорабатывать проблему с шагов 1–7. Начните с самых простых шагов, чтобы быстро одержать победу.

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

Приложение:

Вот как я решил небольшие части проблемы:

def print_rangoli(n): 
   # step 1 - store letters of the alphabet
   alphabet = "abcdefghijklmnopqrstuvwxyz"
   
   # step 2 - get the first n letters of the alphabet
   first_n = alphabet[:n]
 
   # step 3 - draw the middle line
   middle = "-".join(first_n[::-1] + first_n[1:])
   # step 4 - get the length of the middle line
   length_of_middle = len(middle)

Чтобы сделать step 5, я разбил ее на более мелкие задачи. Я создал программу и использовал свое имя, чтобы получить левую и правую стороны.

name = "kurtis"
n = len(name)
for i in range(1, n): 
    # left side
    print(name[n:n-i:-1])
print("-"* 10)
for i in range(1, n):
    # right side 
    print(name[n-i:n])
"""
s
si
sit
sitr
----------
s
is
tis
rtis
urtis
"""

Теперь все, что мне нужно сделать, это соединить значения вместе знаком «-» и центрировать среднее значение (n-i). Убедитесь, что линия имеет ту же длину, что и средняя линия, а остальные значения заполнены знаком «-».

name = "kurtis"
n = len(name)
middle = "-".join(name[::-1] + name[1:])
for i in range(1, n): 
    # left side
    print("-".join((name[n:n-i:-1] + name[n-i:n]).center(len(middle), "-")))
"""
----------s----------
--------s-i-s--------
------s-i-t-i-s------
----s-i-t-r-t-i-s----
--s-i-t-r-u-r-t-i-s--
"""

Следующим шагом будет перевод этого решения в код нашей задачи:

def print_rangoli(n): 
   # step 1 - store letters of the alphabet
   alphabet = "abcdefghijklmnopqrstuvwxyz"
   
   # step 2 - get the first n letters of the alphabet
   first_n = alphabet[:n]
 
   # step 3 - draw the middle line
   middle = "-".join(first_n[::-1] + first_n[1:])
   
   # step 4 - get the length of the middle line
   length_of_middle = len(middle)
   
   # step 5 - draw upper half
   for i in range(1, n):    
       print("-".join((first_n[n:n-i:-1] + first_n[n-i:n]).center(length_of_middle, "-")))
   # step 6 - rotate the upper half
   for i in range(n, 0, -1): # <-- rotation happens here
       print("-".join((first_n[n:n-i:-1] + first_n[n-i:n]).center(length_of_middle, "-")))

Шаг 7 — собрать все вместе, что означает передачу ему значения. Давайте передадим нашей функции размер 4, чтобы увидеть, соответствует ли он шаблону, который мы нарисовали выше.

print_rangoli(n=4)
"""
------d------
----d-c-d----
--d-c-b-c-d--
d-c-b-a-b-c-d
--d-c-b-c-d--
----d-c-d----
------d------
"""

задача решена.

#Шаг 4 — Отражение

Есть несколько способов решить проблему; Ничто не говорит о том, что мое нынешнее решение проблемы — лучший способ ее решить. Это означает, что сейчас самое время подумать о том, как мы решали проблему, и подумать о том, как вы могли бы сделать свое решение более эффективным.

Одна вещь, которую я сразу понял, это то, что мне не нужно было выписывать весь алфавит вручную. Я мог бы просто импортировать модуль string и вызвать ascii_lowercase.

import string 
alphabet = string.ascii_lowercase
print(alphabet)
"""
abcdefghijklmnopqrstuvwxyz
"

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

Заворачивать

Программирование требует, чтобы вы думали. Частью мыслительного процесса является разбиение проблем на более мелкие модули, чтобы упростить их решение. Четыре шага к решению проблемы:

  1. Понять проблему
  2. Разбейте проблему
  3. Выполнять
  4. Отражать

Спасибо, что прочитали.

Свяжитесь со мной:
LinkedIn
Twitter

Если вам нравится читать истории, подобные этой, и вы хотите поддержать меня, подумайте о том, чтобы стать участником Medium. Взяв 5 долларов в месяц, вы открываете неограниченный доступ к историям на Medium. Если вы воспользуетесь моей ссылкой для регистрации, я получу небольшую комиссию.

Уже вступил? Подпишитесь, чтобы получать уведомления, когда я опубликую.