Импорт и создание модулей
Содержание
- Импорт модулей стандартной библиотеки
- Создание своего модуля питон
- Задача: составление анаграмм
- Домашнее задание
Импорт модулей стандартной библиотеки
Питон включает в себя обширную библиотеку модулей, в которых реализовано множество полезных функций. Далее в этом курсе мы будем применять и другие полезные модули: re
для регулярных выражений, collections
, содержащий множество удобных структур данных, os
и shutil
для управления файлами и папками.
Для использования модуля его нужно импортировать — попросить питон загрузить его и сделать его функции доступными для использования. Импорт осуществляется с помощью оператора import
. Например, модуль random
используется для генерации “случайных” чисел.
>>> import random
>>> # Теперь мы можем вызывать функции из модуля random, указав их имя после "random." с точкой
>>> random.randint(0, 5) # выводит случайное целое число между 0 и 5 включительно
2
>>> random.choice('abcdef') # выберает случайный элемент коллекции
'c'
>>> random.random() # Выводит случайное число на полуинтервале [0, 1)
0.9131300358342321
Ещё один пример: модуль math
, содержащий различные математические функции и константы
>>> math.cos(0) # ошибка, модуль ещё не импортирован
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-4-9cdcc157d079> in <module>()
----> 1 math.cos(0)
NameError: name 'math' is not defined
>>> import math
>>> math.cos(0)
1.0
>>> math.asin(1)
1.5707963267948966
>>> math.e
2.718281828459045
Использование псевдонимов
Если название модуля слишком длинное и вы не хотите его писать каждый раз, когда используете какую-то функцию, вы можете импортировать этот модуль под псевдонимом с помощью as:
>>> import math as m
>>> m.factorial(5)
120
Импорт нескольких модулей
Модули можно импортировать в одну строчку через запятую, если требуется использовать несколько, либо можно писать каждый импорт на новой строчке.
>>> import random, math
>>> math.sqrt(random.randint(0, 5))
2.23606797749979
Или:
import random
import math
>>> math.sqrt(random.randint(0, 5))
2.0
Инструкция from
Иногда в модуле бывает много разных функций, а вам нужно использовать только что-то одно (и, например, использовать много раз), тогда проще импортировать какую-то определенную функцию из этого модуля и (1) чуть-чуть сэкономить память, (2) короче синтаксис. Тогда синтаксис импорта будет следующий:
>>> from math import ceil, floor
>>> ceil(145.3)
146
>>> floor(145.6)
145
Также можно импортировать из модуля всё. То есть все функции, переменные и классы. Тогда нам не нужно каждый раз писать название модуля.
>>> from math import *
>>> sqrt(144)
12.0
>>> pi
3.141592653589793
Правило хорошего тона — импортировать модули вначале вашей программы, до любого другого кода и функций.
Создание своего модуля питон
Любой файл с исходным кодом на Python - модуль! Это значит, что любая программа может выступать в роли модуля для другой и импортироваться.
Давайте напишем скрипт с парой функций и импортируем эти функции в другую программу.
Создадим программу mymodule.py:
def avg(numbers):
if not numbers:
return 0
return sum(numbers) / len(numbers)
def myfactorial(n):
if n == 1:
return n
elif n < 1:
return ("NA")
else:
return n * myfactorial(n-1)
В ней мы прописали две математические функции: среднее и факториал. Предположим теперь мы хотим воспользоваться ими в какой-нибудь другой программе myscript.py. Тогда мы положим эти два файла в одну директорию, чтобы импорт работал. И в результате мы сможем ипмортировать эти функции в новую программу.
Файл myscript.py:
import mymodule
n = input("Введите число: ")
my_list = [1] * (int(n)/2) + [2] * (int(n)/2)
print(mymodule.avg(my_list))
print(mymodule.myfactorial(int(n)))
Кстати, найдите баг в этом коде:
>>> [1] * (5/2)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-35-f37e9b720bb2> in <module>
----> 1 [1] * (5/2)
TypeError: can't multiply sequence by non-int of type 'float'
>>> [1] * (5//2)
[1, 1]
Задача: составление анаграмм
В качестве примера использования функций и модуля стандартной библиотеки random
рассмотрим задачу составления анаграмм. В качестве входного файла будем использовать любой текст, из которого мы выберем слова. Пусть текст находится в файле text.txt
и имеет следующее содержание (из Яндекс.Рефератов):
Субъект вызывает мелодический импульс. Пласт параллельно понимает понимающий
эриксоновский гипноз, следовательно тенденция к конформизму связана с менее
низким интеллектом. Дифференциация, по определению, дает звукорядный
бихевиоризм.
Задача состоит в том, что необходимо составить файл формата TSV, состоящий из 4 колонок: слово из файла и три его случайных анаграммы. Для простоты анаграммы могут совпадать с самим словом или друг с другом. В итоге требуется получить файл table.tsv
, который будет начинаться следующим образом:
субъект ъсукебт кутесъб кеубътс
вызывает езтавыыв аыезыввт ывеаывзт
мелодический скйчмеелидио диимечеслйок мкееийлчосид
импульс млсупьи уьмипсл льмпиус
пласт сатпл таслп тпалс
...
Полный код для решения этой задачи может выглядеть следующим образом:
"""Эта программа собирает слова из text.txt и составляет список анаграмм из
них в таблице table.tsv"""
# Здесь мы импортируем модуль стандартной библиотеки random, в котором
# содержаться функции для работы с псевдослучайными числами.
# Правило хорошего тона — делать все импорты в начале вашей программы.
import random
def words_from_file(filename):
"""Принимает имя файла, а точнее его системный путь, и возвращает
список слов в нем
"""
with open(filename, encoding='utf-8') as f: # открвываем файл
text = f.read() # прочитываем весь файл в строковую переменную
text = text.replace('-', '') # удаляем дефисы
text = text.replace(',', '').replace('.', '') # удаляем запятые и точки
# Тут можно было почистить текст еще лучше
text = text.lower() # заменяем все заглавные на строчные
words = text.split() # получаем список слов
return words # возвращаем список слов
def anа(word):
"""Возвращает случайную анаграмму word"""
# Функция random.sample(sequence, count) возвращает список из count
# уникальных элементов последовательности (например списка или строки)
# взятых в случайном порядке. Заметим, что каждый элемент не может быть
# больше одного раза, а также напомним, что элементами строки являются
# односимвольные строки.
a = random.sample(word, len(word)) # получаем список перемешанных букв
new_word = ''.join(a) # объединяем элементы списка из букв в одну строку
return new_word # возвращаем анаграмму
def create_tsv_table(table_filename, words, n_anа):
"""Создает TSV-файл с именем table_filename со строками типа
слово→анаграмма→анаграмма,...
где список слов задается аргументом words, а число анаграмм — n_ana
"""
with open(table_filename, 'w', encoding='utf-8') as f: # открываем файл для записи
for x in words: # перебираем слова в переменной x
f.write(x) # запишем слово в файл
for i in range(n_ana): # n_ana раз создадим и запишем анаграмму
f.write('\t') # запишем разделитель
f.write(ana(x)) # запишем случайную анаграмму
f.write('\n') # не забудем поставить символ конца строки перед следующей строкой
def main():
words = words_from_file('text.txt') # получаем список слов
create_tsv_table('table.tsv', words, 3) # создаем таблицу с тремя анаграммами в каждой строке
if __name__ == '__main__':
main()
Домашнее задание
Пусть какая-то функция получает на вход список из 30 случайных целых чисел от 0 до 100, сгенерированных с помощью модуля random. В вариантах описана функция.
+1 балл для всех: ответьте коротко на вопрос “Почему модуль random на самом деле НЕ генерирует случайные числа?”
-
Функция берёт два случайных числа из этого списка (с помощью модуля random) и считает по ним количество всевозможных сочетаний этих чисел с точки зрения теории вероятности, С из n по k (использовать функцию из модуля math – factorial). Количество сочетаний (в формате float) печатается. k должно быть меньше n
-
Функция возвращает произведение значений списка. Нужно пользоваться модулем math. Руководствоваться надо тем, что exp(log(a) + log(b)) = a * b
-
Функция возвращает строку из 30 букв. Список, полученный на вход, задает порядок букв в строке по номеру буквы в алфавите.
-
Функция берёт из списка 4 случайных числа, условно принимает их за две точки в двумерном пространстве и возвращает евклидово расстояние между этими точками. Использовать модули random и math.
-
Функция перемешивает список с помощью random.shuffle(), сравнивает его с исходным списком и возвращает количество индексов, значение элемента по которым поменялось. Запустите функцию в цикле 100 раз и напечатайте в скольки процентов случаев меняются все элементы списка.
-
Функция возвращает среднее геометрическое списка. Вомпользуйтесь модулем math. Отдельно вне функции покажите, что ее результат лежит между минимальным и максимальным значениями списка для 20 случаев. (Для это нужно на каждой итерации генерировать подаваемый на вход список заново)
-
Функция возвращает среднее арифметическое элементов списка, округлённое вверх. Используйте модуль math.