Инструменты пользователя

Инструменты сайта


learning:py

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слеваПредыдущая версия
Следующая версия
Предыдущая версия
learning:py [08.02.2024 17:25] – [Циклы] viacheslavlearning:py [19.06.2025 09:47] (текущий) – [Круговая диаграмма] viacheslav
Строка 1: Строка 1:
 +====== Python ======
 +
 +===== Перенос установленных пакетов pypi в закрытый контур =====
 +<code powershell>
 +# Экспорт установленных пакетов на машине, имеющей доступ в интернет
 +$folder = 'C:\temp\twine'
 +
 +mkdir $folder -ErrorAction SilentlyContinue > $null
 +(pip.exe list |select -Skip 2) -replace '\s+','==' |% {
 +    pip.exe download -d $folder $_
 +}
 +
 +Compress-Archive $folder\* -DestinationPath "$folder.zip"
 +
 +# Импорт на машине, где нет доступа к интернету, распаковав архив (здесь: C:\temp\twine).
 +# Запускать раз за разом, пока не исчезнут ошибки.
 +$pip = "$env:localappdata\Programs\Python\Python312\Scripts\pip.exe"
 +
 +(dir "C:\temp\twine" |? name -notmatch '^pip').fullname |% {
 +    & $pip install --no-warn-script-location $_
 +}
 +
 +</code>
 +
 +====== code-basics.com ======
 +https://code-basics.com/ru/languages/python
 +===== Функции =====
 +Параметры функций
 +<code python>
 +def truncate(text, length):
 +    t = text[:length] + '...'
 +    return t
 +
 +print(truncate('Нашли ошибку? Есть что добавить?', 16))
 +</code>
 +
 +Необязательные параметры функций. Обязательные параметры должны идти первыми.
 +<code python>
 +def get_hidden_card(num, star=4):
 +    return '*' * star  + num[-4:]
 +
 +print(get_hidden_card('1425364758697069'))
 +</code>
 +
 +Именованные аргументы.\\
 +Преимущество перед позиционными в том, что он более наглядны и можно указывать только те параметры, которые нужны, а не все необязательные.\\
 +Позиционные должны идти первыми.
 +<code python>
 +def trim_and_repeat(string, offset=0, repetitions=1):
 +    return string[offset:] * repetitions
 +
 +print(trim_and_repeat('Hello!', offset=3, repetitions=5)) #lo!lo!lo!lo!lo!
 +</code>
 +
 +Аннотации типов. Указание типов, какие нужно ожидать и какой будет на выходе, повышает удобство и читаемость.
 +<code python>
 +def word_multiply(string: str, repetitions: int) -> str:
 +    return string * repetitions
 +
 +print(word_multiply('Hello!',2)) #Hello!Hello!
 +</code>
 +
 +===== Логика =====
 +Логический тип (true/false). ''=='' - равно, ''!='' - не равно.
 +<code python>
 +def is_pensioner (age: int):
 +    return age >= 60
 +
 +print(is_pensioner(79)) # True
 +</code>
 +
 +Предикаты. Возврат True/False, функции принято обозначать, начиная с is_/has_
 +<code python>
 +def is_mister(mister: str):
 +    return mister == 'Mister'
 +
 +print(is_mister('Mister')) # чувствительно к регистру
 +</code>
 +
 +Комбинирование операций и функций.\\
 +Приоритет арифметических операций выше логических.
 +def is_international_phone(number: str):
 +    return number[0] == '+'
 +
 +print(is_international_phone('89651234567')) # False
 +</code>
 +
 +And/Or.
 +<code python>
 +#Решение учителя:
 +def is_leap_year(year):
 +    return year % 400 == 0 or (year % 4 == 0 and year % 100 != 0)
 +#Ваше решение:
 +def is_leap_year(year: int):
 +    return year % 4 == 0 and (year % 400 == 0 or year % 100 != 0)
 +
 +print(is_leap_year(2000)) # True
 +print(is_leap_year(1900)) # False
 +</code>
 +
 +Not. Возможно множественное отрицание: ''not not''.
 +<code python>
 +def is_palindrome(string: str):
 +    str = string.lower().replace(' ','')
 +    return str == str[::-1]
 +
 +# Через регулярку
 +#def is_palindrome(string: str):
 +#    import re
 +#    str = re.sub('\s+', '', string.lower())
 +#    return str == str[::-1]
 +
 +def is_not_palindrome(string: str):
 +    return not is_palindrome(string)
 +
 +print(is_palindrome('Оголи жопу пожилого')) # True
 +print(is_palindrome('Привет родителям')) # False
 +print(is_not_palindrome('Оголи жопу пожилого')) # False
 +print(is_not_palindrome('Привет родителям')) # True
 +</code>
 +
 +Результат логических выражений.\\
 +Проверка идёт слева направо: OR возвращает первое true, AND - первое false.\\
 +''None'', ''0'', ''0.0'' - False, остальное - True.
 +<code python>
 +# true and yes = true, true or no = true
 +print(10 % 2 == 0 and 'yes' or 'no') # => 'yes'
 +# false and yes = false, false or no = false
 +print(11 % 2 == 0 and 'yes' or 'no') # => 'no'
 +
 +print(1 and 2 and 3 and 4 or 5) # 4
 +print(1 or 2 or 3 or 4 and 5) # 1
 +
 +def string_or_not(string):
 +    return isinstance(string, str) and 'yes' or 'no'
 +
 +print(string_or_not('Hexlet')) # 'yes'
 +print(string_or_not(10)) # 'no'
 +print(string_or_not('')) # 'yes'
 +print(string_or_not(False)) # 'no'
 +</code>
 +
 +===== Условия =====
 +IF
 +<code python>
 +def guess_number(num: int):
 +    if num == 42:
 +        return 'You win!'
 +    return 'Try again!'
 +# Вариант с and/or
 +#def guess_number(num: int):
 +#    return num == 42 and 'You win!' or 'Try again!'
 +
 +print(guess_number(42)) # You win!
 +</code>
 +
 +ELSE\\
 +Сделать все URL начинающимися с ''%%https://%%''.
 +<code python>
 +def normalize_url(url):
 +    if url[:8] == 'https://':
 +        return url
 +    else:
 +        if url[:7] == 'http://':
 +            return 'https://' + url[7:]
 +        else:
 +            return 'https://' + url
 +
 +print(normalize_url('https://ya.ru')) # https://ya.ru
 +print(normalize_url('google.com'))    # https://google.com
 +print(normalize_url('http://ai.fi'))  # https://ai.fi
 +</code>
 +
 +ELIF - альтернативное условие.
 +<code python>
 +def who_is_this_house_to_starks(i):
 +    if i == 'Karstark' or i == 'Tully':
 +        return 'friend'
 +    elif i == 'Lannister' or i == 'Frey':
 +        return 'enemy'
 +    else:
 +        return 'neutral'
 +    
 +print(who_is_this_house_to_starks('Karstark'))  # => 'friend'
 +print(who_is_this_house_to_starks('Frey'))      # => 'enemy'
 +print(who_is_this_house_to_starks('Joar'))      # => 'neutral'
 +print(who_is_this_house_to_starks('Ivanov'))    # => 'neutral'
 +
 +# Можно обойтись без else (в этом случае):
 +    elif i == 'Lannister' or i == 'Frey':
 +        return 'enemy'
 +    return 'neutral'
 +</code>
 +
 +Тернарный оператор\\
 +if — это инструкция, а не выражение. В Python есть конструкция, которая работает как if-else, но считается выражением.\\
 +В целом, тернарный оператор - это более лаконичный вариант if-else.
 +<code python>
 +# Вариант IF
 +def flip_flop(i: str):
 +    if i == 'flip':
 +        return 'flop'
 +    return 'flip'
 +
 +# Тернарный оператор
 +def flip_flop(i: str):
 +    return 'flop' if i == 'flip' else 'flip'
 +
 +print(flip_flop('flip')) # flop
 +print(flip_flop('floppy')) # flip
 +</code>
 +
 +Match (аналог switch в Powershell)\\
 +Частный случай if-else, в ряде случаев читается лучше.
 +<code python>
 +def get_number_explanation(i: int):
 +    match i:
 +        case 666:
 +            return 'devil number'
 +        case 42:
 +            return 'answer for everything'
 +        case 7:
 +            return 'prime number'
 +        case _:
 +            return 'just a number'
 +        
 +print(get_number_explanation(8))  # just a number
 +print(get_number_explanation(666))  # devil number
 +print(get_number_explanation(42))  # answer for everything
 +print(get_number_explanation(7))  # prime number
 +
 +# Без case_, как и без else, здесь можно обойтись:
 +    match i:
 +        case 7:
 +            return 'prime number'
 +    return 'just a number'
 +</code>
 +
 +===== Циклы =====
 +WHILE
 +<code python>
 +def print_numbers(last_number):
 +    i = last_number
 +    while i >= 1:
 +        print(i)
 +        i = i - 1
 +    print('finished!')
 +
 +print_numbers(4) # 4,3,2,1,finished!
 +</code>
 +
 +Агрегирование данных - добавление к уже имеющимся.
 +<code python>
 +# Перемножение чисел в диапазоне
 +def multiply_numbers_from_range(start, end):
 +    result = 1
 +    while start <= end:
 +        result = result * start
 +        start = start + 1
 +    return result
 +
 +print(multiply_numbers_from_range(1, 15)) # 1307674368000
 +
 +# Агрегирование строк
 +def join_numbers_from_range(start, end):
 +    string = ''
 +    while start <= end:
 +        string = string + str(start)
 +        start = start + 1
 +    return string
 +
 +print(join_numbers_from_range(4, 11)) # 4567891011
 +</code>
 +
 +Обход строк
 +<code python>
 +def print_reversed_word_by_symbol(word):
 +    i = len(word) - 1
 +    while i >= 0:
 +        print(word[i])
 +        i = i - 1
 +        
 +print_reversed_word_by_symbol('word')
 +d
 +r
 +o
 +w
 +</code>
 +
 +Условия внутри тела цикла
 +<code python>
 +def count_chars(string, char):
 +    string = string.lower()
 +    char = char.lower()
 +    index = 0
 +    count = 0
 +    while index < len(string):
 +        if string[index] == char:
 +            # Считаем только подходящие символы
 +            count = count + 1
 +        # Счетчик увеличивается в любом случае
 +        index = index + 1
 +    return count
 +    
 +# или делать каждую итерацию:
 +if string[index].lower() == char.lower():
 +</code>
 +
 +Подстрока (substring) с помощью цикла
 +<code python>
 +def my_substr(string, num):
 +    index = 0
 +    result = ''
 +    while index < num:
 +        result = result + string[index]
 +        index = index + 1
 +    return result
 +
 +print(my_substr('Привет, как поживаешь?', 9))
 +Привет, к
 +
 +# Проверка правильности аргументов
 +# Функция возвращает False, если хотя бы одно из условий истинно:
 +#    Отрицательная длина извлекаемой подстроки.
 +#    Отрицательный заданный индекс.
 +#    Заданный индекс выходит за границу всей строки.
 +#    Длина подстроки в сумме с заданным индексом выходит за границу всей строки.
 +# В ином случае функция возвращает True.
 +def is_arguments_for_substr_correct(string, index, subst):
 +    if subst < 0 or index < 0 or index >= len(string) or (subst + index) > len(string):
 +        return False
 +    return True
 +
 +string = 'Sansa Stark'
 +end = len(string) - 1
 +print(is_arguments_for_substr_correct(string, 2, -3))      # False
 +print(is_arguments_for_substr_correct(string, -1, 3))      # False
 +print(is_arguments_for_substr_correct(string, 0, 5))       # True
 +print(is_arguments_for_substr_correct(string, end + 1, 0)) # False
 +</code>
 +
 +==== Синтаксический сахар ====
 +Вместо ''index = index + 1'' пишется ''index += 1''.
 +^Исходная форма ^Сокращённая форма ^
 +|''a = a + 1'' |''a += 1'' |
 +|''a = a - 1'' |''a -= 1'' |
 +|''a = a * 2'' |''a *= 2'' |
 +|''a = a / 1'' |''a /= 1'' |
 +
 +<code python>
 +# Удаление символа из строки без replace()
 +def filter_string(text, letter):
 +    length = len(text)
 +    index = 0
 +    word = ''
 +    while index < length:
 +        if text[index] != letter:
 +            word += text[index]
 +        index += 1
 +    return word
 +
 +print(filter_string("Привет, как поживаешь?", 'а'))
 +Привет, кк поживешь?
 +</code>
 +
 +==== Возврат из цикла ====
 +<code python>
 +# Решение по теме
 +def is_contains_char(string, char):
 +    index = 0
 +    while index < len(string):
 +        if string[index] == char:
 +            return True
 +        index += 1
 +    return False
 +
 +# Моё решение (не вчитался в условие, сделал по-другому)
 +def is_contains_char(str, char):
 +    if (char in str):
 +        return True
 +    return False
 +</code>
 +
 +==== Цикл For ====
 +Как foreach в powershell. Для while нужно задавать условие остановки и вводить счетчик.\\
 +Цикл For предназначен для коллекций, где понятно, где останавливаться, в результате он лаконичнее while.
 +<code python>
 +# Функция filter_string(), реализованная ранее с помощью while
 +def filter_string(str, char):
 +    res = ''
 +    for c in str:
 +        if (c.lower() != char.lower()):
 +            res += c
 +    return res
 +    
 +# range() - диапазон
 +#range(stop) создает последовательность от 0 до stop - 1
 +#range(start, stop) создает последовательность от start до stop - 1
 +#range(start, stop, step) создает последовательность из чисел от start до stop - 1, с шагом step
 +for i in range(3, 0, -1):
 +    print(i)
 +3
 +2
 +1
 +
 +def print_table_of_squares(start, end):
 +    for i in range(start, end+1):
 +       print(f'square of {i} is {i ** 2}')
 +
 +print(print_table_of_squares(1, 4))
 +square of 1 is 1
 +square of 2 is 4
 +square of 3 is 9
 +square of 4 is 16
 +None
 +</code>
 +====== Тони Гэддис - Начинаем программировать на Python, 5 изд. ======
 +//"Starting Out With Python" (5th edition) by Tony Gaddis//
 +===== Ввод, обработка, вывод =====
 +<code python>
 +>>> name = 'world'
 +>>> print('name') # в кавычках - буквальное значение
 +name
 +>>> print(name) # без кавычек - чтение переменной
 +world
 +
 +print('One', 'two') # Разделитель - пробел
 +One two
 +>>> print('One', 'two', sep='---') # Задать разделитель
 +One---two
 +>>> print('One', end='-') # Задать символ окончания строки (по умолчанию - перенос строки)
 +>>> print('two', end='!')
 +One-two!
 +
 +name = input('Enter your name: ') # Ввод пользователя
 +hours = int(input('How many hours you\'ve worked: ')) # Вложенная функция - строку (при вводе всегда строка) в целое число. \ - экранирование
 +
 +# f-строки - форматирование вывода
 +>>> print(f'Hello, {name}!') # {name} - местозаполнитель
 +Hello, world!
 +
 +>>> num = 10
 +>>> print(f'Значение равно {num + 2}.') # В местозаполнителе можно использовать выражения
 +Значение равно 12.
 +
 +orig_price = float(input("Введите исходную цену: "))
 +# Цена со скидкой 20%
 +print(f'Конечная цена: {orig_price - orig_price * 0.2}')
 +
 +# {местозаполнитель:спецификатор формата}, например, :.2f для округления до 2-го знака после запятой
 +print(f'Конечная цена: {orig_price - orig_price * 0.2:.2f}')
 +# Если перед округлением поставить запятую, то целочисленная часть будет поделена запятыми по три разряда
 +num = 1234567890.12345
 +print(f'{num:,.2f}')
 +1,234,567,890.12
 +# Для целых чисел тип d
 +num = 1234567890
 +print(f'{num:d}')
 +1,234,567,890
 +
 +# Вывод десятичной дроби в процентах (в научной нотации - :e)
 +discount = 0.256
 +print(f'{discount:%}')
 +25.600000%
 +print(f'{discount:.0%}')
 +26%
 +
 +# Ширина поля. 10 знаков у поля с числом (включая само число). Если число больше поля, поле будет увеличено.
 +num = 123
 +print(f'Число равно {num:10}')
 +Число равно        123
 +
 +# Совмещение округления и ширины поля
 +discount = 2.256
 +print(f'Число {discount:20.2f}')
 +Число                 2.26
 +
 +# Выравнивание. Числа по умолчанию вправо, строки - влево.
 +# < - влево, > - вправо, ^ - по центру
 +f'num:<10d'
 +f'num:>20,2 f' # вправо с округлением до 2 знаков
 +
 +name1 = 'Василий'
 +name2 = 'Константин'
 +name3 = 'Мария'
 +name4 = 'Ольга'
 +print(f'***{name1:^20}***')
 +print(f'***{name2:^20}***')
 +print(f'***{name3:^20}***')
 +print(f'***{name4:^20}***')
 +***      Василий       ***
 +***     Константин     ***
 +***       Мария        ***
 +***       Ольга        ***
 +
 +# Порядок следования условных обозначений:
 +# [выравнивание][ширина][,][.точность][тип]
 +print(f'{num:^10,.2f}')
 +
 +# Конкатенация f-строк
 +print(f'Имя: {name}, ' +
 +      f'Отдел: {dep}, ' +
 +      f'Должность: {pos}')
 +Имя: Вася, Отдел: ИТ, Должность: сисадмин
 +# Неявная конкатенация (без плюсов), результат тот же.
 +print(f'Имя: {name}, '
 +      f'Отдел: {dep}, '
 +      f'Должность: {pos}')
 +      
 +# Следует избегать "магических чисел" в коде, например,
 +amount = balance * 0.069 # Что за 0.069, непонятно
 +# Рекомендуется использовать именованные константы
 +# Сразу понятно, что это, меньше вероятность опечаток, легче изменить значение, если оно повторяется в коде
 +interest_rate = 0.069
 +amount = balance * interest_rate
 +</code>
 +
 +==== "Черепашья" графика ====
 +<code python>
 +import turtle # Импорт модуля
 +turtle.showturtle() # Показать окно
 +turtle.forward(200) # Двинуть черепаху вперёд на 200 пикселей
 +turtle.left(45) # Развернуться влево на 45° (относительно текущего положения)
 +turtle.setheading(180) # Развернуться влево (абсолютно). 90° - вверх, 270° - вниз, 0° - вправо.
 +turtle.heading() # выяснить текущую ориентацию
 +turtle.penup() # поднять перо (линия рисоваться не будет)
 +turtle.pendown() # опустить перо
 +turtle.circle(100) # Нарисовать круг радиусом 100 пкс
 +turtle.dot() # Нарисовать точку
 +turtle.bgcolor('gray') # Цвет холста, здесь: серый
 +turtle.pencolor('red') # Цвет пера, здесь: красный
 +# Сброс
 +turtle.reset() # Стирает все рисунки, задаёт чёрный цвет пера, черепаха в исходном положении. Фон не сбрасывается.
 +turtle.clear() # Стирает все рисунки, остальное остаётся на месте.
 +turtle.clearscreen() # Полный сброс
 +
 +turtle.setup(640, 480) # размер холста (ширина, высота)
 +turtle.goto(-100, 0) # Переместить на координаты, здесь: x: -100, y: 0
 +turtle.pos() # Выяснить координаты
 +turtle.xcor() # Вывести положение по оси x
 +turtle.ycor() # Вывести положение по оси y
 +turtle.speed(0) # Скорость перемещения черепахи от 1 (по умолчанию, медленно) до 10 (быстро). 0 - анимация отключена, рисуется мгновенно. Без цифры - вывести текущую скорость.
 +turtle.hideturtle() # скрыть значок черепахи
 +turtle.showturtle() # показать значок черепахи
 +turtle.write('Привет') # Написать текст
 +
 +# Заполнение фигуры цветом
 +turtle.fillcolor('green') # Выбор цвета. Если не задать, то будет чёрный по умолчанию.
 +turtle.begin_fill() # Перед началом рисования фигуры
 +turtle.circle(-200)
 +turtle.end_fill() # После окончания рисования фигуры
 +# Если фигура не замкнута, то заполнение будет как если бы фигура была замкнутой
 +
 +# Интерактивный запрос данных, здесь: число, по умолчанию - 100, допустимый минимум 20, максимум 500
 +radius = turtle.numinput('Требуются данные', 'Введите радиус окружности', default=100, minval=20, maxval=500)
 +turtle.circle(radius)
 +# Строка
 +name = turtle.textinput('Требуются данные', 'Введите имя')
 +
 +turtle.done() # Предотвращение закрытия холста после выполнения программы (для IDLE не нужно). Добавляется последней строкой.
 +
 +# Созвездие Ориона
 +betelgeuse_x = -70
 +betelgeuse_y = 200
 +bellatrix_x = 80
 +bellatrix_y = 180
 +alnitak_x = -40
 +alnitak_y = -20
 +alnilam_x = 0
 +alnilam_y = 0
 +mintaka_x = 40
 +mintaka_y = 20
 +saif_x = -90
 +saif_y = -180
 +rigel_x = 120
 +rigel_y = -140
 +
 +import turtle
 +turtle.clearscreen()
 +turtle.reset()
 +turtle.hideturtle()
 +
 +turtle.penup()
 +turtle.goto(betelgeuse_x, betelgeuse_y)
 +turtle.write('Бетельгейзе')
 +turtle.pendown()
 +turtle.dot()
 +
 +turtle.goto(alnitak_x, alnitak_y)
 +turtle.write('Альнитак')
 +turtle.dot()
 +
 +turtle.goto(saif_x, saif_y)
 +turtle.write('Саиф')
 +turtle.dot()
 +turtle.goto(alnitak_x, alnitak_y)
 +
 +turtle.goto(alnilam_x, alnilam_y)
 +turtle.write('Альнилам')
 +turtle.dot()
 +turtle.goto(mintaka_x, mintaka_y)
 +turtle.write('Минтака')
 +turtle.dot()
 +
 +turtle.goto(bellatrix_x, bellatrix_y)
 +turtle.write('Беллатрикс')
 +turtle.dot()
 +turtle.goto(mintaka_x, mintaka_y)
 +turtle.goto(rigel_x, rigel_y)
 +turtle.write('Ригель')
 +turtle.dot()
 +
 +turtle.done()
 +</code>
 +
 +==== Практические задания ====
 +<code python>
 +# Цельсий -> Фаренгейт
 +celsius = int(input('Градусы по Цельсию: '))
 +print(f'Градусы по Фаренгейту: {1.8 * celsius + 32}')
 +
 +# Ингредиенты для булочек (норматив известен на 48 булочек)
 +buns = int(input('Кол-во булочек: '))
 +buns_standard = 48
 +print(f'Стаканов сахара: {buns * 1.5 / buns_standard:.1f}')
 +print(f'Стаканов масла: {buns * 1 / buns_standard:.1f}')
 +print(f'Стаканов муки: {buns * 2.75 / buns_standard:.1f}')
 +
 +# Расчёт кол-ва лоз в гряде
 +length = int(input('Длина гряды: '))
 +length_pillar = int(input('Длина опоры: '))
 +gap = int(input('Расстояние между лозами: '))
 +quantity = int((length - length_pillar * 2) / gap)
 +# Не округление, а отбрасывание десятичных знаков, иначе может не влезть
 +print(f'Кол-во лоз: {int((length - length_pillar * 2) / gap)}')
 +
 +# Сложный процент
 +initial_sum = float(input('Сумма, внесённая на счёт: '))
 +percent = float(input('Процентная ставка: ')) / 100
 +quant_per_year = int(input('Сколько раз в год начисляется процент: '))
 +years = int(input('Кол-во лет: '))
 +print(f'Итоговая сумма: {initial_sum * (1 + percent / quant_per_year) ** (quant_per_year * years):.2f}')
 +
 +</code>
 +
 +===== Структуры принятия решения и булева логика =====
 +
 +==== if/elif/else ====
 +<code python>
 +i = 10
 +reference = 50
 +
 +if i > reference:
 +    print('Больше')
 +elif i == reference:
 +    print('Равно')
 +else:
 +    print ('Меньше')
 +    
 +# Строки тоже можно сравнивать
 +password = input('Пароль: ')
 +reference = 'На горшке сидел король'
 +if password == reference:
 +    print('Проходи')
 +else:
 +    print('Пошёл вон')
 +
 +# При сравнении строк сравниваются их ASCII-коды, поэтому здесь будет "aa меньше ab".
 +# Более длинная строка будет больше более короткой.
 +if 'aa' < 'ab':
 + print('aa меньше ab')
 +else:
 + print('ab меньше aa')
 +
 +# При вложенных условиях нужно делать соответствующие отступы
 +if условие:
 + if условие:
 + действия
 + elif условие:
 + действия
 + else:
 + действия
 +else:
 + действия
 +</code>
 +
 +==== Логические операторы ====
 +<code python>
 +# and - true, если оба выражения истинны
 +if temperature > 40 and minutes > 5:
 + print(f'Температура больше 40 уже больше {minutes} мин!')
 +
 +# or - true, если хотя бы одно из выражений истинно
 +if temperature > 40 or temperature < 0:
 + print('Температура вне пределов нормы!')
 +
 +# not - инвертирует булево выражение
 +if not(temperature > 0):
 + print('Вода замерзает!')
 +
 +# Переменная с типом bool (значения True и False пишутся с большой буквы)
 +if sales >= 50000:
 + sales_quota_met = True
 +else:
 + sales_quota_met = False
 +
 +if sales_quota_met:
 + print('Квота продаж выполнена')
 +
 +# Движение по условию позиции "черепахи" 
 +if turtle.xcor() > 249 or turtle.ycor() > 349:
 + turtle.goto(0, 0)
 +# Если "черепаха" направлена под углом от 90 до 270 градусов, установить её в 180
 +if turtle.heading() >= 90 and turtle.heading() <= 270:
 + turtle.setheading(180)
 +# Если перо опущено, поднять
 +if turtle.isdown():
 + turtle.penup()
 +# Если перо не опущено, опустить
 +if not(turtle.isdown()):
 + turtle.pendown()
 +# Если "черепаха" видна, скрыть
 +if turtle.isvisible():
 + turtle.hideturtle()
 +# Если перо красное, установить синее
 +if turtle.pencolor() == 'red':
 + turtle.pencolor('blue')
 +
 +</code>
 +
 +==== Практические задания ====
 +
 +<code python>
 +# Калькулятор ингредиентов для хот-догов
 +visitors = int(input('Кол-во гостей: '))
 +hotdogs = int(input('Кол-во хот-догов на одного гостя: '))
 +sausage_pack = 10
 +buns_pack = 8
 +
 +total = visitors * hotdogs
 +if total % sausage_pack == 0 and total % buns_pack == 0:
 + print(f'Необходимо {total // sausage_pack} упаковок с сосисками и {total // buns_pack} упаковок с булочками.')
 + print('Лишнего не осталось.')
 +elif total % sausage_pack != 0 and total % buns_pack == 0:
 + print(f'Необходимо {total // sausage_pack + 1} упаковок с сосисками и {total // buns_pack} упаковок с булочками.')
 + print(f'Осталось {sausage_pack - total % sausage_pack} сосисок.')
 +elif total % sausage_pack == 0 and total % buns_pack != 0:
 + print(f'Необходимо {total // sausage_pack} упаковок с сосисками и {total // buns_pack + 1} упаковок с булочками.')
 + print(f'Осталось {buns_pack - total % buns_pack} булочек.')
 +else:
 + print(f'Необходимо {total // sausage_pack + 1} упаковок с сосисками и {total // buns_pack + 1} упаковок с булочками.')
 + print(f'Осталось {sausage_pack - total % sausage_pack} сосисок и {buns_pack - total % buns_pack} булочек.')
 +
 +# Цвета колеса рулетки
 +# RANGE даёт диапазон на единицу меньше в конце! Т. е., range(19, 29) реально будет 19-28!
 +pocket = int(input('Номер кармана (0-36): '))
 +if pocket == 0:
 + print('Зелёный')
 +elif pocket in range(1, 10) or pocket in range(19, 29):
 + if pocket % 2 == 0:
 + print('Чёрный')
 + else:
 + print('Красный')
 +elif pocket in range(11, 18) or pocket in range(29, 37):
 + if pocket % 2 == 0:
 + print('Красный')
 + else:
 + print('Чёрный')
 +else:
 + print('Число вне диапазона!')
 +
 +# Продажа ПО со скидкой
 +pkgs = int(input('Кол-во купленных пакетов ПО: '))
 +price = 99
 +discount = 0
 +if pkgs in range(10, 20):
 + discount = 10
 +elif pkgs in range(20, 50):
 + discount = 20
 +elif pkgs in range(50, 100):
 + discount = 30
 +elif pkgs >= 100:
 + discount = 40
 +
 +print(f'Итого: {(price - discount / 100) * pkgs:.2f} (скидка {discount}%)')
 +
 +# Тариф на доставку
 +weight = int(input('Масса посылки в граммах: '))
 +if weight <= 200:
 + fee = 150
 +elif weight in range(201, 601):
 + fee = 300
 +elif weight in range(601, 1001):
 + fee = 400
 +elif weight >= 1001:
 + fee = 475
 +
 +print(f'Тариф: {weight / 100 * fee:.2f} ({weight} г., тариф {fee})')
 +
 +# Индекс массы тела
 +height = int(input('Ваш рост (см): '))
 +weight = int(input('Ваш вес (кг): '))
 +index = round(weight / (height / 100) ** 2, 1)
 +if index <= 18.5:
 + print ('Худой')
 +elif index >= 18.5 and index <= 25:
 + print ('Туда-сюда')
 +elif index > 25:
 + print ('Толстый')
 +
 +# Секунды в дни-часы-минуты-секунды
 +sec = int(input('Секунд: '))
 +if sec in range(60, 3600):
 + print (f'{sec // 60} мин {sec % 60} сек')
 +elif sec in range(3600, 86400):
 + print (f'{sec // 3600} ч {sec % 3600 // 60} мин {sec % 3600 % 60} сек')
 +elif sec >= 86400:
 + print (f'{sec // 86400} д {sec % 86400 // 3600} ч {sec % 86400 % 3600 // 60} мин {sec % 86400 % 3600 % 60} сек')
 +else:
 + print (f'{sec} сек')
 +
 +# Високосный ли год
 +year = int(input('Год: '))
 +if (year % 100 == 0 and year % 400 == 0) or (year % 100 != 0 and year % 4 == 0):
 + print(f'Год {year} високосный')
 +else:
 + print(f'Год {year} не високосный')
 +</code>
 +
 +===== Циклы =====
 +==== while: цикл с условием повторения ====
 +Цикл повторяется, пока условие истинно. Если условие ложно изначально, цикл выполняться не будет.
 +<code python>
 +number = 5
 +while number <= 10:
 + print (number)
 + number = number + 1
 +</code>
 +
 +==== for: цикл со счётчиком ====
 +<code python>
 +for number in [1, 2, 3, 4, 5, 10]:
 + print (number)
 +
 +for word in ['Бегать', 'Прыгать', 'Ползти', 'Стоять']:
 + print (word)
 +
 +for word in range(3):
 + print ('3 повтора')
 +3 повтора
 +3 повтора
 +3 повтора
 +
 +# range (начало, конец, ширина шага)
 +for num in range(1, 10, 2):
 + print (num)
 +1
 +3
 +5
 +7
 +9
 +
 +# Часы - хорошая иллюстрация вложенных циклов for
 +for hours in range(24):
 + for minutes in range(60):
 + for seconds in range(60):
 + print(f'{hours}:{minutes}:{seconds}')
 +
 +# Ёлочка из звёздочек (range [0, 1, 2, 3, 4])
 +for row in range(5):
 + for col in range(row+1):
 + print('*', end='')
 + print()
 +*
 +**
 +***
 +****
 +*****
 +
 +# С пробелами
 +for row in range(5):
 + for col in range(row):
 + print(' ', end='')
 + print('*')
 +*
 + *
 +  *
 +   *
 +    *
 +
 +</code>
 +
 +===== Функции =====
 +2 варианта: функция без возврата значения (void function) и функция с возвратом. Имена функций подчиняются тем же правилам, что и имена переменных.\\
 +Хорошим вариантом имени будет глагол_существительное, например, get_hours или calculate_tax.
 +<code python>
 +def main():
 +  startup_message()
 +  input('Press Enter to see Step 1.')
 +  step1()
 +def startup_message():
 +  weight = '5 кг' # Локальная переменная. Действует только в рамках функции
 +  print('Приветствую!')
 +  print('{weight} картошки')
 +def step():
 +  weight = '10 кг' # Локальная переменная. Действует только в рамках функции
 +  print('Шаг 1')
 +  print('{weight} сахара')
 +# Вызов основной функции для старта программы
 +main()
 +
 +# pass - заглушка, ничего не делает. Используется, когда функция планируется, но деталей ещё нет.
 +# pass можно использовать и в других случаях, например, в циклах if/else, while и т. д.
 +def step1():
 +  pass
 +def step2():
 +  pass
 +</code>
 +
 +==== Передача аргументов в функцию ====
 +<code python>
 +# Позиционные аргументы
 +def main():
 +  print('Сумма двух чисел')
 +  show_sum(75, 15)
 +def show_sum(num1, num2):
 +  result = num1 + num2
 +  print(result)
 +main()
 +
 +# Именованные аргументы
 +def main():
 +  print('Сумма процентного дохода')
 +  show_interest(rate=0.01, periods=10, principal=10000.0)
 +def show_interest(principal, rate, periods):
 +  interest = principal * rate * periods
 +  print(f'Доход составит {interest:,.2f}')
 +main()
 +</code>
 +Можно использовать одновременно и позиционные, и именованные аргументы, но в этом случае позиционные должны стоять первыми, иначе будет ошибка.
 +
 +==== Глобальные переменные и константы ====
 +Глобальную переменную, которая действует на все функции, можно задать и внутри функции с помощью слова ''global''.
 +<code python>
 +def main():
 +  global number
 +  number = int(input('Введите число: '))
 +</code>
 +Глобальные переменные нужно использовать очень ограниченно, т. к. они затрудняют отладку и понимание программы. Лучше максимально использовать локальные переменные и аргументы функций.
 +
 +Глобальные константы в Питоне отсутствуют, но имитируются с помощью глобальных переменных, которые не меняются внутри функций с использованием слова ''global''.\\
 +Общепринятой практикой является написание их названий прописными буквами.
 +<code python>
 +# CONTRIBUTION_RATE здесь - это процентная ставка, значение которой легко поменять, чтобы обновить весь расчёт.
 +CONTRIBUTION_RATE = 0.05
 +def show_pay_contrib(gross):
 +  contrib = gross * CONTRIBUTION_RATE
 +  print(f'Взнос: {contrib :,.2f}')
 +</code>
 +
 +==== Функции с возвратом значения ====
 +При завершении возвращает значение в ту часть программы, которая её вызвала. Пишется так же, как и функция без возврата значения, но в конце имеет инструкцию ''return''.
 +<code python>
 +def sum(num1, num2):
 +  return num1 + num2
 +</code>
 +
 +Библиотечные функции - ''print()'', ''input()'', ''range()''. Многие функции хранятся в файлах-модулях, их нужно импортировать перед использованием.
 +<code python>
 +import random
 +number = random.randint(1, 100)
 +
 +# Вызов функции из f-строки
 +print(f'{random.randint(1, 1000):^10d}')
 +
 +# Случайное число в диапазоне 0-9
 +number = random.randrange(10)
 +# Случайное число в диапазоне 5-9
 +number = random.randrange(5,10)
 +# Случайное число среди 0, 10, 20 ... 100
 +number = random.randrange(0,101,10)
 +# Случайное число в диапазоне 0.0 - 1.0 (исключая 1.0)
 +number = random.random()
 +# Случайное число в диапазоне 1.0 - 10.0
 +number = random.uniform(1.0, 10.0)
 +# Каждый раз генерировать одну и ту же последовательность псевдослучайных чисел (random.seed)
 +random.seed(10)
 +print(f'{random.randint(1, 100)}')
 +print(f'{random.randint(1, 100)}')
 +print(f'{random.randint(1, 100)}')
 +</code>
 +
 +Для документирования функций удобно использовать таблицу "ввод-обработка-вывод", где описаны соответствующие действия функций.
 +^Функция ^Ввод ^Обработка ^Вывод ^
 +|get_price() |Розничная цена |Запрос розничной цены товара |Розничная цена товара |
 +
 +=== Возврат булева значения ===
 +<code python>
 +# Допустимы только значения 100, 200 и 300
 +def is_invalid(mod_num):
 + if mod_num not in [100,200,300]:
 + status = True
 + else:
 + status = False
 + return status
 +
 +model = int(input('Enter model number: '))
 +
 +if is_invalid(model):
 + print('Enter anotner number!')
 +else:
 + print('OK')
 +</code>
 +
 +=== Возврат нескольких значений ===
 +<code python>
 +def get_info():
 +  n = input('Ваше имя: ')
 +  a = int(input('Ваш возраст: '))
 +  return n, a 
 +# Присвоение значений переменным по порядку. Кол-во должно совпадать, иначе ошибка.
 +my_name, my_age = get_info()
 +</code>
 +
 +=== Значение None ===
 +<code python>
 +def main():
 +  n1 = int(input('Введите делимое: '))
 +  n2 = int(input('Введите делитель: '))
 +  res = divide(n1, n2)
 +  if res is None:
 +    print('Деление на 0 невозможно!')
 +  else:
 +    print(f'{n1} : {n2} = {res}')
 +def divide(n1, n2):
 +  if n2 == 0:
 +    res = None
 +  else:
 +    res = n1 / n2
 +  return res
 +main()
 +</code>
 +
 +==== Хранение функций в модулях ====
 +Когда накапливается много функций, их можно систематизировать, поместив в //модули// - файлы с набором функций определённого направления, например, rectangle.py - функции, связанные с треугольниками, round.py - с кругами и т. д.\\
 +Имя модуля должно иметь расширение ''.py'' и не должно совпадать с командами Питона (например, ''for''). В коде загрузить модуль можно командой import, например, ''import rectangle''. Поиск подходящего модуля идёт сначала в каталоге в программой, потом в других местах ([[https://docs.python.org/3/tutorial/modules.html#the-module-search-path|module search path]]).
 +
 +После импорта модуля можно вызывать его функции.
 +<code python>
 +import circle
 +# Площадь круга
 +my_area = circle.area(radius)
 +</code>
 +
 +==== Исполнение функции main по условию в модуле ====
 +Иногда может потребоваться импортировать как модуль саму программу или скрипт, т. е., получить её функции, не исполняя главной ''main()''. Это можно сделать, написав условие в потенциально импортируемой программе.
 +<code python>
 +if __name__ == '__main__':
 +  main()
 +</code>
 +Суть в том, что переменная ''%%__name__ == '__main__'%%'' только в случае самостоятельного запуска программы. Если программа была импортирована как модуль, то ''%%__name__%%'' будет равна имени модуля.
 +
 +===== Файлы и исключения =====
 +
 +Функция open - открытие файла. Создаётся файловый объект, связанный с файлом на диске.
 +<code python>
 +# r - read-only, w - write/create (если файл есть, он будет перезаписан), a - добавить данные в конец файла, если файла нет, он будет создан
 +test_file = open('file.txt', 'r')
 +# С указанием пути. r - строковый литерал, т. е. "\" не интерпретируется.
 +test_file = open(r'C:\Temp\file.txt', 'w')
 +
 +# Запись в файл
 +test_file = open(r'C:\Temp\people.txt', 'w')
 +test_file.write('Иван\n')
 +test_file.write('Пётр\n')
 +test_file.write('Ольга\n')
 +test_file.close()
 +
 +# Чтение из файла
 +test_file = open(r'C:\Temp\people.txt', 'r')
 +content = test_file.read()
 +test_file.close()
 +# Вывести на экран
 +print(content)
 +
 +# Построчное чтение. После каждого readline() позиция чтения сдвигается на строку вниз.
 +# Каждая прочитанная строка завершается символом \n. Если последняя строка не заканчивается на \n, то строка в переменной будет без него.
 +test_file = open(r'C:\Temp\people.txt', 'r')
 +str1 = test_file.readline()
 +str2 = test_file.readline()
 +str3 = test_file.readline()
 +test_file.close()
 +print(str1) # Иван
 +print(str2) # Пётр
 +print(str3) # Ольга
 +
 +# Убрать \n из полученных строк
 +name = 'Ольга\n'
 +name - name.rstrip('\n')
 +
 +# Перед записью числа в файл его нужно преобразовать в строку
 +test_file = open(r'C:\Temp\people.txt', 'a')
 +num1 = 99
 +test_file.write(str(num1) + '\n')
 +test_file.close()
 +
 +# Соответственно, числа, прочитанные из файла, являются строками, поэтому их нужно преобразовывать в int() или float()
 +# int() и float() игнорируют \n, поэтому убирать его потом не придётся.
 +test_file = open(r'C:\Temp\numbers.txt', 'r')
 +num1 = int(test_file.readline())
 +test_file.close()
 +print(num1)
 +
 +# Чтение файла построчно. Метод readline() возвращает пустое значение, когда он пытается читать за пределами файла,
 +# поэтому, чтобы вычитать файл построчно, применяется цикл с условием.
 +file = open(r'C:\temp\Inputfiles.txt', 'r')
 +line = file.readline().rstrip('\n')
 +while line != '':
 + print(line)
 + line = file.readline().rstrip('\n')
 +file.close()
 +
 +# Более удобный способ - чтение строк через цикл for.
 +# Здесь не надо ловить пустую линию, а просто указывается файловый объект для перечисления.
 +file = open(r'C:\temp\Inputfiles.txt', 'r')
 +for line in file:
 + print(line.rstrip('\n'))
 +file.close()
 +
 +# Удаление записи из файла. Структура файла:
 +# Вася Пупкин
 +# 4
 +# Петя Мокин
 +# 3
 +# Лена Петрова
 +# 5
 +
 +name = 'мокин'
 +
 +file_src = open(r'C:\temp\names.txt', 'r')
 +file_tmp = open(r'C:\temp\names_tmp.txt', 'w')
 +import re
 +
 +s = file_src.readline().rstrip('\n')
 +while s != '':
 + mark = file_src.readline().rstrip('\n')
 + if not re.search(name, s, re.IGNORECASE):
 + file_tmp.write(f'{s}\n')
 + file_tmp.write(f'{mark}\n')
 + s = file_src.readline().rstrip('\n')
 +file_src.close()
 +file_tmp.close()
 +
 +import os
 +os.remove(r'C:\temp\names.txt')
 +os.rename(r'C:\temp\names_tmp.txt', r'C:\temp\names.txt')
 +
 +</code>
 +
 +==== Обработка исключений ====
 +<code python>
 +# try - код, except - обработка исключения, возникшего в try.
 +try:
 + 15 / 0
 +# Имя исключения необязательно к указанию, тогда будут обрабатываться все исключения.
 +# Здесь - обрабатывать только исключение ZeroDivisionError.
 +except ZeroDivisionError:
 + print('Деление на ноль невозможно!')
 +
 +# Текст исключения, если нет его обработки:
 +Traceback (most recent call last):
 +  File "<pyshell#0>", line 1, in <module>
 +    15/0
 +ZeroDivisionError: division by zero
 +
 +# Обработка нескольких исключений. Без указания имени исключения обрабатываются все остальные случаи.
 +except IOError:
 +  print('Не могу прочитать файл, возможно, его не существует')
 +except ValueError:
 +  print('Неверный тип данных')
 +except:
 +  print('Ошибка!')
 +  
 +# Присвоение объекта исключения переменной err (можно задать любое другое название переменной)
 +except ValueError as err:
 +  print(err)
 +# invalid literal for int() with base 10: 'двадцать'
 +
 +# Конструкция try/except может иметь необязательную группу else, она выполняется при отсутствии исключений
 +try:
 + result = 15 / 5
 +except ZeroDivisionError:
 + print('Деление на ноль невозможно!')
 +else:
 +        print(result)
 +        
 +# Конструкция try/except может иметь необязательную группу finally, она выполняется независимо от того, были исключения или нет.
 +try:
 + result = 15 / 0
 +except ZeroDivisionError:
 + print('Деление на ноль невозможно!')
 +finally:
 +        print('Программа завершила работу')
 +</code>
 +Необработанное исключение приводит к остановке выполнения программы. Исключение может быть необработанным, если оно не было учтено в except либо возникло вне try.
 +
 +===== Списки и кортежи =====
 +//Последовательность// - индексируемая коллекция, содержащая множество значений. Есть несколько типов последовательностей, в их числе:
 +  - //Список// - последовательность с изменяемым содержимым. Это более функциональный вариант //массивов//.
 +  - //Кортеж// - последовательность с неизменяемым содержимым
 +
 +//Массивы// - более ограниченный вариант списков. Они могут быть созданы с помощью встроенного модуля ''array()'' или например, с помощью сторонней библиотеки numpy.
 +
 +<code python>
 +# Списки
 +nums = [2, 4, 6, 8, 10]
 +names = ['Вася', 'Петя', 'Коля']
 +info = ['Вася', '22', '1440.0'] # Значения могут быть разных типов
 +
 +# Функция list() преобразует некоторые типы объектов в списки
 +list(range(5)) # даст [0, 1, 2, 3, 4]
 +
 +# * становится оператором повторения, если слева от него последовательность
 +repeat = [1,2,3] * 3
 +print(repeat)
 +[1, 2, 3, 1, 2, 3, 1, 2, 3]
 +
 +# Обход списка в for
 +numbers = [2, 4, 6, 8, 10]
 +for num in numbers:
 +  print(num)
 +  
 +# Индексы
 +numbers[0] # 2
 +numbers[1] # 4
 +numbers[-1] # 10
 +numbers[5] # Исключение IndexError
 +
 +# Длина последовательности - len()
 +numbers = [2, 4, 6, 8, 10]
 +index = 0
 +while index < len(numbers):
 +  print(numbers[index])
 +  index += 1
 +
 +# Обход списка по индексу
 +numbers = [2, 4, 6, 8, 10]
 +for index in range(len(numbers)):
 +  print(numbers[index])
 +  
 +# Изменение списка. Изменить можно только существующие индексы.
 +numbers = [2, 4, 6, 8, 10]
 +numbers[0] = 1 # [1, 4, 6, 8, 10]
 +numbers[5] = 12 # исключение IndexError
 +# Можно сначала создать список, а потом менять его значения циклом
 +numbers = [0] * 6
 +n = 11
 +for i in range(len(numbers)):
 + numbers[i] = n
 + n += 1
 +print(numbers) # [11, 12, 13, 14, 15, 16]
 +
 +# Конкатенация (слияние) списков
 +list1 = [1,2,3]
 +list1 = [4,5,6]
 +list3 = list1 + list2 # [1, 2, 3, 4, 5, 6]
 +# Можно так:
 +list1 += list2 # list1 будет [1, 2, 3, 4, 5, 6]
 +
 +# Нарезка списка - [<начальный индекс>:<конечный индекс (не включая его)>].
 +numbers = [2, 4, 6, 8, 10]
 +print(numbers[1:4]) # [4, 6, 8]
 +print(numbers[2:-1]) # [6, 8]
 +# Если начальный индекс не указан, то подразумевается, что он равен 0
 +print(numbers[:-3]) # [2, 4]
 +# Если конечный индекс не указан, то перечисление будет идти до конца списка
 +print(numbers[3:]) # [8, 10]
 +print(numbers[-3:]) # [6, 8, 10]
 +# Если не указаны оба индекса, то это то же самое, что и список целиком. Эти значения одинаковы:
 +print(numbers[:])
 +print(numbers)
 +# Указание шага:
 +print(numbers[::2]) # [2, 6, 10]
 +print(numbers[1::2]) # [4, 8]
 +# Если в нарезке списка указать несуществующие индексы, то исключения не будет.
 +print(numbers[-888::2]) # [2, 6, 10] # Если начальный индекс за пределами диапазона индексов - используется начало списка
 +print(numbers[1:999:2]) # [4, 8] # Если конечный индекс за пределами диапазона индексов - используется длина списка
 +print(numbers[777:1:2]) # [] # Если индекс конца меньше индекса начала - пустой список
 +</code>
 +
 +==== Поиск и методы обработки списков ====
 +<code python>
 +# Поиск выполняется при помощи инструкции in
 +if num in [122,133,144,155]:
 +  print('The number is in the list')
 +  
 +# append(value) - добавить значение в конец списка
 +numbers = [2, 4, 6, 8, 10]
 +numbers.append(12)
 +print(numbers) # [2, 4, 6, 8, 10, 12]
 +
 +# index(value) - индекс первого совпавшего значения. Если значение не найдено - исключение ValueError.
 +print(numbers.index(6)) # 2
 +
 +# insert(index,value) - вставить значение на указанный индекс. Остальные сдвинутся. Если индекс за пределами диапазона, добавится в начало или в конец.
 +numbers.insert(3,7)
 +print(numbers) # [2, 4, 6, 7, 8, 10]
 +
 +# sort() - сортировка по значениям
 +numbers = [46, 2, 69, 28, 15]
 +numbers.sort()
 +print(numbers) # [2, 15, 28, 46, 69]
 +
 +# remove(value) - удалить первое совпавшее значение. Если значение не найдено - исключение ValueError.
 +numbers = [46, 5, 69, 5, 15]
 +numbers.remove(5)
 +print(numbers) # [46, 69, 5, 15]
 +
 +# Удалить конкретный индекс
 +numbers = [46, 5, 69, 5, 15]
 +del numbers[2]
 +print(numbers) # [46, 5, 5, 15]
 +
 +# reverse() - инвертировать порядок значений
 +numbers = [46, 2, 69, 28, 15]
 +numbers.reverse()
 +print(numbers) # [15, 28, 69, 2, 46]
 +
 +# min(), max() - минимальное и максимальное значение
 +numbers = [46, 5, 69, 5, 15]
 +print(min(numbers)) # 5
 +print(max(numbers)) # 69
 +
 +# Двумерный список
 +names = [["Вася","Петя"],["Оля","Маша"]]
 +print(names[1][0]) # Оля
 +</code>
 +
 +==== Копирование списков ====
 +<code python>
 +numbers = [2, 4, 6, 8, 10]
 +numbers2 = numbers # теперь обе переменные ссылаются на один и тот же объект в памяти
 +# Если изменить один объект, то изменится и второй
 +numbers[0] = 222
 +print(numbers2) # [222, 4, 6, 8, 10]
 +
 +# Чтобы сделать копию, но отдельную:
 +numbers2 = []
 +for i in numbers:
 +  numbers2.append(i)
 +# Другой вариант:
 +numbers2 = [] + numbers
 +</code>
 +
 +==== Некоторые функции ====
 +
 +<code python>
 +numbers = [2,4,6,8,10]
 +# Случайный выбор элемента списка
 +import random
 +print(random.choice(numbers))
 +# Случайные 3 элемента (может содержать повторяющиеся элементы)
 +print(random.choices(numbers, k=3))
 +# Случайные 3 уникальных элемента
 +print(random.sample(numbers, k=3))
 +
 +# Минимальное значение
 +print(min(numbers))
 +
 +# Строки из файла в массив
 +file = open(r'C:\temp\names_only.txt', 'r')
 +array = file.readlines()
 +print(array[5])
 +file.close()
 +
 +# Записать массив в файл (нужно подавать на вход строки, слова будут в одну строку без пробелов - ВасяПетяОля)
 +names = ["Вася","Петя","Оля"]
 +file = open(r'C:\temp\file.txt', 'w')
 +file.writelines(names)
 +file.close()
 +
 +</code>
 +
 +==== Включение в список ====
 +Создание нового списка путём копирования значений из другого.
 +<code python>
 +numbers = [2,4,6,8,10]
 +# Вариант 1 - через цикл. Здесь значения numbers добавляются к значениям numbers2
 +numbers2 = []
 +for i in numbers:
 +  numbers2.append(i)
 +# Вариант 2 - "включение в список". Здесь значения numbers2, если они были, полностью заменяются
 +numbers2 = [i for i in numbers]
 +
 +# Действия со значениями, включаемыми в список (здесь: возведение в квадрат)
 +numbers2 = [i**2 for i in numbers]
 +
 +# Длина значений
 +names = ["Вася","Петя","Оля"]
 +names_length = [len(i) for i in names]
 +
 +# Проверка условия перед включением в список
 +numbers = [2,4,6,8,10]
 +numbers2 = []
 +for i in numbers:
 +  if i >= 5:
 +    numbers2.append(i)
 +# Вариант 2
 +numbers2 = [i for i in numbers if i >= 5]
 +# Ещё пример
 +short_names = [name for name in names if len(name) < 6]
 +</code>
 +
 +==== Кортеж ====
 +Тот же список, но который невозможно изменить. Их смысл заключается с большем быстродействии (например, когда нужно обработать большой объём данных, который не будет изменяться) и в каком-то смысле большей безопасности, т. к. можно быть уверенным, что содержимое кортежа не будет изменено в программе. Также, в Питоне существуют операции, которые требуют применения кортежа.
 +
 +Кортежи поддерживают те же методы, что и списки, кроме тех, которые изменяют содержимое. Поддерживаются:
 +  * Доступ к элементам по индексам (для получения их значений)
 +  * Методы, например, ''index()''
 +  * Встроенные функции, например, ''len'', ''min'', ''max''
 +  * Выражения среза
 +  * Оператор ''in''
 +  * Операторы + и *
 +Кортежи не поддерживают методы ''append()'', ''remove()'', ''insert()'', ''reverse()'' и ''sort()''.
 +<code python>
 +# Создать кортеж
 +my_tuple = (1,2,3,4,5)
 +# Последовательно отобразить элементы
 +for i in my_tuple:
 +  print(i)
 +
 +# Создать кортеж с одним элементом (нужна запятая после значения, иначе создастся просто целочисленное значение)
 +my_tuple = (1,)
 +
 +# Преобразование кортежа в список и наоборот
 +my_list = list(my_tuple)
 +my_tuple = tuple(my_list)
 +
 +</code>
 +
 +==== График ====
 +<code bash>
 +# Установка доп. компонента (Windows)
 +pip install matplotlib
 +# Linux
 +sudo pip3 install matplotlib
 +</code>
 +
 +{{ .:pasted:20250614-200918.png?500}}
 +<code python>
 +# Импорт с алиасом, чтобы писать plt вместо matplotlib.pyplot
 +import matplotlib.pyplot as plt
 +
 +# Задание координат
 +x = [0,1,2,3,4, 5, 6,7]
 +y = [0,3,1,5,2,-1,-1,1]
 +# Нарисовать график с метками точек в виде ромба
 +plt.plot(x,y,marker='D')
 +# Если передать параметр маркера как позиционный,
 +# то будут нарисованы только маркеры без линий
 +# plt.plot(x,y,'D')
 +# Надписи
 +plt.title("Рельеф местности")
 +plt.xlabel("Ширина")
 +plt.ylabel("Высота")
 +# Границы осей
 +plt.xlim(xmin=-1, xmax=10)
 +plt.ylim(ymin=-1, ymax=6)
 +# Подписи делений
 +plt.xticks([1,3], ['Пик 1','Пик 2'])
 +plt.yticks([-1,0], ['Дно','Уровень моря'])
 +# Отображать сетку
 +plt.grid(True)
 +plt.show()
 +</code>
 +
 +==== Гистограмма ====
 +{{ .:pasted:20250616-203624.png?450}}
 +<code python>
 +import matplotlib.pyplot as plt
 +# Задание координат
 +x = [0,10,20,30,40]
 +y = [100,200,300,400,500]
 +# Ширина столбика (по умолчанию 0.8)
 +width = 10
 +# Нарисовать, задать цвета
 +plt.bar(x,y,width,color=('r','g','b','m','k'))
 +plt.title('Продажи по годам')
 +plt.xlabel('Год')
 +plt.ylabel('Объём продаж')
 +plt.xticks([5,15,25,35,45],['2016','2017','2018','2019','2020'])
 +plt.yticks([0,100,200,300,400,500],['0', '1 млн','2 млн','3 млн','4 млн','5 млн'])
 +plt.show()
 +</code>
 +
 +==== Круговая диаграмма ====
 +{{ .:pasted:20250619-094427.png?400}}
 +<code python>
 +import matplotlib.pyplot as plt
 +sales = [100,400,300,600]
 +labels = ['I квартал','II квартал','III квартал','IV квартал']
 +plt.pie(sales, labels=labels, colors=('r','g','b','m'))
 +plt.title('Продажи поквартально')
 +plt.show()
 +</code>
 +
 +
 +стр 427 (pdf 452)
 +====== Проблемы и их решение ======
 +
 +===== pip: Fatal error in launcher: Unable to create process =====
 +После установки новой версии питона и удаления старой. Помогло удаление каталогов старых версий в ''%LocalAppData%\Programs\Python''
 +
 +https://stackoverflow.com/questions/37220055/pip-fatal-error-in-launcher-unable-to-create-process-using
 +
  

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki