"Теория и практика иногда сталкиваются. Когда это случается, теория проигрывает. Всегда."
© Linus Torvalds.
Забавный способ распаковки |
Оказывается, в пайтон есть способ беспонтовой распаковки сложных, но закономерных итерабельных объектов.
l = [(1, 2, 3), (4, 5, 6), (7, 8, 9), (4, 0, 1)]
for (a, b ,c) in l:
print(f"{a}, {b}, {c}")
1, 2, 3
4, 5, 6
7, 8, 9
4, 0, 1
|
module 'collections' has no attribute 'MutableMapping' |
Кстате, третья джанга не работает с питоном 3.10. Сегодня пробовал установить, получил AttributeError: module 'collections' has no attribute 'MutableMapping'.
Выход: или юзать питон 3.9 + джанга 3.2 или 3.10 + 4.0.
Метки: Django Python AttributeError |
jupyter notebook |
Так, на всякий случай заметочка для себя. Чтобы установить в Линукс jupyter notebook, набираем одну единственную команду:
$ pip3 install notebook
|
Как организовать цикл for i in range(...) в шаблоне Django |
Сегодня столкнулся с такой необходимостью. Чтобы сделать пагинатор, решил замутить цикл в шаблоне Django в духе:
{% for num in range(1, count_of_pages + 1) %}
<a href="/page{{num}}">{{num}}</a>
{% endfor %}
Работать такой код не будет))). Код Python содержащий функции обычно не работает. Но можно очень просто выкрутиться. Из контекста текущего вьюза в месте с остальными переменными шаблону можно передать что-то типа { ..., 'my_range': range(1, count_of_pages + 1)}
. Теперь в шаблоне доступна переменная my_range
. А дальше с ней можно делать то же, что со списками, итераторами и т.п.:
{% for num in my_range %}
<a href="/page{{num}}">{{num}}</a>
{% endfor %}
|
Как добавить новое поле типа DateTimeField в Django |
Ситуация: нужно добавить в модель Django два новых поля с датой и временем - created и last_modified. При чём дата создания (created) должна быть заполнена обязательно по логике здравого смысла, а дату модификации мы хотим изначально оставить пустой, чтобы, например, для новых страниц (записей, заметок, комментариев, чего угодно) выводилось примерно следующее:
Создано: 10.05.2021 в 13:40:28
Отредактировано: Никогда
Есть две проблемы. Первая. У нас на сайте уже есть страницы, при добавлении поля created оно окажется изначально пустым и мы получим ошибку. То есть старым записям нужно назначить некоторую дату. Единственный вариант, который я нашёл, сделать такое поле:
created = models.DateTimeField('Date of creation', default=timezone.now)
default=timezone.now
обязательно без скобок. Если указать default=timezone.now()
, полю будет назначена дата запуска сервера, и у всех новых страниц дата создания (как и время) будут одинаковыми. Если скобки не указать, метод будет вызываться при записи каждой новой строки в таблицу БД и вычислять текущее время.
А вот с полем last_modified другая проблема. Дата в него изначально не записывается, и мы получим ту же ошибку:
django.db.utils.IntegrityError: column "last_modified" contains null values
Есть два простых выхода:
last_modified = models.DateTimeField('Last modified', default=None, null=True, blank=True)
База данных позволит хранить пустые значения. Возможно, этот код будет работать без null=True
, я не пробовал. Но без blank=True
точно будут проблемы.
Второй выход - всё же назначить дату по умолчанию как timezone.now, а при выводе на страницу проверять: если дата модификации совпадает с датой создания, выводить Отредактировано: Никогда.
P.S. подозреваю, что default=None
во втором примере кода тоже ненужен)).
|
Как проверить целостность скачанного Пайтоном файла |
Если качать файлы с помощью Python через хреновое соединение, например - бесплатный VPN, иногда они оказываются недокачаными.
Сравниваем реальный размер с тем, который должен быть получен:
# качаем файл
response = requests.get('адрес_файла_в_сети')
# узнаём требуемый размер
declared_file_size = int(response.headers["Content-Length"])
# проверяем, сколько скачано по факту
real_file_size = len(response.content)
# если всё правильно, записываем файл на диск
if declared_file_size == real_file_size:
with open('имя_файла_на_диске', 'wb') as f:
f.write(response.content)
else:
чего_вы_там_хотите_сделать_ещё))
|
Ключевое слово else в Python |
Ключевое слово else в Python используется как минимум в трёх конструкциях.
В конструкции if ... elif ... else. Тут всё понятно. Если не выполнено ни одно из вышеперечисленных условий, выполняется блок else.
В конструкции try ... except. После try ... except и, возможно, finally можно так же прописать блок else, который выполнится, только если в try не было поймано никакого исключения.
И наконец - в конструкции while. После блока while можно вписать else, который выполнится только если цикл "умер" своей смертью. А если он прерван ключевым словом break, тогда else не выполнится, так как он является частью цикла, а он окончательно прерван.
count = 0
while count < 10:
print(count)
count += 1
if count == 5:
break
else:
print('Цикл завершён')
Последняя строка не будет выполнена, так как цикл оборвётся, когда счётчик станет равным 5.
|
Как перевести римские цифры в арабские в Python |
Ставим модуль roman
$ pip3 install roman
Далее пользуемся методом fromRoman()
Например так:
import roman
print(roman.fromRoman("XVII"))
|
Простой способ вывести на экран список в python |
Оказывается, есть простой способ вывести на экран список в Python без всяких циклов и прочего. То есть вместо:
for item in lst:
print(item)
есть сокращённая запись:
print(*lst)
Во кино).
Таким же образом можно вывести множество, кортеж и ключи словаря.
|
Оператор not в Python |
Оператор not в Python на первый взгляд иногда ведёт себя нелогично. Например,
print([] == False) # выведет False, но:
if not False:
print('not False') # выведет not False
if not []:
print('not []') # выведет not []
То есть пустой список ведёт себя точно так же, как и False, при этом не равняясь ему.
Дело, оказывается, вот в чём. not возвращает True, если ему передано булево значение False, или любое другое, имеющее длину == 0, или же сам 0 (неважно в каком виде: int, float или complex). То есть "пустые" или нулевые значения в конструкции if not ... будут вести себя как False. Может быть удобно для проверки, было ли в ходе выполнения программы, например, в список или словарь добавлено какое-то значение, или нет.
|
Определить, делится ли число в двоичном формате на 3 в Python |
import re pattern = r"(1(01*0)*1|0)*" nums = ['0', '10010', '00101', '01001', 'Not a number', '1 1', '0 0', '10', '1000'] for num in nums: if re.fullmatch(pattern, num) is not None: print("Число:", num)
|
$a = true ? 0 : true ? 1 : 2; |
Читал только что о левоассоциативных и правоассоциативных операторах в PHP. Понравился пример)))))).
$a = true ? 0 : true ? 1 : 2;
Возвращает 2. Сначала завис. Потом дошло.
Вычисляется слева направо.
true ? 0 : true вернуло 0.
0 ? 1 : 2 вернуло 2.
$a = 2.
|
Без заголовка |
Давно тут не был))).
Мало,я думаю, кому интересно, но всё же. Сижу до сих пор в Linux Mint (и доволен). Изучаю web-разработку. Два года. Но времени катастрофически не хватает, потому движется всё очень медленно.
Причина: решил податься в вэб-девелоперы). У нас в городе аж три фирмы, занимающихся этим делом. Одна на WP, одна на Django, одна на Drupal и TYPO3 (хотя недавно добавили в арсенал WP/bedrock). Вот они-то меня грозились взять на работу, если подтяну то и это. Подтянул. Но во время карантина, как известно, с вакансиями сильно не разгонишься.
Чё научился. Два года назад знал html4, немного css и имел представление о JS и PHP. Сейчас юзаю HTML5 очень хорошо, css неплохо, JS на уровне "написать анимированную менюшку, скрыть блок, создать блок, сделать таймер и т.п.", на PHP есть пару самостоятельных проектов. Маленький и очень маленький). Юзаю git, GitHub, Packagist, Composer, немного twig. MySQL на уровне "создать таблицу, записать, удалить, изменить, выбрать строку". Немного регулярные выражения. Немного темизацию в Друпал освоил. Начинаю изучать создание модулей для Друпал.
Из последних впечатлений. Всегда юзал Kate в качестве редактора кода. На днях попробовал Sublime Text. В общем я в оргазме восторге. Kate фтопку. Хотя Sublime Text установлен был давно, но раньше я его не понимал.
Начал я изучение веб-разработки с JS. Он безумно мне понравился просто со старту. Но потом настала пора учить ненавистный PHP. Он бесил меня всегда. И вот чудо. Теперь PHP представляется мне стройным, а JS корявым сучком).
Короче, вот такие вот дела.
|
Без заголовка |
|
Программа |
Вот такое понаписал. Добавить нечего, кроме Qt-морды. Но это потом, когда комп будет.
#-*-coding:utf8;-*-
# ver. 2.31
# Программа рассчитывает скорость или время свободного падения из пользовательского ввода. Автоматически корректирует введенные данные. Например убирает лишние точки, заменяет запятые точками. Если ввод содержит некорректные символы (буквы и пунктуацию), выдаёт ошибку и предлагает повторить ввод.
# Как и все мои программы работает ТОЛЬКО в оффлайне, потому что содержит символы кириллицей.
import math
def finput ():
g = 9.8
a = input("Введите высоту падения в метрах \nили Enter, если хотите вычислить \nскорость по времени: \n> ")
a = zap2point(a)
if len(a) > 0:
h = number_test(a)
if h == "error":
finput ()
else:
h = float (h)
u = math.sqrt(2*g*h)
t = u / g
u2 = u * 3.6
print ("Конечная скорость падения: \n{} м/с \n{} км/ч \n{} м за {} сек.".format (fr(u), fr(u2), fr(h), fr(t)))
else:
a = input("Введите время падения в секундах: \n> ")
a = zap2point(a)
t = number_test(a)
if t == "error":
finput ()
else:
t = float (t)
u = g * t
h = (u * t) / 2
u2 = u * 3.6
print ("Конечная скорость падения: \n{} м/с \n{} км/ч \n{} м за {} сек.".format (fr(u), fr(u2), fr(h), fr(t)))
def number_test (a):
b = ""
# Если число точек в строке больше 1
# запоминаем индекс первой точки.
if a.count (".") > 1:
pindex = a.index(".")
else:
pindex = len (a) + 2
if len(a) == 0:
b = "error"
return b
else:
# Перебираем все символы строки
# Если символ число или точка, продолжаем
# Если символ точка и его индекс больше
# индекса первой точки, пропускаем его
# Если символ не число и не точка -
# обрываем цикл
for char in a:
if char in ("1234567890."):
if char == "." and len (b) > pindex:
continue
b += char
else:
print ("***********************\nОшибка! Введите целое или \nвещественное число, \nнапример 34 или 45.6\n***********************")
b = "error"
break
if b == ".":
print ("***********************\nОшибка! Введите целое или \nвещественное число, \nнапример 34 или 45.6\n***********************")
b = "error"
return b
# Так как питон иногда отображает
# натуральные числа некрасиво, например
# 3.2999999999 вместо 3.3, я написал
# функцию,которая более и менее корректно
# окугляет число перед выводом на экран.
def fr (x):
if x >= 10000:
x = int(math.modf(x)[1])
elif x >= 999:
x = "{:.5}".format(x)
elif x <= 0.0001:
x = "{:.10}".format(x)
elif x >= 99.9:
x = "{:.4}".format(x)
else:
x = "{:.3}".format(x)
return x
# Так как часто при вводе числа хочется
# вместо точки поставить запятую, эта
# функция заменяет все запятые точками
# и удаляет пробелы
# чтобы избежать ошибок при вычислении
def zap2point (h):
y = ""
for char in h:
if char == ",":
char = "."
elif char == " ":
continue
y += char
return y
# собственно, запускаем программу
finput()
|