– Программист – wer ist das? (нем. - кто это)
– Человек, который пишет программы.
– Верно. Но что, если я скажу, что программист – это человек, который решает проблемы, задачи, с помощью программ?
– То есть если я пишу какую-то программу, то я еще не программист?
– Exactly.
Цель этого курса – не просто научить вас писать программы на языке Python, но научиться именно мыслить, как программист. Ведь программист в первую очередь решает задачи, умеет подходить где-то даже творчески к проблемам и использовать инструменты для решения этих проблем.
Роль программиста:
Как инженер — программист умеет проектировать и собирать отдельные компоненты в целые системы.
Как математик — программист умеет мыслить абстракциями и использовать формальные языки для выражения идей.
Как учёный — программист умеет наблюдать за поведением систем и строить теории относительно их работы.
И по сути главный навык в становлении программистом — это обрести навык нахождения решения задачи. Поэтому прежде чем начать непосредственно писать программы на Python, мы рассмотрим в целом, что такое программа, как они строятся и то, как машина в итоге понимает человека.
Цель же этой главы - коротко ввести вас в "курс дела" – что такое программирование, чем язык машин (ЭВМ) отличается от нашего языка, а также краткая история эволюции ЯП. Если вы и так это знаете - смело пропускайте эту главу и переходите дальше. :)
Если говорить «университетским» языком, программа — это набор инструкций, выполняемых компьютером. Компьютеры не обладают мышлением, они строго следуют тому, что написано в инструкциях, и не могут отклоняться от заданного порядка или выполнять действия самостоятельно. Хотя, конечно, имитацию самостоятельного мышления можно создать с помощью программирования.
Программы могут выполнять множество задач: проводить математические вычисления, обрабатывать текст, рисовать изображения на экране и даже управлять сложными устройствами, например ракетами.
В своей основе «программировать» означает писать эти инструкции на языке программирования, который понятен человеку, но может быть выполнен электронным устройством, будь то компьютер, телефон или что-то более экзотическое.
На базовом уровне каждая программа состоит из трёх основных частей, которые могут немного отличаться в реализации в зависимости от используемого языка программирования:
Input (ввод данных): Программа должна получить входные данные. Это могут быть числа, вводимые с клавиатуры, данные из файла или информация, поступающая из других источников.
Пример: пользователь вводит свое имя с клавиатуры
Execution (выполнение): Программа обрабатывает введённые данные по заранее заданной логике. Например, это может быть простое сложение чисел или сложный алгоритм для решения задачи.
Пример: программа определяет длину имени, введённого пользователем.
Output (вывод данных): Программа обрабатывает введённые данные по заранее заданной логике. Например, это может быть простое сложение чисел или сложный алгоритм для решения задачи.
Пример: программа выводит сообщение с длиной имени.
Вот и всё, что вам нужно знать о том, что такое программа. Любая программа — от простой игры до сложной системы управления ракетой — в конечном счёте сводится к этим трём шагам.
Но главный навык программиста — это умение разбить сложную задачу на более простые части, которые можно выразить в инструкциях на языке программирования. Как только вы овладеете этим умением, вы сможете превратить любую идею в работающую программу.
Попробуйте провести мысленный эксперимент. Возьмите любую программу, которой вы часто пользуетесь, и представьте, в какой момент происходит ввод данных, что может выполняться и каков результат. Подробно опишите, что в этой программе ввод, как программа (на ваш взгляд) обрабатывает данные и что является результатом. Если программа слишком большая – возьмите только её часть.
В будущем, когда вы будете писать какие-то программы, руководствуйтесь этим алгоритмом. Это поможет вам лучше понимать, с чего начать решать какую-то задачу или писать приложение.
Писать программы не сложно, стоит лишь научиться думать так, словно ты машина, что куда проще, чем вы думаете.
Для этого все задачи нужно разбивать на небольшие подзадачи, которым легко следовать и которые невозможно понять неправильно.
Представим себе кафе с официантом-роботом. Нам понадобилось обучить его бесхитростному делу официанта. Всего-то нужно, доставлять блюда с кухни посетителям, которые ожидают в обеденном зале. Сперва эту проблему нужно разбить на простые, понятные роботу подзадачи.
В целом неплохо. Но вот, что делает робот:
Берет еду с тарелки
Проходит в зал через стену
Бросает еду на пол рядом со столиком посетителя
Кажется, что-то мы не продумали. Попробуем еще раз.
Уже гораздо лучше.
Однако, в зале робот натыкается сначала на другой стол, потом на посетителя. В итоге, робот роняет тарелку, и заказ пропадает.
Попробуем еще.
Получилось!
Робот благополучно доставил еду посетителю.
Однако, продумали ли мы, что он делает после этого? Вряд-ли. Робот застыл на месте, сильно напрягая посетителей, да и заказы копятся.
Плюс, робот не может взять новые заказы, для этого надо продумывать логику отдельно.
Надеюсь, что на этом примере вам стало гораздо понятнее, как стоятся программы. Вообще, такие последовательности называются алгоритмами. Как правило, алгоритм – это последовательность действий, приводящая к желаемому результату.
При этом алгоритмы могут быть также и математические(например, для сортировок или нахождения самого короткого пути), которые не просто решают задачу, но и оптимизируют работу программы и кода в целом. Такие алгоритмы помогают программам работать быстрее и эффективнее.
Попробуйте дальше продумать алгоритм для робота. Постарайтесь предусмотреть как можно больше событий.
Для взаимодействия с компьютером люди используют языки программирования (далее будет сокращено до ЯП).
Их развитие прошло через несколько поколений, каждое из которых повышало уровень абстракции, делая процесс программирования более удобным и понятным.
Понимание поколений языков программирования позволяет лучше осознать, как развивались технологии и почему современные программисты предпочитают высокоуровневые языки, такие как Python.
Чтобы понять, как машина "понимает" человека, нужно начать с самого базового уровня — двоичной системы, на которой основаны все вычисления. Компьютеры «общаются» на уровне электрических сигналов, которые для удобства представляются в виде комбинаций 0 и 1.
Этот принцип легко понять, представив себе обычный выключатель света.
Включенный свет (1)
Если лампочка горит, это состояние можно интерпретировать как 1. В электронике это соответствует наличию электрического напряжения.
Выключенный свет (0)
Если лампочка не горит, состояние соответствует 0, что означает отсутствие напряжения.
Так и в компьютере: сигнал есть — это 1, сигнала нет — это 0. Эти два состояния формируют двоичную систему, которая лежит в основе машинных языков. Но программировать напрямую на уровне двоичного кода невероятно сложно, ведь для человека это неестественный способ общения.
Чтобы упростить взаимодействие с компьютером, были изобретены перфокарты. Они представляли собой картонные карточки с рядами и столбцами, в которых определённые отверстия (или их отсутствие) кодировали двоичные данные (0 и 1).
Каждая перфокарта имела стандартный формат: обычно 80 столбцов и 12 рядов. Программисты использовали специальные устройства для пробивания отверстий, или делали это вручную, создавая «программы» в виде последовательностей данных.
Перфокарты применялись в ранних компьютерах, таких как IBM 1401 и ENIAC. Хотя это был прогресс по сравнению с прямым использованием двоичного кода, процесс оставался трудоёмким. С приходом магнитных лент и дисков перфокарты быстро утратили популярность.
– Чтобы не тратить место на объяснение бинарного кода, как ЭВМ распознают сигналы и прочее, рекомендую глянуть небольшое видео на эту тему.
Мы уже обсудили, что программировать на машинном языке крайне сложно. Человеку пришлось изобретать более удобные инструменты, которые позволяли бы писать инструкции на понятном словесно-буквенном языке.
Так появились языки ассемблера — программные инструменты, которые получили своё название от термина «сборка» (assembly), отражающего их основную задачу.
Программа на Assembler для систем x86, которая выводит "Hello, world!"
Язык ассемблера — это следующий шаг в развитии языков программирования. Он позволяет программисту использовать мнемоники (короткие текстовые команды), чтобы задавать инструкции. Эти команды затем преобразуются в машинный код, понятный компьютеру. Этот процесс называется ассемблированием или трансляцией.
Например, вместо того чтобы записывать двоичный код для команды, программист может написать инструкцию вида:
MOV AX, BX
Эта команда на языке ассемблера означает «переместить содержимое регистра BX в регистр AX» — не нужно помнить сложные комбинации из 0 и 1.
Главный недостаток языка ассемблера — жёсткая привязка к аппаратной архитектуре. Программу, написанную на ассемблере для одного типа компьютера, нельзя просто так запустить на другой машине. Например, код, разработанный для процессоров Intel, не будет работать на ARM-устройствах без адаптации.
Для того чтобы программа на ассемблере могла быть запущена на другом устройстве, необходимо, чтобы эти устройства имели одинаковую архитектуру чипа. Иначе трансляция будет невозможна.
Как мы уже обсуждали, главным недостатком ассемблера является жёсткая привязка к архитектуре конкретного компьютера, а также сложность в использовании. Даже упрощение, которое он предлагает по сравнению с машинными кодами, остаётся далеко от уровня удобства, необходимого для работы программиста.
В ответ на эти ограничения учёные-математики разработали языки программирования высокого уровня. Эти языки сделали огромный шаг в сторону удобства для программиста, поскольку их синтаксис стал напоминать обычный человеческий язык.
Однако, чтобы программа на таком языке могла исполняться компьютером, требовались трансляторы — программы, написанные на ассемблере. Транслятор берет код, написанный на языке высокого уровня, и переводит его в машинный код, который способен исполнять компьютер.
Основное преимущество языков высокого уровня — это переносимость. Программу, написанную на языке высокого уровня, можно запустить на любом компьютере с подходящим транслятором для этого языка. При этом вам не нужно вручную адаптировать код под архитектуру новой машины.
К примеру, если вы написали программу на языке Fortran или C на одном компьютере, вы сможете запустить её на другом, где установлен соответствующий транслятор, без каких-либо изменений в коде. Именно эта универсальность стала ключевой характеристикой третьего поколения языков.
Появление языков высокого уровня стало революционным шагом, сделав программирование доступным для более широкого круга людей. Они упростили создание программ, сократили количество ошибок и открыли новые горизонты для развития технологий. Это был не просто шаг вперёд — это был настоящий скачок в истории программирования.
Главной особенностью языков четвёртого поколения является высокий уровень абстракции, который делает программирование ещё более удобным и близким к человеческому восприятию. Этот стиль программирования называют объектно-ориентированным программированием (ООП).
Объектно-ориентированное программирование предлагает новый подход к созданию программ. Вместо того чтобы разрабатывать программы как последовательности действий, программисты описывают системы через взаимодействие объектов. Объект — это сущность, которая объединяет в себе данные и методы работы с этими данными. Это позволяет более эффективно решать сложные задачи, структурируя код таким образом, чтобы он был легче читаем, поддерживаем и расширяем.
Меньше ошибок.
Высокая абстракция и использование объектов помогают программистам избегать типичных ошибок. Вместо работы с низкоуровневыми деталями программист концентрируется на описании архитектуры и взаимодействий в системе.
Фокус на задачах.
Благодаря ООП программисты могут сосредоточиться на решении задач, а не на том, как язык программирования взаимодействует с компьютером.
Интерактивное тестирование и отладка.
Языки 4GL предоставляют мощные инструменты для тестирования и исправления кода, что упрощает процесс разработки.
Простота обучения.
Синтаксис языков четвёртого поколения максимально приближен к человеческому языку. Это делает их доступными для новичков, даже тех, кто никогда раньше не сталкивался с программированием.
Языки четвёртого поколения сделали программирование более доступным, гибким и мощным. Они стали естественным продолжением эволюции языков, помогая разработчикам создавать сложные системы с минимальными усилиями. Но их потенциал раскроется для вас только после изучения ключевых парадигм программирования.
Ну и напоследок, вот некоторые языки, которые используются в разных отраслях
Откройте любой сайт по поиску вакансий, например hh.ru или career.habr.com (можете выбрать актуальный сайт для вашего региона). Поищите упомянутые ранее языки в вакансиях. Выпишите количество вакансий для разных языков. Поизучайте также требования к вакансиям, найдите наиболее повторяющиеся.
Также посмотрите рейтинг популярности ЯП. Как много в нем языков низкого уровня? А Assembler? Как вы думаете, с чем связана популярность разных ЯП?
Как мы уже обсуждали, для выполнения программы, написанной на языке высокого уровня, её нужно перевести в машинный код. Этот процесс выполняется специальной программой — транслятором.
Несмотря на сложность алгоритма трансляции, для нас важно знать, что существует два основных подхода к этому процессу: компиляция и интерпретация.
Компиляция — это процесс, при котором весь исходный код программы сразу переводится в машинный код. В результате создаётся исполняемый файл (например, с расширением .exe в Windows), который можно запускать без участия транслятора. К языкам, которые используют компиляцию, относятся, например, C, C#, Rust.
Преимущества:
Высокая скорость выполнения.
Исполняемый файл уже содержит готовый машинный код, и операционная система (ОС) запускает его напрямую.
Нет необходимости в трансляторе.
После компиляции исходный код не нужен для выполнения программы.
Недостатки:
Процесс компиляции может занимать время.
Ошибки обнаруживаются только после завершения компиляции, что может быть неудобно при разработке.
Интерпретация — это процесс, при котором программа выполняется последовательно, условно говоря, строка за строкой. Интерпретатор читает код, переводит его в машинный или промежуточный код и передаёт операционной системе для выполнения. К таким языкам относятся Python, JavaScript
Преимущества:
Мгновенное обнаружение ошибок.
Если в программе есть ошибка, вы узнаете об этом сразу же, без необходимости ожидать завершения всего процесса трансляции.
Отсутствие подготовительных действий.
Для выполнения программы достаточно интерпретатора, без необходимости компилировать код.
Недостатки:
Скорость выполнения программы может быть ниже, поскольку интерпретатор переводит код во время его выполнения.
Зависимость от интерпретатора.
Для запуска программы необходима установка соответствующей программы на компьютере.
На современных компьютерах разница в скорости выполнения между интерпретируемыми и компилируемыми языками может быть незаметной. Однако выбор подхода зависит от задач: компиляция предпочтительна для проектов, требующих высокой производительности, а интерпретация — для гибкости и быстрого тестирования.
Python относится к категории интерпретируемых языков программирования. Когда вы запускаете программу на Python, интерпретатор последовательно переводит код в машинный язык и передаёт операционной системе для выполнения. Если в коде содержится ошибка, интерпретатор сразу сообщит вам об этом, что делает Python особенно удобным для обучения и быстрого прототипирования.
Возьмите список ЯП которые вы составили в предыдущем задании. Выясните, какие из них являются интерпретируемыми, а какие - компилируемые. Есть ли те, которые и вовсе не используют компиляторы/интерпретаторы и сразу транслируются в машинный код? Например те языки, что принадлежат к группе ассемблеров.
Если вы впервые смотрите на программный код, то он может показаться чем-то загадочным. Символы, отступы, странные слова вроде if или for... Всё это создаёт впечатление особого языка, которым пользуются только «посвящённые». На самом деле, всё намного проще! Код выглядит так, как выглядит, благодаря нескольким особенностям, которые помогают программистам и компьютерам понимать друг друга.
Одна из первых вещей, которые бросаются в глаза, — это шрифт. Программный код почти всегда пишут шрифтом с фиксированной шириной (например, Courier New, Consolas или Fira Code). Это значит, что каждая буква и символ занимают одинаковое место по ширине. Почему это важно?
Такой шрифт делает код более аккуратным и удобным для чтения.
Отступы и структура кода легко воспринимаются глазами, что помогает быстро находить ошибки.
Посмотрите на пример. Думаю, вы сразу отличите, где шрифт для кода, а где обычный, не так ли?
year = 2024
word = "Hello"
print(year)
print(word)
year = 2024
word = "Hello"
print(year)
print(word)
Цвета в коде — это не просто украшение, а важный инструмент. Программа для написания кода выделяет его части, чтобы вам было легче понимать, что к чему:
Ключевые слова (if, for, while) подсвечиваются яркими цветами, чтобы вы могли сразу их заметить.
Переменные и имена функций часто имеют более нейтральные цвета.
Комментарии (текст, который объясняет код, но не выполняется) выделяются, например, серым или красным.
Это помогает программистам быстрее ориентироваться в коде и понимать его смысл.
a = input("Первое число: ") # 4
b = input("Второе число: ") # 12
print(f"Сумма {a} и {b} равна {int(a) + int(b)}")
# Сумма 4 и 12 равна 16
Программисты не пишут код в обычных текстовых редакторах вроде Microsoft Word. Для этого используются специальные программы — IDE (интегрированные среды разработки) или текстовые редакторы, такие как Visual Studio Code (лично я именно его использую), PyCharm, Sublime Text, Notepad++.
Эти программы созданы специально для работы с кодом. Они автоматически:
Подсвечивают разные части кода разными цветами (например, ключевые слова одним цветом, строки другим).
Помогают находить ошибки ещё до запуска программы.
Предлагают автодополнение кода, что ускоряет написание.
Существует также особый набор правил (который меняется от языка к языку), в который входит то, как писать отступы, специальные знаки (скобки, фигурные, квадратные, обычные и угловые скобки и тд.). Такие правила называются синтаксисом языка. Благодаря синтаксису, код не просто начинает выглядеть красивым, но и несет функциональность и смысл для компьютера (потому что компьютер не знает нашего языка, это программисты придумали, как обозначить разные действия, если компьютер встречает эти символы).
Теперь, даже если вы не будете писать программы, вы можете оценить, насколько продумана каждая, казалось бы, мелочь!
Если у вас есть время, очень рекомендую просветиться и изучить следующие видеоролики, в которых емко и познавательно рассказывается то, как работают компьютеры, процессоры и как работаю
Магия транзисторов: как мы научили компьютеры думать с помощью кусочков кремния?
Как работает компьютер? Взгляд изнутри!
Компиляция и интерпретация кода
АССЕМБЛЕР В 2023. Первый и последний урок.