Рубрики
Без рубрики

Бинарные часы – Django Nibbles

Автор оригинала: Arun Ravindran.

Django можно использовать для создания отличных веб-сайтов. Но он также действительно хорош для быстрого решения небольших проблем. Представляем новую серию статей под названием «Django Nibbles» , которая поможет вам изучить один из аспектов Django say Templates с помощью короткой и простой задачи. Вы можете решить проблему самостоятельно или следовать моему пошаговому решению.

В. Создайте страницу, которая отображает двоичные часы, показывающие текущее время (когда страница была загружена).

Например, если время «23:55:02», мы должны увидеть:

○ ○ ○ ○ ○ ○
○ ○ ● ● ○ ○
● ● ○ ○ ○ ●
○ ● ● ● ○ ○

Каждый столбец представляет собой двоичную цифру при чтении сверху вниз. Дополнительные сведения см. На вики-странице двоичных часов .

Функция Django : Просмотры

Отведенное время : 1 час

Вперед, продолжать. Попробуйте сами, прежде чем читать дальше!

A. Мы будем использовать Python 3 (не 2.7) и Django 1.6 для решения этой проблемы. Обе версии являются последними на момент написания.

Настройка проекта

Этот раздел можно пропустить, если вы знаете основы создания проекта в Django (что проще в Django 1.6).

В командной строке Linux (обозначенной подсказкой ‘$’) введите следующее, чтобы создать проект binclock :

$ cd ~/projects
$ django-admin.py startproject binclock
$ cd binclock

Получение текущего времени

Откройте binclock/urls.py и замените все этими строками:

from django.conf.urls import patterns, url

urlpatterns  patterns('',
    url(r'^$', 'binclock.views.home', name'home'),
)

Создайте новый файл binclock/views.py со следующими строками:

from django.http import HttpResponse
from django.utils.timezone import localtime, now

def home(request):
    clock  str(localtime(now()))
    return HttpResponse(clock, content_type"text/plain;)

Функция просмотра home возвращает текущее время в виде обычного текста. Мы импортируем функцию now из django.utils.timezone , чтобы получить текущее время в формате с учетом часового пояса. Вызов localtime преобразует его в часовой пояс, определенный в файле settings.py проекта.

Вызов HttpResponse дает вам низкоуровневый контроль над точной строкой, которую нужно вернуть. в браузер, т.е. первый аргумент. Вы также можете упомянуть content-type , который по умолчанию установлен на HTML, т.е. “text/html ;. Обычный текст достаточно хорош для нашей цели. Мы будем использовать символы Unicode, поэтому нам нужно упомянуть также кодировку .

Попробуйте запустить сервер сейчас:

$ ./manage.py runserver

Если вы откроете браузер и укажете URL-адрес по умолчанию http://127.0.0.1:8000/, вы должны увидеть отображаемую дату и время. Если вы не находитесь в часовом поясе UTC, он может отличаться от вашего текущего часового пояса.

Давайте изменим это на ваш текущий часовой пояс (найдите свой в списке часовых поясов ). Откройте binclock/settings.py , найдите строку, начинающуюся с TIME_ZONE , и измените ее часовой пояс. Поскольку я живу в Бангалоре, моя линия будет выглядеть так:

TIME_ZONE  'Asia/Calcutta'

Теперь обновите страницу браузера, и вы должны увидеть свое текущее время.

Преобразование в двоичный

Мы будем переводить в двоичный формат шаг за шагом. Обратите внимание, что каждая цифра должна быть преобразована в упакованный формат BCD , а не в двоичную форму. Например, 12 в двоичном формате – это 1100, но нам это нужно в форме BCD, то есть 0001 0010.

Приглашение Python будет обозначено “»> “(на самом деле я использовал IPython). Откройте оболочку с помощью команды ./manage.py shell :

>>> def bcd_digit(x):
...     return [(x & 8) >> 3, (x & 4) >> 2, (x & 2) >> 1, x & 1]
... 
>>> bcd_digit(5)
[0, 1, 0, 1]

Здесь мы используем поразрядные операторы Python ‘&’ и ‘»’. Чтобы извлечь четыре крайних правых бита, мы используем битовую маску, а затем сдвигаем результат вправо. Мы можем преобразовать одну десятичную цифру в список двоичных цифр с помощью bcd_digit . Но числа в часах могут содержать до двух цифр.

>>> def bcd_2digits(x):
...     return [bcd_digit(x // 10), bcd_digit(x % 10)]
... 
>>> bcd_2digits(12)
[[0, 0, 0, 1], [0, 0, 1, 0]]

Теперь мы можем преобразовывать двузначные числа. Попробуем преобразовать реальный объект datetime в двоичные цифры.

>>> from datetime import datetime
>>> def bcd_hhmmss(dt):
...     return bcd_2digits(dt.hour) + bcd_2digits(dt.minute) + \
...         bcd_2digits(dt.second)
... 
>>> t = bcd_hhmmss(datetime(2013,11,16,23,55,2))
>>> t
[[0, 0, 1, 0], [0, 0, 1, 1], [0, 1, 0, 1], [0, 1, 0, 1], [0, 0, 0, 0], [0, 0, 1, 0]]

Это близко к желаемому результату. Но строки должны быть преобразованы в столбцы (путем транспонирования). Нам также необходимо преобразовать числа в символы Юникода для лучшего внешнего вида.

>>> char_one = chr(0x25CF)
>>> char_zero = chr(0x25CB)
>>> def disp_unicode(clock_matrix):
...     return "\n".join(" ".join(char_one if p
...                               ) for line in list(zip(*clock_matrix)))
... 
>>> disp_unicode(t)'○ ○ ○ ○ ○ ○\n○ ○ ● ● ○ ○\n● ● ○ ○ ○ ●\n○ ● ● ● ○ ○'
>>> print(disp_unicode(t))
○ ○ ○ ○ ○ ○
○ ○ ● ● ○ ○
● ● ○ ○ ○ ●
○ ● ● ● ○ ○

Функция disp_unicode использует множество уловок Python. Мы можем найти транспонирование любой матрицы с помощью трюка zip (* matrix) . Мы также используем вложенные списки, чтобы перебирать строку за строкой, а затем столбец за столбцом. Встроенный оператор if (также называемый условным выражением ) преобразует биты в красивые символы Юникода.

Наконец, мы привязываем это к нашей функции просмотра в views.py :

def home(request):
    clock  disp_unicode(bcd_hhmmss(localtime(now())))
    return HttpResponse(clock, content_type"text/plain;)

Полный исходный код можно найти на github .

А теперь попробуйте немного насладиться чтением;)

Упражнение для читателя: измените код, чтобы вместо этого отображалась дата в формате «гггг-мм-дд».