OpenGuides

Python 3

[≔ Оглавление]

Полезные ссылки

Введение

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

Так, например, различные диалекты языка Prolog (напр., SWI Prolog) - декларативного языка программирования - обычно используются для создания различных экспертных систем, систем поддержки принятия решений, а также (иногда) для создания искуственного интелекта (напр., в играх), т.е. он используется в задачах, где проще описать набор понятий и правил, чем создавать алгоритм работы всей системы.

В то же время при решении задачи, где легче написать алгоритм её решения, логично использовать императивные языки, например, Python.

Note: В текущем руководстве описана работа Python 3

План работ


Level 1: Ввод, вывод и арифметика

Теоретический материал

Змеиные прелести

Python - интерпретируемый язык, т.е. программа на нём есть просто текст, а для её работы необходим интерпретатор. Положим, что такая программа уже установлена в ОС (если интерпретатора в системе нет, то (Windows|MacOS) идут на сайт https://www.python.org/downloads/, там где-то можно загрузить установщик, а *Linux и *BSD загружают из своих репозиториев).

Каждая строчка содержит (условно) одну команду, а отступы (по умолчанию - 4 пробела или 1 гориз. табуляция) представляют часть синтаксиса Python, причём в одном и том же скрипте нельзя сочетать отступы с помощью табуляции и пробелов.

Команда (точнее, функция) print("аргументы",... , "для", "печати") печатает переданный список объектов в стадартный поток вывода (т.е. консоль, терминал или иное обозначение командной строки). Пример:

print("Print <F> to pay respects")
print("<F>")

Типы данных

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

Как в различных математических дисциплинах, в языках программирования (далее ЯП) есть переменные. Например:

string_var = "str" # присваивание переменной string_var значения "str"
int_var = 1
float_var = 0.21
bool_var = True
list_var = ["some", bool_var, "values"] # использование переменной
                                        # для формирования списка,
                                        # к-рый записывается в list_var 

Правда, следует всегда помнить, что, в отличие от математики, в ЯП переменные - это также "указатели" на ячейки памяти. (Это значит как минимум, что под каждую переменную выделяется оперативная память, которая, естественно, небесконечна)

Python имеет динамическую типизацию, т.е. в одну и ту же переменную в процессе работы можно записывать разичные типы данных.

Арифметические Операторы

Оператор Назначение
-a унарный минус
a + b сложить операнды
a - b вычесть из a b
a / b разделить a на b
a * b умножить операнды
a // b взять частное от целочисленного деления a на b
a % b взять остаток от целочисленного деления a на b
a ** b возвести a в степень b
(...) то же предназначение, что в математике - изменение порядка действий

Ввод и вывод

Функция вывода на экран уже упомналась прежде, рассмотрим её подробнее.

print(*objects, sep=' ', end='\n', file=sys.stdout)`

Она печатает объекты, которые указываются через запятую, также у неё есть 3 доппараметра (с версии 3.3 их стало 4):

Для получения ввода из командной строки используется функция input([prompt]). У неё есть единственный опциональный параметр prompt. Пример:

s = input()

input() всегда возвращает введённую строку.

Преобразование типов

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

Функция Преобразование
str(объект) в строку
int(объект) в целое число
float(объект) в вещественное
bool(объект) в логическое знач.
list(объект) в список

Например, преобразование ввода в целочисленное значение:

i = int(input())

Задачи

Ссылка на задачу 'C'

  1. C и D

    N школьников делят K яблок поровну, неделящийся остаток остается в корзинке. Сколько яблок достанется каждому школьнику? Сколько яблок останется в корзинке?

    Входные данные: Программа получает на вход числа N и K.

    Выходные данные: Программа должна вывести искомое количество яблок.

  2. I

    Дано трехзначное число. Найдите сумму его цифр.

    Входные данные: Вводится трехзначное число.

    Выходные данные: Выведите ответ на задачу.

  3. J

    Дано целое число n. Выведите следующее за ним четное число. При решении этой задачи нельзя использовать условную инструкцию if и циклы.

    Примеры:

    Входные данные Выходные данные
    7 8
    8 10
  4. L

    Электронные часы показывают время в формате h:mm:ss, то есть сначала записывается количество часов, потом обязательно двузначное количество минут, затем обязательно двузначное количество секунд. Количество минут и секунд при необходимости дополняются до двузначного числа нулями. С начала суток прошло n секунд. Выведите, что покажут часы.

    Входные данные: Вводится целое число n.

    Выходные данные: Выведите ответ на задачу, соблюдая требуемый формат.

    Примеры:

    Входные данные Выходные данные
    3602 1:00:02
    129700 12:01:40

Level 2: Условный оператор

Теоретический материал

Логические выражения (высказывания)

Условия как известно задаются высказываниями. Эти выражения могут быть либо ложными(Л), либо истинными(И). В языке Python – это False и True или 0 и 1 (строго говоря, есть правило, что нуль - всегда ложь, а любое значение отличное от него - истина). Условия можно составить, либо используя операторы сравнения, либо логические функции. Ниже приведён список операторов сравнения:

Например:

a = 2 == (1 + 1) # присвоить переменной а результат проверки равенства 2 и суммы 1 и 1
print(a) # равенсво верное, следовательно, выведется True

В задании логических выражений используются т.н. логические операторы – И(and), ИЛИ(or) и НЕ(not). ~~На самом деле операторов больше

Пример:

a = (2 == (1 + 1)) and not (4 == 2 * 2)
print(a) # выведет False, т.к. отрицание второго равенства есть ложь (в пределах десятичной системы счисления и обычной арифметики)

Естественно, без переменных будет скучно:

c = 4 # представим, что это произошло где-то далеко в тексте программы
b = (c == 2 * 2) # это тоже

a = (2 == (1 + 1)) and not b
print(a) # по сути предыдущий пример, который я запутал настолько, насколько позволила лень
Оператор ветвления

Ветвление является одним из трёх элементов структурного программирования. Во многих задачах часть действий нужно производить только при выполнении определённых условий. В языке Python условный оператор выглядит следующим образом:

if CONDITION:
    DO_SMTH

Здесь CONDITION – выражение которое может быть либо истинным, либо ложным (высказывание), а DO_SMTH – блок кода (выделяется отступом) выполняется только когда условие выполняется, т.е. высказывание истинно.

Действия, выполняемые лишь в случае ложности высказывания (соотв., наличие if обязательно), описываются после ключевого слова (т.е. слова, которое есть элемент синтаксиса) else:

else:
    DO_OTHER_THING

Чтобы создать последовательность ветвлений можно использовать elif CONDITION: вместо сочетания else и if. Например:

if a == 1:
    print('one')
elif a == 2:
    print('two')
elif a == 3:
    print('three')
else:
    print("I can't count more")

Подробнее:

Задачи


Level 3: Операторы цикла

Теоретический материал

Задачи


Level 4: Строки и списки

Теоретический материал

Задачи


Level 5: Функции

Предназначение

При написании крупных проектов (100 и более строк) возникает неприятная запутанность исходных текстов. При проектировании алгоритмов, в таких случаях, блоки операций, которые выполняет одну задачу, сокращают до одной операции, реализацию которой описывают отдельно. Такой подход позволяет лицезреть подробности операции только когда это необходимо, а не в каждом месте алгоритма, где она встречается.

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

Краткое введение синтаксис

В Python общий вид синтаксической конструкции:

def <имя функции>(<параметры функции>):
    <команды>

Пример функции, печатающей элементы списка через пробел:

def print_list(list_0):
    for i in list_0:
        print(i, end=' ') # end - параметр функции print, отвеч. за конец строки (по умолчанию = '\n')

Пример программы с вызовом этой функции:

li = ['test0','test1','test2','test3']
print_list(li)

Вывод:

test0 test1 test2 test3

Подробный теоретический материал

Задачи

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

Цель - захватить все города, одолев всех противников.
Каждый из которых имеет свои характеристики(hp, атака,защита и т.п.).
В одном из городов противник-босс с повышенными характеристиками.

Игрок может выбрать "класс персонажа" со своими особенностями 
    (т.е. характеристиками, влияющими на игровой процесс).
    
В городе должна быть возможность моментального восстановления HP за плату и покупки зелий лечения.

При перемещении на героя с некоторой вероятностью могут нападать
весьма ослабленные противники (для пополнения геройского кошелька).
----
Интерфейс - командная строка
Игрок может видеть три экрана - меню, "город" и "бой" 
(ОСТОРОЖНО: вариативная часть, строчкой выше просто пример)
----

Level 6: Введение в ООП

Теоретический материал

Третий подход к программированию - объектно ориентированный. Его основу составляет понятие класса (своеобразный шаблон по которому создаются объекты), которому свойственны:

  1. инкапсуляция - включение в один объект переменнных и функций (а также иных сущностей языка программирования);
  2. наследование - (аки наследование в биологии) передача свойств от родителя потомкам
  3. полиморфизм - явление, при котором одно и то же имя функции (точнее, идентификатор) может иметь различную реализацию у родителя и его наследника.

В языке Python 3 новый класс создаётся через использование ключевого слова class. Рассмотрим пример с квадратами и прямоугольниками. Учитывая что квадрат описывается, по сути, одним параметром, а п-угольник - 2-мя, создадим класс квадрат, чтобы затем, используя наследование, создать класс прямоугольник:

class Square:   # класс квадрат
    a = 2       # поле - сторона квадрата (можно не указывать поля, если они инициализируются в конструкторе)
    
    def __init__(self, a = 2):  # конструктор, параметр 'a' по умолчанию будет равен 2
        self.a = a              # здесь self.a - поле 'a'
        
    def get_area(self):     # метод (внутренняя функция) класса,
        return self.a**2    # возвращающий площадь квадрата
    
    def __str__(self):  # перегрузка метода отвечающего за представление объекта как строки
        return "A " + type(self).__name__ + " with area of " + str(self.get_area())
        # столь странное представление сделано ради дальнейшей демонстрации полиморфизма
        # в которой также будет индикация имени класса, т.е. будет показано либо Square, либо Rectangle
    

Метод __init__(self,<параметры>) - т.н. конструктор класса, который описывает инициализацию полей. Этот и некоторые другие методы (__str__(self), __mul__(self, other) и т.д.) именуются магическими методами. Причиной сему служит то, что они, как магия, являются довольно мощным и иногда опасным инструментом при программировании (это касается, например, getattr).

Подробнее о магических методах можно прочесть здесь: https://habr.com/ru/post/186608/

Наследование происходит с помощью указания имени родителя после имени потомка:

class Rectangle(Square):
    b = 4 # поле (вторая сторона прямоугольника, первая наследуется из Square)
    
    def __init__(self, a = 2, b = 4):
        super().__init__(a)     # запуск инициализации класса-родителя (т.е. Square)
        self.b = b
        
    def get_area(self):         # переопределение функции получения площади
        return self.b*self.a

В качестве демонстрации создадим список из квадратов и прямоугольников, а затем выведем его на экран:

el_list = list()
for i in range(5):              # === i in [0,1,2,3,4]
    el_list.append(Square(i))
    el_list.append(Rectangle(i, i+1))
    
for i in el_list:
    print(i) 

Благодаря перегрузке метода __str__(self) получим следующий вывод:

A Square with area of 0
A Rectangle with area of 0
A Square with area of 1
A Rectangle with area of 2
A Square with area of 4
A Rectangle with area of 6
A Square with area of 9
A Rectangle with area of 12
A Square with area of 16
A Rectangle with area of 20

Если закомментировать участок с перегрузкой этого метода, то печать будет (условно) менее информативной.

Задачи


Copyright 2021 Fe-Ti