Содержание

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

https://code-basics.com/ru/languages/python

Функции

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

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.
 
# {местозаполнитель:спецификатор формата}

стр 80

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

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