Примеры программ на языке Python
В этой статье собраны примеры небольших программ на языке программирования Python, демонстрирующих его синтаксис и некоторые из возможностей.Задание 5//2==
Нахождение 10 наиболее частых слов на web странице
правитьДанный пример чисто демонстрационный, так как его можно значительно улучшить.
from urllib import urlopen # из модуля urllib импортируем функцию urlopen
u = urlopen("http://python.org") # открываем URL на чтение
words = {} # связываем имя words с пустым словарём
# (словарь — неупорядоченный [[ассоциативный массив]])
for line in u: # читаем u по строкам
line = line.strip(" \n") # отбрасываем начальные и конечные пробелы
for word in line.split(" "): # режем каждую строку на слова, ограниченные пробелами
try: # блок обработки исключений
words[word] += 1 # пытаемся увеличить words[word] на единицу
except KeyError: # если не получилось (раньше words[word] не было)
words[word] = 1 # присваиваем единицу
# теперь словарь words содержит частоту встречаемости каждого слова.
# Например, words может содержать {"яблоко":5, "апельсин": 12, "груша": 8}
pairs = words.items() # делаем из словаря список пар
# pairs == [("яблоко",5), ("апельсин",12), ("груша",8)]
pairs.sort(key=lambda x: x[1], reverse=True) # сортируем по убыванию второго элемента пары
for p in pairs[:10]: # печатаем первые 10 элементов списка
print(p[0], p[1])
Текст для версии 3.7.1
from urllib.request import urlopen # из модуля urllib импортируем функцию urlopen
u = urlopen("http://python.org") # открываем URL на чтение
words = {} # связываем имя words с пустым словарём
# (словарь — неупорядоченный [[ассоциативный массив]])
for line in u: # читаем u по строкам
line =line.decode("utf-8") # преобразуем байт-строку в строку
line = line.strip(" \n") # отбрасываем начальные и конечные пробелы
for word in line.split(" "): # режем каждую строку на слова, ограниченные пробелами
try: # блок обработки исключений
words[word] += 1 # пытаемся увеличить words[word] на единицу
except KeyError: # если не получилось (раньше words[word] не было)
words[word] = 1 # присваиваем единицу
# теперь словарь words содержит частоту встречаемости каждого слова.
# Например, words может содержать {"яблоко":5, "апельсин": 12, "груша": 8}
pairs = words.items() # делаем из словаря список пар
# pairs == [("яблоко",5), ("апельсин",12), ("груша",8)]
A= sorted (pairs, key=lambda x: x[1], reverse=True) # сортируем по убыванию второго элемента пары
for p in A[:10]: # печатаем первые 10 элементов списка
print(p[0], p[1])
Примеры работы с последовательностями
правитьИллюстрируют особенности индексации элементов и срезов: при взятии среза нумеруются не сами элементы, а промежутки между ними.
>>> l = ['A', 'B', 'C', 'D', 'E'] # исходный список
>>> # 0 1 2 3 4 5 # пронумерованные промежутки между элементами
>>> # -5 -4 -3 -2 -1 # нумерация с конца
>>> l[0:2] # срез от нулевого до второго промежутка
['A', 'B']
>>> l[1:-2] # срез от второго до второго с конца элемента
['B','C']
>>> l[1::2] # каждый второй элемент начиная с первого
['B', 'D']
>>> l[::-1] # все элементы в обратном порядке
['E', 'D', 'C', 'B', 'A']
Функции подобные range()
поддерживают то же правило (для версий языка 2.x):
>>> range(2, 5)
[2, 3, 4]
>>> range(5)
[0, 1, 2, 3, 4]
Генерация коллекций:
>>> [0]*10
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
>>> [ i for i in range(5) if i%2==0]
[0, 2, 4]
import sys # для получения объектов из вышележащих фрэймов стека
class CannotResolve(Exception): # класс исключения для случая ненахождения функции
pass
class Resolver(object): # класс, реализующий разрешение на этапе исполнения
emess = "Can't found appropriate signature of func %s() for call with" + \ " params %r" # сообщение об ошибке def __init__(self,name): # конструктор self.function_map = {} # словарь, отображающий типы параметров на функции self.default = None # функция по умолчанию self.name = name # имя функции для вывода сообщений об ошибках def __call__(self,*dt): # имитируем функцию, принимающую любое количество # позиционных параметров cls = tuple(map(type,dt)) # создаем tuple из типов переданных аргументов # функция type возвращает тип своего параметра # map вызовет type для каждого элемента из dt try: x = self.function_map[cls] # пытаемся получить функцию из словаря except KeyError: # если подходящей нет, if self.default is not None: # используем функцию по умолчанию x = self.default else: # если её нет - возбуждаем исключение raise CannotResolve(self.emess % (self.name,cls)) return x(*dt) # вызываем функцию и возвращаем результат
def overload(*dt): # декоратор для перегрузки в качестве параметров
# принимает типы параметров def closure(func): name = func.__name__ # получаем имя функции fr = sys._getframe(1).f_locals.get(name,Resolver(name)) # опускаемся на один шаг вниз по стеку и находим # локальную переменную с именем функции # если же ее нет, то используем новый # Resolver-объект fr.function_map[dt] = func # добавляем новую функцию к словарю # разрешения вызовов return fr return closure
def overdef(func): # для создания функции по умолчанию
name = func.__name__ # аналогично как и в функции overload fr = sys._getframe(1).f_locals.get(name,Resolver(name)) fr.default = func return fr
- теперь воспользуемся полученными декораторами
@overdef # это будет функция по умолчанию def f(*dt,**mp):
print ("Default call") # если нет явного return, то вернется None
@overload(int) # единственный параметр - целое def f(x):
return x + 1
@overload(str) # единственный параметр - строка def f(x):
return x + "1"
@overload(str,int) # строка и целое def f(x,y):
return x + str(y)
print (f"1") # напечатает : 2 print (f"1") # напечатает : 11 f(2,2) # напечатает : Default call
Управление контекстом выполнения
правитьСледующий пример из PEP343 иллюстрирует применение оператора with
для защиты блока кода от одновременного выполнения двумя потоками:
from __future__ import with_statement # задействует оператор with в коде
from contextlib import contextmanager
from threading import Lock
# Описание менеджера контекста
@contextmanager
def locked(lock):
lock.acquire()
try:
yield
finally:
lock.release()
# Определение блокировки
myLock = Lock()
# Применение оператора
with locked(myLock):
#
print "Охраняемый блок кода. Блокировка будет освобождена при любом выходе из этого блока."
#
Генератор чисел Фибоначчи
правитьПример генератора чисел Фибоначчи и его использования:
def fibonacci(max): # генератор (а не функция, т.к. оператор return заменён на yield)
a, b = 0, 1
while a < max:
yield a # return a, + запоминаем место рестарта для следующего вызова
a, b = b, a + b # параллельное присваивание, которое выполняется одновременно и параллельно
for n in fibonacci(100): # используем генератор fibonacci() как итератор
print(n) # печатаем все числа Фибоначчи меньшие 100 через пробел
Альтернативный синтаксис доступа к элементам словаря
правитьМожно определить словарь, который в дополнение к обычному синтаксису доступа к значению по ключу d[key]
может предоставлять синтаксически более наглядный доступ к атрибуту d.key
в случае алфавитно-цифровых ключей:
class Entity(dict): # наследуем класс от __builtin__.dict
def __getattr__(self, key): # этот метод будет вызван, если атрибут
# с именем key не будет найден у экземпляра класса
try:
return self[key] # пытаемся вернуть элемент словаря
except KeyError, k: # если такого элемента нет, то возбуждаем
raise AttributeError, k # исключение AttributeError
# по договоренности __getattr__
# не должно возбуждать других исключений
def __setattr__(self, key, value): # этот метод будет вызван при присвоении
self[key] = value # атрибуту key значения value
def __delattr__(self, key): # а этот при удалении атрибута
try: # с помощью del mydict.g
del self[key]
except KeyError, k:
raise AttributeError, k
def __repr__(self): # используется функцией repr
return self.__class__.__name__ + "(" + dict.__repr__(self) + ")"
d = Entity(a=1)
d.b_100 = 100
assert d.a == d['a'] and d.b_100 == d['b_100']
Функтор с генерацией байтокода
правитьПример эффективной реализации функтора, основанный на генерации байтокода во время исполнения. Этот пример демонстрирует следующие возможности/особенности Python:
- Возможность реализации специфических средств функционального программирования наработками, уже имеющимися в языке
- Работать с байтокодом в Python достаточно просто
- Зачастую генерация байтокода способна значительно ускорить исполнение.
Это только пример, он реализует всего одну операцию — сложение и имеет несколько других ограничений.
#-------------------------------------------------------------------------------
import byteplay # специальный модуль для удобной работы с Python-байтокодом
import new # для создания функции во время исполнения
import functools # для update_wrapper
import inspect # для получения информации о параметрах, принимаемых функцией
#-------------------------------------------------------------------------------
class FastFunctor(object):
def __init__(self,func,code = None):
self.func = None # здесь будем хранить результирующую функцию
self.ofunc = func # а здесь исходную(original) функцию
if code is None:
# конструируем байтокод для вызова функции
self.code = [(byteplay.LOAD_CONST,func)]
rparams = inspect.getargspec(func)[0] # получаем список параметров, принимаемых функцией
self.code.extend((byteplay.LOAD_FAST,i) for i in rparams)
self.code.append((byteplay.CALL_FUNCTION,len(rparams)))
else:
# если же функтор создан из другого функтора,
# то только копируем переданный байтокод
self.code = code
# создаем новый объект кода
self.ocode = bp.Code.from_code(func.func_code)
def __add__(self,obj): # этот метод вызывается для операции '+'
code = self.code[:] # копируем байтокод
if isinstance(obj,FastFunctor): # если прибавляемый объект - функтор
# просто дописываем его код к нашему
# после своего исполнения он "оставит" в вершине стека результат
code.extend(obj.code)
else:
# иначе загружаем объект в стек
code.append((byteplay.LOAD_CONST,obj))
# дописываем байтокод, складывающий два верхних элемента в стеке
code.append((byteplay.BINARY_ADD ,None ))
# создаем новый функтор, с байтокодом получения суммы
return self.__class__(self.ofunc,code = code)
def __call__(self,*dt,**mp): # этот метод будет вызван для операции вызова object()
return self.fast()(*dt,**mp) # конструируем и вызываем функцию
def fast(self): # конструируем функцию из байтокода
if self.func is None: # если функция не была создана раннее
code = self.code + [(bp.RETURN_VALUE,None)] # добавляем байтокод возврата
oc = self.ocode
# создаем объект кода из байтокода и другой информации
bin_code = byteplay.Code(code,
oc.freevars,
oc.args,
oc.varargs,
oc.varkwargs,
oc.newlocals,
"<just_code_%s>" % id(self),
"<auto_gen_%s>" % id(self),
0,
"auto_generated code")
# конструируем новую функцию из объекта кода
self.func = new.function(bin_code.to_code(),globals())
# после этой операции для всех средств интроспекции
# созданная функция будет выглядеть как оригинальная
self.func = functools.update_wrapper(self.func,self.ofunc)
return self.func
# Ниже представлено тестирование скорости объектов FastFunctor и SlowFunctor
# (статья "Функциональное программирование на Python", см. сноску после блока кода)
# из IPython (для удобства чтения лог немного изменен)
# строки, начинающиеся с "In [XX]:" вводятся, остальные — вывод интерпретатора
In [1]: import fastfunctor
In [2]: func = lambda x : x + 1 # Создаем очень простую функцию
In [3]: vl = 1 # Переменная, для предотвращения оптимизации
In [4]: functor = fastfunctor.Functor(func)
In [5]: %timeit (functor + functor + 1)(vl) # Тестируем "лобовой" способ
1000 loops, best of 3: 661 mks per loop # Очень медленно
In [6]: functor2 = (functor + functor + 1) # Конструируем функтор один раз
In [7]: %timeit functor2(vl) # и тестируем только непосредственно вызов
100000 loops, best of 3: 4.52 mks per loop # Значительно лучше
In [8]: functor3 = (functor + functor + 1).fast() # Получаем результирующую функцию
In [9]: %timeit functor3(vl)
1000000 loops, best of 3: 1.42 mks per loop
In [10]: def of(vl): return x(vl) + x(vl) + 1 # Создаем функцию "вручную"
In [11]: %timeit of(vl)
1000000 loops, best of 3: 1.42 mks per loop # Скорость полностью совпадает со
# скоростью функтора
In [12]: sfunctor = SlowFunctor(func) # Простая реализация функтора
In [13]: sfunctor = sfunctor + sfunctor + 1 #
In [14]: %timeit sfunctor(vl) #
100000 loops, best of 3: 12.6 mks per loop # Примерно в 9 раз медленнее, чем статический
# вариант
Код SlowFunctor можно посмотреть здесь.
Приведенные значения времени следует рассматривать только в сравнении друг с другом.
ipython — расширение интерпретатора Python для интерактивной работы.
Используя эту технику, можно создать полноценный функтор, добавив функции для других операций
(__sub__, __div__
и другие) и расширив его на случай нескольких входных
функций с разными аргументами.
Транспонирование матрицы
правитьПример лаконичной реализации операции транспонирования матриц с использованием парадигмы функционального программирования.
from pprint import pprint # модуль pprint используется для удобного вывода на экран
matrix = [[0.5, 0, 0, 0, 0],
[ 1, 0.5, 0, 0, 0],
[ 1, 1, 0.5, 0, 0],
[ 1, 1, 1, 0.5, 0],
[ 1, 1, 1, 1, 0.5]]
matrix_t = list(zip(*matrix)) # непосредственно транспонирование
pprint(matrix)
pprint(matrix_t)
Вывод:
[[0.5, 0, 0, 0, 0],
[1, 0.5, 0, 0, 0],
[1, 1, 0.5, 0, 0],
[1, 1, 1, 0.5, 0],
[1, 1, 1, 1, 0.5]]
[[0.5, 1, 1, 1, 1],
[0, 0.5, 1, 1, 1],
[0, 0, 0.5, 1, 1],
[0, 0, 0, 0.5, 1],
[0, 0, 0, 0, 0.5]]
Нахождение Факториала
правитьfactorial = lambda x: factorial(x - 1) * x if x > 1 else 1
Решение квадратного уравнения
правитьПростая программа для решения квадратных уравнений (то есть вида: ax2+bx+c=0). Даются небольшие пояснения, каким образом уравнение решается в том или ином случае (например, для неполных квадратных уравнений).
a = int(input('a = ', )) # запрашиваем первый коэффициент
b = int(input('b = ', )) # запрашиваем второй коэффициент
c = int(input('c = ', )) # запрашиваем третий коэффициент
if a!= 0 and b % 2 == 0 and c!= 0: # решение по сокращенной формуле, т.к. b - четное
k = b / 2
d1 = k ** 2 - a * c
k1 = (-k + d1 ** 0.5) / a
k2 = (-k - d1 ** 0.5) / a
print('так как коэффициент b - четное число, решаем по сокращенной формуле')
print(f'k1 = {k1}')
print(f'k2 = {k2}')
if a != 0 and b % 2 != 0 and c != 0: # решение полного уравнения
d = b ** 2 - 4 * a * c
if d > 0:
k1 = (-b + d ** 0.5) / (2 * a)
print(f'дискриминант равен: {d}')
print(f'первый корень равен: {round(k1, 2)}')
k2 = (-b - d ** 0.5) / (2 * a)
print(f'второй корень равен: {round(k2, 2)}')
elif d < 0:
print(f'так как дискриминант меньше нуля и равен: {d}')
print('действительных корней нет')
else:
k = -b / (2 * a)
print(f'уравнение имеет один корень: {k}')
if a != 0 and c != 0 and b == 0: # решение уравнения при b = 0
if (- c / a) >= 0:
k1 = (-c / a) ** 0.5
print(f'первый корень равен: {k1}')
k2 = (-1) * ((-c / a) ** 0.5)
print(f'второй корень равен: {k2}')
if (- c / a) < 0:
print(f' -c / a = : {-c / a}, т.е. < 0, поэтому действительных корней нет')
if a != 0 and c== 0 and b != 0: # решение уравнения при с = 0
print(f'корень уравнения равен либо нулю, либо {-b / a}')
if a != 0 and b== 0 and c == 0: # решение уравнения при b = 0 и c = 0
print(f'корни уравнения равны нулю, a*x**2 = 0')
Что такое дробь
правитьcls @ECHO OFF title Folder Private if EXIST "HTG Locker" goto UNLOCK if NOT EXIST Private goto MDLOCKER
- CONFIRM
echo Are you sure you want to lock the folder(Y/N) set/p "cho=(more than)" if %cho%==Y goto LOCK if %cho%==y goto LOCK if %cho%==n goto END if %cho%==N goto END echo Invalid choice. goto CONFIRM
- LOCK
ren Private "HTG Locker" attrib +h +s "HTG Locker" echo Folder locked goto End
- UNLOCK
echo Enter password to unlock folder set/p "pass=(more than)" if NOT %pass%== [Ваш пароль] goto FAIL attrib -h -s "HTG Locker" ren "HTG Locker" Private echo Folder Unlocked successfully goto End
- FAIL
echo Invalid password goto end
- MDLOCKER
md Private echo Private created successfully goto End
- End
Вычисление числа Пи
правитьfrom decimal import *
getcontext().prec = int(input('Введите начальную точность:')) # Десятичная точность.
def Factorial(F):
result = 1
for i in range(2, F + 1):
result *= i
return result
b = int(input('Введите число слагаемых:')) # Число слагаемых.
n = 0
k = 0
while k <= b:
getcontext().prec += 20 # Увеличивается точность.
n += (Decimal(Factorial(4 * k) / (Factorial(k) ** Decimal(4))) * Decimal(
(1103 + 26390 * k) / (Decimal((4 * 99) ** Decimal(4 * k)))))
k += 1
N = n
n = Decimal(9801) / (Decimal(Decimal(2 * (Decimal(2 ** Decimal(0.5))) * N)))
print(Decimal(n))
input()
Тренажёр для изучения координат
правитьПрограмма, интересная и как тренажёр для учебной работы с координатами (5-7 класс) и как пример несложной программы, которую может написать начинающий программист (8-9 класс)
from tkinter import
import randomaps
okno = Tk()
okno.geometry('1500x700+0+0')
koordinatkax=random.randint(-15,15)
koordinatkay=random.randint(-6,6)
holst = Canvas(okno, width=1500, height = 600, bg = "white")
holst.create_line(0,300,1500,300,fill="black",width=3,arrow=LAST)
holst.create_line(750,600,750,0,fill="black",width=3,arrow=LAST)
metka = Label(okno,font=20,text="Привет всем! Найди точку с координатами x = " + str(koordinatkax) + ", y = " + str(koordinatkay))
metka.place(x = 0,y = 620)
metkaX = Label(holst,font=20,text="X")
metkaX.place(x = 1475,y =310)
metkaY = Label(holst,font=20,text="Y")
metkaY.place(x =760,y = 10)
#положительные метки Y
metka1Y = Label(holst,font=20,text="1")
metka1Y.place(x =725,y = 240)
#метка 0
metka0 = Label(holst,font=20,text="0")
metka0.place(x =725,y = 305)
#положительные метки X
metka1X = Label(holst,font=20,text="1")
metka1X.place(x =792,y = 308)
#отрицательные метки Y
metka1Y = Label(holst,font=20,text="-1")
metka1Y.place(x =725,y = 340)
#отрицательные метки X
metka1X = Label(holst,font=20,text="-1")
metka1X.place(x =692,y = 308)
for i in range(14):
holst.create_line(0,50*i,1500,50*i,fill="black",width=1)
holst.create_line(745,50*i,755,50*i,fill="black",width=3)
for i in range(30):
holst.create_line(50*i,0,50*i,600,fill="black",width=1)
holst.create_line(50*i,295,50*i,305,fill="black",width=3)
holst.place(x=0,y=0)
knopka = Button(okno)
knopka.place(x = 50,y = 650)
def gdelevyklik(event):
xo = koordinatkax*50+750
yo = 300-koordinatkay*50
if int(((event.x-xo)**2+(event.y-yo)**2)**0.5) < 5:
okno.title("Молодец! Левая кнопка мыши нажата" + str(event.x) + " " + str(event.y))
else:
okno.title("Не правильно! Левая кнопка мыши нажата" + str(event.x) + " " + str(event.y))
holst.bind('<Button-1>', gdelevyklik)
okno.mainloop()