[Python, Программирование, Учебный процесс в IT] 10 удивительно полезных базовых функций Python (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Те, кто работает с Python, знают, что этот язык хорош благодаря своей обширной экосистеме. Можно даже сказать, что язык программирования не выделялся бы ничем особенным, если бы не его замечательные пакеты, которые добавляют новые функции к основным.
В качестве примера можно привести NumPy. Инструменты работы с матрицами хороши и в базовом Python, но использование NumPy улучшает все во много раз. Кроме того, у этого языка есть несколько крутых возможностей, которые делают его еще более функциональным. Используя эти возможности, вы можете уменьшить количество зависимостей, освободить время и упростить сам процесс разработки. Давайте посмотрим, что это за возможности.
Кстати, свои советы по некоторым функциям добавил Алексей Некрасов — лидер направления Python в МТС, программный директор направления Python в Skillbox. Чтобы было понятно, где перевод, а где — комментарии, последние мы выделим текстом.
№1 lambda
Я как-то написал целую статью о том, почему lambda делает Python оптимальным языком программирования для статистических вычислений. Благодаря этой функции математические операции можно применить практически к любому типу данных, используя не целые функции, а оценку выражений.
Она позволяет вводить определения в глобальном масштабе, а также использовать functional-like синтаксис и методологию, причем на языке, у которого все еще есть структура классов.
Все это позволяет сэкономить время в ходе написания программы, сохранить ресурсы и сделать код более лаконичным. Более того, lambda дает возможность использовать такие методы, как apply() для быстрого применения выражений ко всем подмножествам данных. Для дата-сайентиста, да и не только для представителей этой профессии, подобные возможности крайне полезны.
Синтаксис выглядит следующим образом. Начинаем со значения, равного возвращению lambda-выражения, затем следует переменная, которую мы хотели бы предоставить в качестве позиционного аргумента. После этого выполняем операцию, используя этот аргумент в качестве переменной:
mean = lambda x : sum(x) / len(x)
Теперь мы можем осуществить вызов, как и в случае с любым другим методом в Python:
x = [5, 10, 15, 20]
print(mean(x))
Комментарий Алексея:
Будьте аккуратнее с lambda, чтобы не ухудшить читаемость кода. Вот пара советов:
Из PEP8. Всегда используйте оператор def вместо оператора присваивания, который связывает лямбда-выражение напрямую с идентификатором:
Правильно:
def f (x): return 2 * x
Неправильно:
f = lambda x: 2 * x
Если длина lambda выражения больше 40 символов, то скорее всего вы засунули в одну строчку кода слишком много логики и она стала нечитабельна. Так делать не стоит, лучше вынести в отдельную функцию.
№2: Shutil
Модуль Shutil — один из наиболее недооцененных инструментов в арсенале Python. Он включен в стандартную библиотеку, и может быть импортирован так же, как и любой другой модуль в языке:
import shutil
Что же делает shutil? На самом деле, это интерфейс высокого уровня для языка программирования Python, в отношении файловой системы вашей ОС. Эти вызовы часто выполняются с использованием модуля os, об shutil не стоит забывать. Вероятно, вам приходилось перемещать файл из каталога в каталог при помощи скрипта, проделав для этого массу утомительной работы, верно?
Shutil решает эти классические проблемы с файлами и таблицами размещения (allocation tables) при помощи высокоуровневого решения. Это — ключ для экономии времени и ускорению операций с файлами. Вот несколько примеров высокоуровневых вызовов, которые предоставляет shutil.
import shutil
shutil.copyfile('mydatabase.db', 'archive.db')
shutil.move('/src/High.py', '/packages/High')
№3: glob
Возможно, glob и не такой классный, как shutil, плюс он и рядом не стоял с lambda в плане полезности. Но он незаменим в некоторых случаях. Этот модуль используется для поиска директорий для wildcards. Это означает, что его можно использовать для агрегирования данных о файлах на вашем ПК и их расширениях. Импортируется модуль без проблем:
import glob
Я не уверен, есть ли у этого модуля еще функции, но glob() — то, что нужно для выполнения поиска файлов. В ходе поиска используется синтаксис Unix, т.е. т.е. *, / и т. д.
glob.glob('*.ipynb')
Эта строка возвращает все имена файлов соответствующих указанному запросу. Использовать функцию можно как для агрегирования данных, так и просто для работы с файлами.
№4: argparse
Этот модуль предоставляет надежный и глубокий метод анализа аргументов командной строки. Многие инструменты разработки используют эту концепцию, работать со всем этим можно при помощи командной строки Unix. Отличный пример — Python Gunicorn, обрабатывающий переданные аргументы командной строки. Для начала работы с модулем его нужно импортировать.
import argparse
Затем, чтобы получить возможность работать с ним, строим новый тип, это будет парсер аргументов:
parser = argparse.ArgumentParser(prog = 'top',
description = 'Show top lines from the file')
Ну а теперь мы добавляем новые аргументы в наш парсер. В этом случае создаем аргумент, который можно передать для определения количества строк, которые мы хотим вывести для каждого файла:
parser.add_argument('-l', '--lines', type=int, default=10)
Здесь добавлено несколько аргументов ключевого слова, один из которых предоставит тип данных, который передается для этого аргумента, а другой — значение по умолчанию, когда файл вызывается без этого аргумента. Теперь мы можем получить аргументы, вызвав функцию parse_args () для нашего нового типа парсера аргументов:
args = parser.parse_args()
Теперь мы можем вызвать этот файл Python для компиляции, а также легко предоставить необходимые параметры из Bash.
python top.py --lines=5 examplefile.txt
Излишне говорить, что это определенно может пригодиться. Я часто использовал этот модуль при работе с Crontab. Он может запускать скрипты с определенными временными метками Unix. Кроме того, этот сценарий также можно использовать для супервизоров, которые запускают команды Bash без участия пользователя в качестве worker.
№5: import re
Еще один крайне недооцененный модуль. Модуль re используется для синтаксического анализа строк с помощью регулярных выражений и предоставляет больше возможностей для работы со строками в Python. Сколько раз вы сталкивались с принятием алгоритмических решений на основе функций, которые есть в строковом классе, например str.split ()? Но хватит это терпеть! Ведь регулярные выражения намного проще и их намного проще использовать!
import re
Модуль re, в отличие от некоторых других в этом списке, предоставляет не одну, а множество крайне полезных функций. Они особенно актуальны для работы с большими объемами данных, что важно для дата-саентистов. Вот два примера, с которых стоит начать, — это функции sub () и findall ().
import re
re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
['foot', 'fell', 'fastest']
re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat')
'cat in the hat'
Комментарий Алексея:
При написании любых regex в коде придерживаться следующих правил:
- re.compile. Использовать re.compile (или его аналог в других языках) для любых более менее сложных и длинных regex.
- Избегать многократного вызова re.compile на один и тот же regex.
- Писать подробные регулярные выражения используя дополнительный аргумент re.VERBOSE. При re.compile использовать флаг re.VERBOSE (или его аналог в других языках) писать regex в несколько строк с комментариями о том что происходит. Смотри документацию по ссылкам тут и тут.
Пример:
компактный вид
pattern = '^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$'
re.search(pattern, 'MDLV')
Подробный вид
pattern = '''
^ # beginning of string
M{0,3} # thousands - 0 to 3 Ms
(CM|CD|D?C{0,3}) # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 Cs),
# or 500-800 (D, followed by 0 to 3 Cs)
(XC|XL|L?X{0,3}) # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 Xs),
# or 50-80 (L, followed by 0 to 3 Xs)
(IX|IV|V?I{0,3}) # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 Is),
# or 5-8 (V, followed by 0 to 3 Is)
$ # end of string
'''
re.search(pattern, 'M', re.VERBOSE)
- Использовать python raw string для записи regex.
- Named capture group для всех capture group, если их больше чем одна (?P...). (даже если одна capture, тоже лучше использовать)
regex101.com отличный сайт для дебага и проверки regex
№6: Math
Это не величайший модуль в истории, но часто он полезен. Математический модуль дает доступ ко всему, от sin и cos до логарифмов. Все это крайне важно при работе с алгоритмами.
import math
Модуль, безусловно, может сэкономить некоторое время, сделав математические операции доступными без зависимостей. В этом примере я продемонстрирую функцию log (), но если вы углубитесь в модуль, то вам откроется целый мир.
import math
math.log(1024, 2)
№7: Statistics
Еще один модуль, который крайне полезен для статистических подсчетов. Он дает доступ к базовой статистике — не такой глубокой, как в случае SCiPy, но и ее может быть достаточно для анализа данных. Alias этого модуля — st, в некоторых случаях — stc или sts. Но, внимание — не scs, это уже alias для Scipy.stats.
import statistics as st
Этот модуль предоставляет множество полезных функций, на которые стоит обратить внимание! Самое замечательное в этом пакете то, здесь нет никаких зависимостей. Давайте оценим некоторые основные статистические операции общего назначения:
import statistics as st
st.mean(data)
st.median(data)
st.variance(data)
№8: urllib
Если многие другие модули из этого списка не очень известны, то urlib — исключение. Давайте импортируем его!
import urllib
Вместо него можно использовать Flask, поскольку он более функционален. Но для большинства базовых функций хватает и возможностей стандартной библиотеки, которая дает возможность не беспокоиться о зависимостях. Конечно, если нужны дополнительные возможности — то в этом случае стоит обратить внимание уже на что-то другое. Но если речь об HTTP-запросе, то urlib сделает то, что нужно.
from urllib.request import urlopen
data = null
with urlopen('http://example_url/') as response: data = response
Модуль urlib — то, что я крайне рекомендую изучить дополнительно.
№9: datetime
Еще один отличный пример инструмента, который довольно часто встречается в научных вычислениях, — это тип «дата и время». Очень часто у данных есть отметки времени. Иногда они даже являются прогностической функцией, используемой для обучения модели. Этот модуль часто используется с алиасом dt:
import datetime as dt
Теперь мы можем создавать типы даты и времени и работать с типичным синтаксисом даты и времени со свойствами, включая год, месяц и день. Это невероятно полезно для переформатирования, анализа и работы с отдельными разделами дат в ваших данных. Давайте посмотрим на некоторые основные функции этого пакета:
import datetime as dt
now = dt.date.today()
print(now.year)
print(now.month)
№10: zlib
Последний участник этого списка — модуль zlib. Это универсальное решение для сжатия данных с использованием языка программирования Python. Модуль крайне полезен при работе с пакетами.
import zlib
Наиболее важные функции здесь — compress() and decompress().
h = " Hello, it is me, you're friend Emmett!"print(len(h))
t = zlib.compress(h)
print(len(t))
z = decompress(t)
print(len(z))
В качестве вывода скажу, что программирование на Python иногда кажется сложным из-за большого количества зависимостей. И стандартная библиотека языка позволяет частично избавиться от этой проблемы. Кроме того, стандартные инструменты Python позволяют экономить время, уменьшить объем кода и сделать его более читаемым.
===========
Источник:
habr.com
===========
===========
Автор оригинала: Emmett Boudreau
===========Похожие новости:
- [Учебный процесс в IT, Научно-популярное, Биотехнологии] Биоинформатика: лекции онлайн-школы 2020
- [Python, Google Cloud Platform] Выжать максимум: Cloud Composer как fully-managed решение для Airflow
- [Тестирование IT-систем, Программирование, Java, Тестирование веб-сервисов] AspectJ в автоматическом тестировании — несколько практических примеров
- [IT-инфраструктура, Машинное обучение, Искусственный интеллект, Финансы в IT] Как машинное обучение позволило Dropbox экономить ежегодно 1,7 миллиона долларов (перевод)
- [Учебный процесс в IT] Для российских школьников закупят квесты, симуляторы и подкасты
- [Python, Data Mining, API, Big Data] Как лайкать четыре тысячи девушек в час
- [Управление разработкой, Управление персоналом, Карьера в IT-индустрии, IT-компании] Почему лучше работать в B2B-проектах: неожиданные факты о разработке в B2B и B2C
- [Программирование, Управление разработкой, Управление проектами, Подготовка технической документации] Docs as Code. Часть 2: получаем документацию из кода
- [Ненормальное программирование, Математика, Научно-популярное, Старое железо] 12-минутный Мандельброт: фракталы на 50-летнем мейнфрейме IBM 1401 (перевод)
- [Учебный процесс в IT, IT-эмиграция, Карьера в IT-индустрии] Диплом IT-специалиста в разных странах: особенности эвалюации
Теги для поиска: #_python, #_programmirovanie (Программирование), #_uchebnyj_protsess_v_it (Учебный процесс в IT), #_python, #_obuchenie (обучение), #_programmirovanie (программирование), #_blog_kompanii_skillbox (
Блог компании Skillbox
), #_python, #_programmirovanie (
Программирование
), #_uchebnyj_protsess_v_it (
Учебный процесс в IT
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 11:21
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Те, кто работает с Python, знают, что этот язык хорош благодаря своей обширной экосистеме. Можно даже сказать, что язык программирования не выделялся бы ничем особенным, если бы не его замечательные пакеты, которые добавляют новые функции к основным. В качестве примера можно привести NumPy. Инструменты работы с матрицами хороши и в базовом Python, но использование NumPy улучшает все во много раз. Кроме того, у этого языка есть несколько крутых возможностей, которые делают его еще более функциональным. Используя эти возможности, вы можете уменьшить количество зависимостей, освободить время и упростить сам процесс разработки. Давайте посмотрим, что это за возможности. Кстати, свои советы по некоторым функциям добавил Алексей Некрасов — лидер направления Python в МТС, программный директор направления Python в Skillbox. Чтобы было понятно, где перевод, а где — комментарии, последние мы выделим текстом. №1 lambda Я как-то написал целую статью о том, почему lambda делает Python оптимальным языком программирования для статистических вычислений. Благодаря этой функции математические операции можно применить практически к любому типу данных, используя не целые функции, а оценку выражений. Она позволяет вводить определения в глобальном масштабе, а также использовать functional-like синтаксис и методологию, причем на языке, у которого все еще есть структура классов. Все это позволяет сэкономить время в ходе написания программы, сохранить ресурсы и сделать код более лаконичным. Более того, lambda дает возможность использовать такие методы, как apply() для быстрого применения выражений ко всем подмножествам данных. Для дата-сайентиста, да и не только для представителей этой профессии, подобные возможности крайне полезны. Синтаксис выглядит следующим образом. Начинаем со значения, равного возвращению lambda-выражения, затем следует переменная, которую мы хотели бы предоставить в качестве позиционного аргумента. После этого выполняем операцию, используя этот аргумент в качестве переменной: mean = lambda x : sum(x) / len(x)
Теперь мы можем осуществить вызов, как и в случае с любым другим методом в Python: x = [5, 10, 15, 20]
print(mean(x)) Комментарий Алексея:
Будьте аккуратнее с lambda, чтобы не ухудшить читаемость кода. Вот пара советов: Из PEP8. Всегда используйте оператор def вместо оператора присваивания, который связывает лямбда-выражение напрямую с идентификатором: Правильно: def f (x): return 2 * x
Неправильно: f = lambda x: 2 * x
Если длина lambda выражения больше 40 символов, то скорее всего вы засунули в одну строчку кода слишком много логики и она стала нечитабельна. Так делать не стоит, лучше вынести в отдельную функцию. №2: Shutil Модуль Shutil — один из наиболее недооцененных инструментов в арсенале Python. Он включен в стандартную библиотеку, и может быть импортирован так же, как и любой другой модуль в языке: import shutil
Что же делает shutil? На самом деле, это интерфейс высокого уровня для языка программирования Python, в отношении файловой системы вашей ОС. Эти вызовы часто выполняются с использованием модуля os, об shutil не стоит забывать. Вероятно, вам приходилось перемещать файл из каталога в каталог при помощи скрипта, проделав для этого массу утомительной работы, верно? Shutil решает эти классические проблемы с файлами и таблицами размещения (allocation tables) при помощи высокоуровневого решения. Это — ключ для экономии времени и ускорению операций с файлами. Вот несколько примеров высокоуровневых вызовов, которые предоставляет shutil. import shutil
shutil.copyfile('mydatabase.db', 'archive.db') shutil.move('/src/High.py', '/packages/High') №3: glob Возможно, glob и не такой классный, как shutil, плюс он и рядом не стоял с lambda в плане полезности. Но он незаменим в некоторых случаях. Этот модуль используется для поиска директорий для wildcards. Это означает, что его можно использовать для агрегирования данных о файлах на вашем ПК и их расширениях. Импортируется модуль без проблем: import glob
Я не уверен, есть ли у этого модуля еще функции, но glob() — то, что нужно для выполнения поиска файлов. В ходе поиска используется синтаксис Unix, т.е. т.е. *, / и т. д. glob.glob('*.ipynb')
Эта строка возвращает все имена файлов соответствующих указанному запросу. Использовать функцию можно как для агрегирования данных, так и просто для работы с файлами. №4: argparse Этот модуль предоставляет надежный и глубокий метод анализа аргументов командной строки. Многие инструменты разработки используют эту концепцию, работать со всем этим можно при помощи командной строки Unix. Отличный пример — Python Gunicorn, обрабатывающий переданные аргументы командной строки. Для начала работы с модулем его нужно импортировать. import argparse
Затем, чтобы получить возможность работать с ним, строим новый тип, это будет парсер аргументов: parser = argparse.ArgumentParser(prog = 'top',
description = 'Show top lines from the file') Ну а теперь мы добавляем новые аргументы в наш парсер. В этом случае создаем аргумент, который можно передать для определения количества строк, которые мы хотим вывести для каждого файла: parser.add_argument('-l', '--lines', type=int, default=10)
Здесь добавлено несколько аргументов ключевого слова, один из которых предоставит тип данных, который передается для этого аргумента, а другой — значение по умолчанию, когда файл вызывается без этого аргумента. Теперь мы можем получить аргументы, вызвав функцию parse_args () для нашего нового типа парсера аргументов: args = parser.parse_args()
Теперь мы можем вызвать этот файл Python для компиляции, а также легко предоставить необходимые параметры из Bash. python top.py --lines=5 examplefile.txt
Излишне говорить, что это определенно может пригодиться. Я часто использовал этот модуль при работе с Crontab. Он может запускать скрипты с определенными временными метками Unix. Кроме того, этот сценарий также можно использовать для супервизоров, которые запускают команды Bash без участия пользователя в качестве worker. №5: import re Еще один крайне недооцененный модуль. Модуль re используется для синтаксического анализа строк с помощью регулярных выражений и предоставляет больше возможностей для работы со строками в Python. Сколько раз вы сталкивались с принятием алгоритмических решений на основе функций, которые есть в строковом классе, например str.split ()? Но хватит это терпеть! Ведь регулярные выражения намного проще и их намного проще использовать! import re
Модуль re, в отличие от некоторых других в этом списке, предоставляет не одну, а множество крайне полезных функций. Они особенно актуальны для работы с большими объемами данных, что важно для дата-саентистов. Вот два примера, с которых стоит начать, — это функции sub () и findall (). import re
re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest') ['foot', 'fell', 'fastest'] re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat') 'cat in the hat' Комментарий Алексея:
При написании любых regex в коде придерживаться следующих правил:
Пример: компактный вид pattern = '^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$'
re.search(pattern, 'MDLV') Подробный вид pattern = '''
^ # beginning of string M{0,3} # thousands - 0 to 3 Ms (CM|CD|D?C{0,3}) # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 Cs), # or 500-800 (D, followed by 0 to 3 Cs) (XC|XL|L?X{0,3}) # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 Xs), # or 50-80 (L, followed by 0 to 3 Xs) (IX|IV|V?I{0,3}) # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 Is), # or 5-8 (V, followed by 0 to 3 Is) $ # end of string ''' re.search(pattern, 'M', re.VERBOSE)
№6: Math Это не величайший модуль в истории, но часто он полезен. Математический модуль дает доступ ко всему, от sin и cos до логарифмов. Все это крайне важно при работе с алгоритмами. import math
Модуль, безусловно, может сэкономить некоторое время, сделав математические операции доступными без зависимостей. В этом примере я продемонстрирую функцию log (), но если вы углубитесь в модуль, то вам откроется целый мир. import math
math.log(1024, 2) №7: Statistics Еще один модуль, который крайне полезен для статистических подсчетов. Он дает доступ к базовой статистике — не такой глубокой, как в случае SCiPy, но и ее может быть достаточно для анализа данных. Alias этого модуля — st, в некоторых случаях — stc или sts. Но, внимание — не scs, это уже alias для Scipy.stats. import statistics as st
Этот модуль предоставляет множество полезных функций, на которые стоит обратить внимание! Самое замечательное в этом пакете то, здесь нет никаких зависимостей. Давайте оценим некоторые основные статистические операции общего назначения: import statistics as st
st.mean(data) st.median(data) st.variance(data) №8: urllib Если многие другие модули из этого списка не очень известны, то urlib — исключение. Давайте импортируем его! import urllib
Вместо него можно использовать Flask, поскольку он более функционален. Но для большинства базовых функций хватает и возможностей стандартной библиотеки, которая дает возможность не беспокоиться о зависимостях. Конечно, если нужны дополнительные возможности — то в этом случае стоит обратить внимание уже на что-то другое. Но если речь об HTTP-запросе, то urlib сделает то, что нужно. from urllib.request import urlopen
data = null with urlopen('http://example_url/') as response: data = response Модуль urlib — то, что я крайне рекомендую изучить дополнительно. №9: datetime Еще один отличный пример инструмента, который довольно часто встречается в научных вычислениях, — это тип «дата и время». Очень часто у данных есть отметки времени. Иногда они даже являются прогностической функцией, используемой для обучения модели. Этот модуль часто используется с алиасом dt: import datetime as dt
Теперь мы можем создавать типы даты и времени и работать с типичным синтаксисом даты и времени со свойствами, включая год, месяц и день. Это невероятно полезно для переформатирования, анализа и работы с отдельными разделами дат в ваших данных. Давайте посмотрим на некоторые основные функции этого пакета: import datetime as dt
now = dt.date.today() print(now.year) print(now.month) №10: zlib Последний участник этого списка — модуль zlib. Это универсальное решение для сжатия данных с использованием языка программирования Python. Модуль крайне полезен при работе с пакетами. import zlib
Наиболее важные функции здесь — compress() and decompress(). h = " Hello, it is me, you're friend Emmett!"print(len(h))
t = zlib.compress(h) print(len(t)) z = decompress(t) print(len(z)) В качестве вывода скажу, что программирование на Python иногда кажется сложным из-за большого количества зависимостей. И стандартная библиотека языка позволяет частично избавиться от этой проблемы. Кроме того, стандартные инструменты Python позволяют экономить время, уменьшить объем кода и сделать его более читаемым. =========== Источник: habr.com =========== =========== Автор оригинала: Emmett Boudreau ===========Похожие новости:
Блог компании Skillbox ), #_python, #_programmirovanie ( Программирование ), #_uchebnyj_protsess_v_it ( Учебный процесс в IT ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 11:21
Часовой пояс: UTC + 5