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

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


learning:py

Python

Перенос установленных пакетов pypi в закрытый контур

# Экспорт установленных пакетов на машине, имеющей доступ в интернет
$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-basics.com

Функции

Параметры функций

def truncate(text, length):
    t = text[:length] + '...'
    return t
 
print(truncate('Нашли ошибку? Есть что добавить?', 16))

Необязательные параметры функций. Обязательные параметры должны идти первыми.

def get_hidden_card(num, star=4):
    return '*' * star  + num[-4:]
 
print(get_hidden_card('1425364758697069'))

Именованные аргументы.
Преимущество перед позиционными в том, что он более наглядны и можно указывать только те параметры, которые нужны, а не все необязательные.
Позиционные должны идти первыми.

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!

Аннотации типов. Указание типов, какие нужно ожидать и какой будет на выходе, повышает удобство и читаемость.

def word_multiply(string: str, repetitions: int) -> str:
    return string * repetitions
 
print(word_multiply('Hello!',2)) #Hello!Hello!

Логика

Логический тип (true/false). == - равно, != - не равно.

def is_pensioner (age: int):
    return age >= 60
 
print(is_pensioner(79)) # True

Предикаты. Возврат True/False, функции принято обозначать, начиная с is_/has_

def is_mister(mister: str):
    return mister == 'Mister'
 
print(is_mister('Mister')) # чувствительно к регистру

Комбинирование операций и функций.
Приоритет арифметических операций выше логических. def is_international_phone(number: str):

  return number[0] == '+'

print(is_international_phone('89651234567')) # False </code>

And/Or.

#Решение учителя:
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

Not. Возможно множественное отрицание: not not.

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

Результат логических выражений.
Проверка идёт слева направо: OR возвращает первое true, AND - первое false.
None, 0, 0.0 - False, остальное - True.

# 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'

Условия

IF

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!

ELSE
Сделать все URL начинающимися с https://.

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

ELIF - альтернативное условие.

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'

Тернарный оператор
if — это инструкция, а не выражение. В Python есть конструкция, которая работает как if-else, но считается выражением.
В целом, тернарный оператор - это более лаконичный вариант if-else.

# Вариант 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

Match (аналог switch в Powershell)
Частный случай if-else, в ряде случаев читается лучше.

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'

Циклы

WHILE

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!

Агрегирование данных - добавление к уже имеющимся.

# Перемножение чисел в диапазоне
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

Обход строк

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

Условия внутри тела цикла

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():

Подстрока (substring) с помощью цикла

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

Синтаксический сахар

Вместо 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
# Удаление символа из строки без 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("Привет, как поживаешь?", 'а'))
Привет, кк поживешь?

Возврат из цикла

# Решение по теме
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

Цикл For

Как foreach в powershell. Для while нужно задавать условие остановки и вводить счетчик.
Цикл For предназначен для коллекций, где понятно, где останавливаться, в результате он лаконичнее while.

# Функция 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

Тони Гэддис - Начинаем программировать на Python, 5 изд.

Ввод, обработка, вывод

>>> 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

"Черепашья" графика

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()

Практические задания

# Цельсий -> Фаренгейт
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}')

Структуры принятия решения и булева логика

if/elif/else

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:
	действия

Логические операторы

# 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')

Практические задания

# Калькулятор ингредиентов для хот-догов
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} не високосный')

Циклы

while: цикл с условием повторения

Цикл повторяется, пока условие истинно. Если условие ложно изначально, цикл выполняться не будет.

number = 5
while number <= 10:
	print (number)
	number = number + 1

for: цикл со счётчиком

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('*')	
*
 *
  *
   *
    *

Функции

2 варианта: функция без возврата значения (void function) и функция с возвратом. Имена функций подчиняются тем же правилам, что и имена переменных.
Хорошим вариантом имени будет глагол_существительное, например, get_hours или calculate_tax.

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

Передача аргументов в функцию

# Позиционные аргументы
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()

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

Глобальные переменные и константы

Глобальную переменную, которая действует на все функции, можно задать и внутри функции с помощью слова global.

def main():
  global number
  number = int(input('Введите число: '))

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

Глобальные константы в Питоне отсутствуют, но имитируются с помощью глобальных переменных, которые не меняются внутри функций с использованием слова global.
Общепринятой практикой является написание их названий прописными буквами.

# CONTRIBUTION_RATE здесь - это процентная ставка, значение которой легко поменять, чтобы обновить весь расчёт.
CONTRIBUTION_RATE = 0.05
def show_pay_contrib(gross):
  contrib = gross * CONTRIBUTION_RATE
  print(f'Взнос: {contrib :,.2f}')

Функции с возвратом значения

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

def sum(num1, num2):
  return num1 + num2

Библиотечные функции - print(), input(), range(). Многие функции хранятся в файлах-модулях, их нужно импортировать перед использованием.

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)}')

Для документирования функций удобно использовать таблицу «ввод-обработка-вывод», где описаны соответствующие действия функций.

Функция Ввод Обработка Вывод
get_price() Розничная цена Запрос розничной цены товара Розничная цена товара

Возврат булева значения

# Допустимы только значения 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')

Возврат нескольких значений

def get_info():
  n = input('Ваше имя: ')
  a = int(input('Ваш возраст: '))
  return n, a 
# Присвоение значений переменным по порядку. Кол-во должно совпадать, иначе ошибка.
my_name, my_age = get_info()

Значение None

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()

Хранение функций в модулях

Когда накапливается много функций, их можно систематизировать, поместив в модули - файлы с набором функций определённого направления, например, rectangle.py - функции, связанные с треугольниками, round.py - с кругами и т. д.
Имя модуля должно иметь расширение .py и не должно совпадать с командами Питона (например, for). В коде загрузить модуль можно командой import, например, import rectangle. Поиск подходящего модуля идёт сначала в каталоге в программой, потом в других местах (module search path).

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

import circle
# Площадь круга
my_area = circle.area(radius)

Исполнение функции main по условию в модуле

Иногда может потребоваться импортировать как модуль саму программу или скрипт, т. е., получить её функции, не исполняя главной main(). Это можно сделать, написав условие в потенциально импортируемой программе.

if __name__ == '__main__':
  main()

Суть в том, что переменная __name__ == '__main__' только в случае самостоятельного запуска программы. Если программа была импортирована как модуль, то __name__ будет равна имени модуля.

Практические задания

### Оценочная стоимость и налог с недвижимости
def main():
	my_sum = float(input('Введите стоимость недвижимости: '))
	ocenochnaya_stoimost, nalog = tax(my_sum)
	print(f'Оценочная стоимость: {ocenochnaya_stoimost:.2f}')
	print(f'Налог: {nalog:.2f}')
def tax(s):
	# Оценочная стоимость - 60% от указанной
	ocenochnaya_stoimost = s * 0.6
	# 72 коп на каждые 100 руб от оценочной стоимости
	nalog = ocenochnaya_stoimost / 100 * 0.72
	return ocenochnaya_stoimost, nalog
if __name__ == '__main__':
	main()
 
Стоимость недвижимости: 5000000
Оценочная стоимость: 3000000.00
Налог: 21600.00
 
### Выручка от продажи мест на стадионе (стоимость: А - 20, B - 15, C - 10)
def main():
	sold_a = int(input('Продано мест А: '))
	sold_b = int(input('Продано мест B: '))
	sold_c = int(input('Продано мест C: '))
	print(f'Выручено: {income(sold_a,sold_b,sold_c)}')
def income(a,b,c):
	return a*20 + b*15 + c*10
if __name__ == '__main__':
	main()
 
Продано мест А: 1000
Продано мест B: 2000
Продано мест C: 4000
Выручено: 90000

стр 302 (pdf 327)

Проблемы и их решение

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

learning/py.txt · Последнее изменение: 14.05.2025 08:41 — viacheslav

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki