Что из нижеперечисленного является характеристикой для python
Перейти к содержимому

Что из нижеперечисленного является характеристикой для python

  • автор:

Функциональное программирование на языке Python

Хотя пользователи обычно думают о Python как о процедурном и объектно-ориентированном языке, он содержит все необходимое для поддержки полностью функционального подхода к программированию.
В этой статье рассматриваются общие концепции функционального программирования и иллюстрируются способы реализации функционального подхода на Python.

Что такое Python?

Python — свободно распространяемый, очень высокоуровневый интерпретируемый язык, разработанный Гвидо ван Россумом (Guido van Rossum). Он сочетает прозрачный синтаксис с мощной (но необязательной) объектно-ориентированной семантикой. Python доступен почти на всех существующих ныне платформах и обладает очень высокой переносимостью между платформами.

Что такое функциональное программирование?

Лучше всего начать с труднейшего вопроса — а что, собственно, такое «функциональное программирование (FP)»? Один из возможных ответов — «это когда вы пишете на языке наподобие Lisp, Scheme, Haskell, ML, OCAML, Clean, Mercury или Erlang (или еще на некоторых других)». Этот ответ, безусловно, верен, но не сильно проясняет суть. К сожалению, получить четкое мнение о том, что же такое FP, оказывается очень трудно даже среди собственно функциональных программистов. Вспоминается притча о трех слепцах и слоне. Возможно также определить FP, противопоставив его «императивному программированию» (тому, что вы делаете на языках наподобие C, Pascal, C++, Java, Perl, Awk, TCL и на многих других — по крайнее мере, большей частью).

  • Функции — объекты первого класса. Т.е., все, что можно делать с «данными», можно делать и с функциями (вроде передачи функции другой функции в качестве параметра).
  • Использование рекурсии в качестве основной структуры контроля потока управления. В некоторых языках не существует иной конструкции цикла, кроме рекурсии.
  • Акцент на обработке списков (lists, отсюда название Lisp — LISt Processing). Списки с рекурсивным обходом подсписков часто используются в качестве замены циклов.
  • «Чистые» функциональные языки избегают побочных эффектов. Это исключает почти повсеместно распространенный в императивных языках подход, при котором одной и той же переменной последовательно присваиваются различные значения для отслеживания состояния программы.
  • FP не одобряет или совершенно запрещает утверждения (statements), используя вместо этого вычисление выражений (т.е. функций с аргументами). В предельном случае, одна программа есть одно выражение (плюс дополнительные определения).
  • FP акцентируется на том, что должно быть вычислено, а не как.
  • Большая часть FP использует функции «высокого порядка» (функции, оперирующие функциями, оперирующими функциями).

Защитники функционального программирования доказывают, что все эти характеристики приводят к более быстрой разработке более короткого и безошибочного кода. Более того, высокие теоретики от компьютерной науки, логики и математики находят, что процесс доказательства формальных свойств для функциональных языков и программ много проще, чем для императивных.

Функциональные возможности, присущие Python

Python поддерживает большую часть характеристик функционального программирования, начиная с версии Python 1.0. Но, как большинство возможностей Python, они присутствуют в очень смешанном языке. Так же как и с объектно-ориентированными возможностями Python, вы можете использовать то, что вам нужно, и игнорировать все остальное (пока оно вам не понадобится). В Python 2.0 было добавлено очень удачное «синтаксическое украшение» — списочные встраивания (list comprehensions). Хотя и не добавляя принципиально новых возможностей, списочные встраивания делают использование многих старых возможностей значительно приятнее.

Базовые элементы FP в Python — функции map() , reduce() , filter() и оператор lambda . В Python 1.x введена также функция apply(), удобная для прямого применения функции к списку, возвращаемому другой. Python 2.0 предоставляет для этого улучшенный синтаксис. Несколько неожиданно, но этих функций и всего нескольких базовых операторов почти достаточно для написания любой программы на Python; в частности, все управляющие утверждения ( ‘if’ , ‘elif’ , ‘else’ , ‘assert’ , ‘try’ , ‘except’ , ‘finally’ , ‘for’ , ‘break’ , ‘continue’ , ‘while’ , ‘def’ ) можно представить в функциональном стиле, используя исключительно функции и операторы. Несмотря на то, что задача реального удаления всех команд управления потоком, возможно, полезна только для представления на конкурс «невразумительный Python» (с кодом, выглядящим как программа на Lisp’е), стоит уяснить, как FP выражает управляющие структуры через вызовы функций и рекурсию.

Исключение команд управления потоком

#—— «Короткозамкнутые» условные вызовы в Python ——#
# Обычные управляющие конструкции
if : func1()
elif : func2()
else: func3()

# Эквивалентное «накоротко замкнутое» выражение
( and func1()) or ( and func2()) or (func3())

# Пример «накоротко замкнутого» выражения
>>> x = 3
>>> def pr(s): return s
>>> (x==1 and pr(‘one’)) or (x==2 and pr(‘two’)) or (pr(‘other’))
‘other’
>>> x = 2
>>> (x==1 and pr(‘one’)) or (x==2 and pr(‘two’)) or (pr(‘other’))
‘two’

Казалось бы, наша версия условных вызовов с помощью выражений — не более, чем салонный фокус; однако все становится гораздо интересней, если учесть, что оператор lambda может содержать только выражения! Раз, как мы только что показали, выражения могут содержать условные блоки, используя короткое замыкание, выражение lambda позволяет в общей форме представить условные возвращаемые значения. Базируясь на предыдущем примере:

#——— Lambda с короткозамкнутыми условными выражениями в Python ——-#
>>> pr = lambda s:s
>>> namenum = lambda x: (x==1 and pr(«one»)) \
. or (x==2 and pr(«two»)) \
. or (pr(«other»))
>>> namenum(1)
‘one’
>>> namenum(2)
‘two’
>>> namenum(3)
‘other’

Функции как объекты первого класса

Приведенные примеры уже засвидетельствовали, хотя и неочевидным образом, статус функций как объектов первого класса в Python. Дело в том, что, создав объект функции оператором lambda , мы произвели чрезвычайно общее действие. Мы имели возможность привязать наш объект к именам pr и namenum в точности тем же способом, как могли бы привязать к этим именам число 23 или строку «spam». Но точно так же, как число 23 можно использовать, не привязывая ни к какому имени (например, как аргумент функции), мы можем использовать объект функции, созданный lambda , не привязывая ни к какому имени. Функция в Python — всего лишь еще одно значение, с которым можно что-то сделать.

Главное, что мы делаем с нашими объектами первого класса — передаем их во встроенные функции map() , reduce() и filter() . Каждая из этих функций принимает объект функции в качестве первого аргумента. map() применяет переданную функцию к каждому элементу в переданном списке (списках) и возвращает список результатов. reduce() применяет переданную функцию к каждому значению в списке и ко внутреннему накопителю результата; например, reduce(lambda n,m:n*m, range(1,10)) означает 10! (факториал 10 — умножить каждый элемент на результат предыдущего умножения). filter() применяет переданную функцию к каждому элементу списка и возвращает список тех элементов исходного списка, для которых переданная функция вернула значение истинности. Мы также часто передаем функциональные объекты нашим собственным функциям, но чаще некоторым комбинациям вышеупомянутых встроенных функций.

Комбинируя три этих встроенных FP-функции, можно реализовать неожиданно широкий диапазон операций потока управления, не прибегая к утверждениям (statements), а используя лишь выражения.

Функциональные циклы в Python

Замена циклов на выражения так же проста, как и замена условных блоков. ‘for’ может быть впрямую переведено в map() . Так же, как и с условным выполнением, нам понадобится упростить блок утверждений до одного вызова функции (мы близки к тому, чтобы научиться делать это в общем случае):

#———- Функциональный цикл ‘for’ в Python ———-#
for e in lst: func(e) # цикл на утверждении ‘for’
map(func,lst) # цикл, основанный на map()

Кстати, похожая техника применяется для реализации последовательного выполнения программы, используя функциональный подход. Т.е., императивное программирование по большей части состоит из утверждений, требующих «сделать это, затем сделать то, затем сделать что-то еще». ‘map()’ позволяет это выразить так:

#—— Функциональное последовательное выполнение в Python ———-#
# создадим вспомогательную функцию вызова функции
do_it = lambda f: f()

# Пусть f1, f2, f3 (etc) — функции, выполняющие полезные действия
map(do_it, [f1,f2,f3]) # последовательное выполнение, реализованное на map()

В общем случае, вся главная программа может быть вызовом ‘map()’ со списком функций, которые надо последовательно вызвать, чтобы выполнить программу. Еще одно удобное свойство функций как объектов — то, что вы можете поместить их в список.

Перевести ‘while’ впрямую немного сложнее, но вполне получается :

#——— Функциональный цикл ‘while’ в Python ———-#
# Обычный (основаный на утверждении ‘while’) цикл
while :

if :
break
else:

# Рекурсивный цикл в функциональном стиле
def while_block():

if :
return 1
else:

return 0

while_FP = lambda: ( and while_block()) or while_FP()
while_FP()

Наш вариант ‘while’ все еще требует функцию while_block() , которая сама по себе может содержать не только выражения, но и утверждения (statements). Но мы могли бы продолжить дальнейшее исключение утверждений в этой функции (как, например, замену блока ‘if/else’ в вышеописанном шаблоне на короткозамкнутое выражение). К тому же, обычная проверка на месте (наподобие ‘while myvar==7’ ) вряд ли окажется полезной, поскольку тело цикла (в представленном виде) не может изменить какие-либо переменные (хотя глобальные переменные могут быть изменены в while_block() ). Один из способов применить более полезное условие — заставить while_block() возвращать более осмысленное значение и сравнивать его с условием завершения. Стоит взглянуть на реальный пример исключения утверждений:

#———- Функциональный цикл ‘echo’ в Python ————#
# Императивная версия «echo()»
def echo_IMP():
while 1:
x = raw_input(«IMP — «)
if x == ‘quit’:
break
else
print x
echo_IMP()

# Служебная функция, реализующая «тождество с побочным эффектом»
def monadic_print(x):
print x
return x

# FP версия «echo()»
echo_FP = lambda: monadic_print(raw_input(«FP — «))==’quit’ or echo_FP()
echo_FP()

Исключение побочных эффектов

После всей проделанной работы по избавлению от совершенно осмысленных конструкций и замене их на невразумительные вложенные выражения, возникает естественный вопрос — «Зачем?!». Перечитывая мои описания характеристик FP, мы можем видеть, что все они достигнуты в Python. Но важнейшая (и, скорее всего, в наибольшей степени реально используемая) характеристика — исключение побочных эффектов или, по крайней мере, ограничение их применения специальными областями наподобие монад. Огромный процент программных ошибок и главная проблема, требующая применения отладчиков, случается из-за того, что переменные получают неверные значения в процессе выполнения программы. Функциональное программирование обходит эту проблему, просто вовсе не присваивая значения переменным.

Взглянем на совершенно обычный участок императивного кода. Его цель — распечатать список пар чисел, чье произведение больше 25. Числа, составляющие пары, сами берутся из двух других списков. Все это весьма напоминает то, что программисты реально делают во многих участках своих программ. Императивный подход к этой задаче мог бы выглядеть так:

#— Императивный код для «печати произведений» —-#
# Процедурный стиль — поиск больших произведений с помощью вложенных циклов
xs = (1,2,3,4)
ys = (10,15,3,22)
bigmuls = []
#. прочий код.
for x in xs:
for y in ys:
#. прочий код.
if x*y > 25:
bigmuls.append((x,y))
#. прочий код.
#. прочий код.
print bigmuls

Этот проект слишком мал для того, чтобы что-нибудь пошло не так. Но, возможно, он встроен в код, предназначенный для достижения множества других целей в то же самое время. Секции, комментированные как «#. прочий код. » — места, где побочные эффекты с наибольшей вероятностью могут привести к ошибкам. В любой из этих точек переменные xs , ys , bigmuls , x , y могут приобрести неожиданные значения в гипотетическом коде. Далее, после завершения этого куска кода все переменные могут иметь значения, которые могут ожидаются, а могут и не ожидаться посдедующим кодом. Очевидно, что инкапсуляция в функциях/объектах и тщательное управление областью видимости могут использоваться, чтобы защититься от этого рода проблем. Вы также можете всегда удалять ( ‘del’ ) ваши переменные после использования. Но, на практике, указанный тип ошибок весьма обычен.

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

#— Функциональный код для поиска/печати больших произведений на Python —-#
bigmuls = lambda xs,ys: filter(lambda (x,y):x*y > 25, combine(xs,ys))
combine = lambda xs,ys: map(None, xs*len(ys), dupelms(ys,len(xs)))
dupelms = lambda lst,n: reduce(lambda s,t:s+t, map(lambda l,n=n: [l]*n, lst))
print bigmuls((1,2,3,4),(10,15,3,22))

Мы связываем в примере анонимные ( ‘lambda’ ) функции с именами, но это не необходимо. Вместо этого мы могли просто вложить определения. Мы использовали имена как ради большей читаемости, так и потому, что combine() — в любом случае отличная служебная функция (генерирует список всех возможных пар элементов из двух списков). В свою очередь, dupelms() в основном лишь вспомогательная часть combine() . Хотя этот функциональный пример более многословен, чем императивный, при повторном использовании служебных функций код в собственно bigmuls() окажется, вероятно, более лаконичным, чем в императивном варианте.

Реальное преимущество этого функционального примера в том, что в нем абсолютно ни одна переменная не меняет своего значения. Какое-либо неожиданное побочное влияние на последующий код (или со стороны предыдущего кода) просто невозможно. Конечно, само по себе отсутствие побочных эффектов не гарантирует безошибочность кода, но в любом случае это преимущество. Однако заметьте, что Python, в отличие от многих функциональных языков, не предотвращает повторное привязывание имен bigmuls , combine и dupelms . Если дальше в процессе выполнения программы combine() начнет значить что-нибудь другое — увы! Можно было бы разработать класс-одиночку (Singleton) для поддержки однократного связывания такого типа (напр. ‘s.bigmuls’ , etc.), но это выходит за рамки настоящей статьи.

Еще стоит отметить, что задача, которую мы только что решили, скроена в точности под новые возможности Python 2.0. Вместо вышеприведенных примеров — императивного или функционального — наилучшая (и функциональная) техника выглядит следующим образом:

#—— Код Python для «bigmuls» с использованием списочных встраиваний (list comprehensions) ——#
print [(x,y) for x in (1,2,3,4) for y in (10,15,3,22) if x*y > 25]

Заключение

Эта статья продемонстрировала способы замены практически любой конструкции управления потоком в Python на функциональный эквивалент (избавляясь при этом от побочных эффектов). Эффективный перевод конкретной программы требует дополнительного обдумывания, но мы увидели, что встроенные функциональные примитивы являются полными и общими. В последующих статьях мы рассмотрим более мощные подходы к функциональному программированию; и, я надеюсь, сможем подробнее рассмотреть «pro» и «contra» функционального подхода.

Ресурсы

Библиотека «xoltar toolkit» Брина Келлера (Bryn Keller), включающий модуль [functional], добавляет множество полезных FP-расширений к Python. Поскольку сам модуль [functional] написан на чистом Python, то, что он делает, можно сделать и без него. Но Келлер создал замечательно интегрированный набор расширений, предоставляющий высокую мощность в компактном определении. Пакет можно найти по адресу: http://sourceforge.net/projects/xoltar-toolkit

Автор нашел, что понять суть функционального программирования много проще через язык Haskell, нежели через Lisp (несмотря на то, что последний, вероятно, используется шире — хотя бы в Emacs). Возможно, другим программистам на Python тоже окажется легче жить без такого количества скобок и префиксной (польской) записи.

Блестящее введение в язык:

Об авторе

Поскольку постижение без интуиции бесплодно, а интуиция без постижения слепа, Давид Мертц хочет поставить литую скульптуру Мильтона в свой офис. Запланируйте подарить ему на день рождения.
Давида можно найти по адресу mertz@gnosis.cx; его жизнь протекает на http://gnosis.cx/publish.

Примечания

1. T.е. вычисление логического выражения заканчивается сразу, как только становится известен его логический результат. Стоит также заметить, что в Python, так же как и в Lisp, значением логического выражения является не true/false, а значение последнего вычисленного подвыражения — например, 4 and «Hello!» or 2*2 будет иметь значение «Hello!». прим. перев.

2. monadic_print() может быть реализована в полностью функциональном стиле, без использования утверждения print :

monadic_print = lambda x: sys.write(str(x) + ‘\n’) and x
прим. перев.

3. Следует обратить внимание, что пример работает только в том случае, если переменная echo_FP глобальна. Это связано с тем, что в Python всех версий до 2.0 включительно отсутствует статическая вложенность области действия имен. Любое имя, встретившееся в контексте функции или метода, ищется сначала среди локальных имен функции, а потом сразу среди глобальных имен (затем среди встроенных имен). Это отличается от логики языков со статическими областями действия имен (C, C++, Pascal, etc.), где имя последовательно ищется во всех объемлющих блоках. Из этого, в частности, следует, что рекурсивный вызов lambda-функции, привязанной к неглобальному имени, в Python версии меньше 2.1 невозможен. В Python 2.1 введены опциональные статические области действия. Таким образом, начиная с версии 2.1 Python можно рассматривать и как полноценный FP-язык (помимо всего прочего). Вышеприведенный комментарий относится почти ко всем функциональным примерам в статье. прим.

Автор: David Mertz, Ph.D., Applied Metaphysician, Gnosis Software, Inc.

Что из нижеперечисленного является объектом в Python?

Какие из перечисленных действий можно выполнить над любым объектом obj в языке Python 2.4?

Какие из перечисленных действий можно выполнить над любым объектом obj в языке Python 2.4?

Насколько полно C API Python охватывает средства языка Python?

В каком случае целесообразно написать модуль расширения, а не модуль на чистом Python (в предположении, что программная система пишется на Python)?

Как средствами самого Python определить имена формальных аргументов функции func() , если известно, что функция написана на Python?

Как определить функцию в Python?

Ответы: Программирование на языке Python. Синергия

Ответы представлены на ИТОГОВЫЙ ТЕСТ
Результат — 97-100 баллов
Перед покупкой сверьте список вопросов и убедитесь, что вам нужны ответы именно на эти вопросы!
С вопросами вы можете ознакомиться ДО покупки.
Для быстрого поиска вопроса используйте Ctrl+F.

Что из нижеперечисленного является характеристикой для Python?
Что такое интерпретатор Python?
Если прописать в редакторе “print (2+10)”, то что выводится на консоль?
Какие значения может принимать тип данных boolean?
Какие значения может принимать тип данных int?
Что выводится в консоль если в интерпретатор прописать
a= int(input())
b= int(input())
if a>b:
print(a)
else a==b:
print (“Данные числа равны”)
else
print(b)
и в консоле указать 7 и 5?
Какие кавычки можно использовать в Python для указания строки
Что выводится на консоль, умножить строку на n (где n, целое число)?
Какие существуют виды циклов?
В каких скобках указываются элементы для списка?
Какой индекс нужно указать чтобы получит число 4 из списка numbers=[1,2,3,4,5]
Что из нижеперечисленного является обозначением функции?
Какой индекс нужно указать чтобы получит число 5 из списка numbers=[8,2,6,4,5]
Что выполняет функция choice?
Что выведет данное решение, если a = 13?
a = int(input())
if a 6% == 0:
print(«делится»)
else:
print(«не делится»)
Какой оператор Возвращает значение True если оба утверждения верны?
Какой элемент списка выводится в консоль?
thislist = [«яблоко», «банан», «вишня»]
print(thislist[1])
Что делает функция “isupper()”?
Функция в python это —
Списки в Python это —
Что делает функция “f = open(‘text.txt’, ‘r’)”?
Обязательна ли функция “f.close()” для закрытия файла после работы с ним?
Инкапсуляция это —
Выберете правильное создание класса:
Что относится к встроенным и изменяемым типам в Python?
Разница между кортежем и списком в том, что
Для чего используется функция “range()”
Обязательны ли отступы в Python?
С чего обычно начинается индекс в Python?
Что выводиться на экран если прописать в интерпретатор

Клуб студентов «Технарь». Уникальный сайт с дипломами и курсовыми для технарей.

Описание:
В тесте 30 вопросов. Правильные ответы выделены желтым цветом.
1. Что делает функция “f = open(\’text.txt\’, \’r\’)”?
Открытие файла
Чтение файла
Запись в файл
2. Какой элемент списка выводится в консоль? thislist = [«яблоко», «банан», «вишня» target=’_blank’ > print(thislist[1])
Яблоко
Банан
Вишня
3. Что выводится в консоль если в интерпретатор прописать a= int(input()) b= int(input()) if a>b: print(a) else a==b: print (“Данные числа равны”) else print(b) и в консоле указать 7 и 5?
7
5
7 и 5
4. Что выводиться на экран если прописать в интерпретатор
2022.02.02
2022, 2, 3
2022.03.02
5. Что выводится на консоль, умножить строку на n (где n, целое число)?
выведется строка с указанием числа n
выведется целое число
выведется n-ое количество строк
6. Какой индекс нужно указать чтобы получит число 5 из списка numbers=[8,2,6,4,5]
3
-1
4
7. Если прописать в редакторе “print (2+10)”, то что выводится на консоль?
2+10
12
20
8. Какой индекс нужно указать чтобы получит число 4 из списка numbers=[1,2,3,4,5]
3
-2
3
9. Что выведет данное решение, если a = 13? a = int(input()) if a 6% == 0: print(«делится») else: print(«не делится»)
Не делится
Делится
Ошибка
10. Что из нижеперечисленного является обозначением функции?
def
for
int
11. Какие существуют виды циклов?
float
while
for
12. Что относится к встроенным и изменяемым типам в Python?
Списки
Кортежи
Множества
13. Выберете правильное создание класса:
class SomeClass(object):
SomeClass class(object):
class SomeClass ‘object’:
14. Разница между кортежем и списком в том, что
кортеж изменяемый, а список — нет
список изменяемый, а кортеж — нет
разницы нет
15. Что такое интерпретатор Python?
функция, которая позволяет изменять парадигму
вид документации
редактор кода для создания проектов
16. Что делает функция “isupper()”?
Проверяет, все ли символы в строке находятся в верхнем регистре
Проверяет, все ли символы в строке находятся в нижнем регистре
Проверяет, количество символов в строке
17. Что выполняет функция choice?
возвращает случайный элемент списка
возвращает случайное число из диапазона
генерирует случайное число от 0 до 1
18. Списки в Python это —
Упорядоченные изменяемые коллекции объектов произвольных типов (почти как массив, но типы могут отличаться)
Неупорядоченные изменяемые коллекции объектов произвольных типов (почти как массив, но типы могут отличаться)
Это структура данных, в которой хранятся значения одного типа
19. Функция в python это —
Упорядоченная последовательность, неизменяемая
Объект, принимающий значение и возвращающий аргументы
Объект, принимающий аргументы и возвращающий значение
20. Обязательна ли функция “f.close()” для закрытия файла после работы с ним?
Обязательна в определенных случаях
Не обязательна
Обязательна
21. Инкапсуляция это —
Дочерний класс который содержит все атрибуты родительского класса, при этом некоторые из них могут быть переопределены или добавлены в дочернем
Ограничение доступа к составляющим объект компонентам (методам и переменным)
Разное поведение одного и того же метода в разных классах
22. Какие значения может принимать тип данных int?
1.5, 1.6, 2.34 и тд.
0-255
1,2,3 и т.д.
23. Какой оператор Возвращает значение True если оба утверждения верны?
not
and
or
24. Какие кавычки можно использовать в Python для указания строки
любые
“”
<>
25. Что из нижеперечисленного является характеристикой для Python?
является зависимым от платформ
поддержка различных парадигм программирования
не динамическая типизация
26. С чего обычно начинается индекс в Python?
-1
0
1
27. Обязательны ли отступы в Python?
Да, они являются частью его синтаксиса
Нет, они не являются частью его синтаксиса
Они используются для красоты кода
28. Какие значения может принимать тип данных boolean?
1,2,3 и тд.
1/0
true/false
29. Для чего используется функция “range()”
Для создания списка из целых чисел
Для создания списка из любых чисел
Для создания списка из букв
30. В каких скобках указываются элементы для списка?
<>
“”
[]

Комментарии: Тест был успешно сдан в 2022 году.

Размер файла: 12,7 Кбайт
Фаил: (.rar)

Скачано: 25 Сейчас качают: 3 Коментариев: 0

Некоторые похожие работы:

К сожалению, точных предложений нет. Рекомендуем воспользоваться поиском по базе.

Спеши, предложение ограничено !

Что бы написать комментарий, вам надо войти в аккаунт, либо зарегистрироваться.

Вход в аккаунт:

Cодержание / Языки программирования / Ответы на тест «Программирование на языке Python». Синергия — 2022.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *