sdfsdhgjkbmnmxc в пальто
[Most Recent Entries]
[Calendar View]
[Friends]
Below are the 20 most recent journal entries recorded in
гинеколог отечественного веб-дизайна's LiveJournal:
[ << Previous 20 ]
| Thursday, December 9th, 2010 | | 2:58 am |
Почему в Django при объявлении модели обязательно стоит задавать ordering
Есть, допустим у нас моделька под названием, скажем BigData. А в объявлении её не стали мы ordering прописывать. Поленились. А ещё мы поленились при запросе сделать явный order_by. И теперь, ленивые мы такие, делаем запрос: objects = BigData.objects.all()Или не .all(), а .filter() чего-то там, не важно. Главное, что у нас есть objects, в котором нету сортировки. Никакой. Вроде бы всё хорошо, но ровно до тех пор, пока мы не захотим сделать, допустим срез. Взять, и поделить: a = objects[:m] b = objects[m:]Всё шикарно, прелестно и замечательно. Срезы разворачиваются в sqlные LIMITы и OFFSETы. И... получается два разных запроса без сортировки. В чём подвох? Если и один и тот же запрос без сортировки делать несколько раз подряд, не факт, что порядок следования элементов будет одинаковый. И значит, делая срез, в большинстве случаев мы получим не две половинки выборки, а 2 подмножества одной выборки: часть элементов будет и там, и там, а часть не попадёт никуда вообще. А разгадка одна. И не "джанга говно", "orm говно", "реляционные базы говно", как могли бы подумать некоторые. Разгадка в том, что любые абстракции текут. Хорошие текут редко. Но когда текут, они могут очень сильно попортить паркет, ковры и всё ценное, что имело неосторожность лежать на полу... | | Wednesday, October 6th, 2010 | | 4:15 pm |
Bad Gateway
Ну кто никогда не видел вот такую ошибку?  Мало того, некоторые даже были виновниками её наличия. А ведь некрасиво и неудобно требовать от пользователя самому жать F5 (ошибка зачастую временная и пропадает через несколько секунд). Может заставить браузер перезагружать страницу самостоятельно? А пользователя займём чем-нибудь движущемся, пусть втыкает, а не нервничает. Открываем конфиг nginxа: ===== error_page 500 502 504 /errorpages/50x.html; =====И пока backend будет возвращать ошибку, пользователь будет наблюдать 50x.html. | | Wednesday, December 23rd, 2009 | | 10:40 pm |
Порой конструкторы бывают однообразны и утомительны:
class A:
def __init__(self, start_date, stop_date, current_date, tasks, resources, constraints):
self.start_date = start_date
self.stop_date = stop_date
self.current_date = current_date
self.tasks = tasks
self.resources = resources
self.constraints = constraints
Можно заменить шило на мыло, избавившись от части " = " (и ухудшив читабельность):
class A:
def __init__(self, start_date, stop_date, current_date, tasks, resources, constraints):
self.start_date, self.stop_date, self.current_date = start_date, stop_date, current_date
self.tasks, self.resources, self.constraints = tasks, resources, constraints
А можно вспомнить про то, что в каждом экземпляре класса есть доступ к его содержимому через свойство __dict__:
class A:
def __init__(self, start_date, stop_date, current_date, tasks, resources, constraints):
self.__dict__.update(vars())
Единственная беда: мы получим таким образом свойство self.self. Но если нас это волнует, тогда мы просто удалим его.
class A:
def __init__(self, start_date, stop_date, current_date, tasks, resources, constraints):
self.__dict__.update(vars())
del self.self | | Tuesday, August 18th, 2009 | | 6:18 pm |
Ситуация result = [] for d in lst: d_copy = dict(d) d_copy['some_key'] = func(d_copy['some_key']) result.append(d_copy)...элегантно заменяется на list comprehension, если вспомнить, что конструктор словарей может принимать несколько аргументов (кажется, я повторяюсь). Т.е. вместо того, чтобы по отдельности сначала создавать копию словаря, а потом менять один из ключей, можно это сделать одновременно: result = [dict(d, some_key=func(d['some_key'])) for d in lst] | | Wednesday, June 17th, 2009 | | 5:16 pm |
Убираем лишнее с прохода
Дано: def is_english(s):
return re.compile('^[a-zA-Z\s]*$', re.IGNORECASE).match(s) compile выполняется каждый раз при вызове. Это плохо. Давайте, сделаем, чтобы было 1 раз: _english_pattern = re.compile('^[a-zA-Z\s]*$', re.IGNORECASE)
def is_english(s):
return _english_pattern.match(s) Теперь всё один раз, но появилась временная переменная, кода стало больше... Ещё мы видим, что функция просто делает проброску к другой функции. А зачем нам лишний кузнец? Итого: is_english = re.compile('^[a-zA-Z\s]*$', re.IGNORECASE).match | | Thursday, May 7th, 2009 | | 4:12 pm |
python. "сложение" словарей
Пусть a и b словари: a = {'aaa': 111} b = {'bbb': 222} Требуется минимумом усилий получить словарь ab, в котором будут элементы обеих словарей. Сложение для словарей не поддерживается и выдает TypeError: "unsupported operand type(s) for +: 'dict' and 'dict'". Решение #1 (в лоб): ab = {} ab.update(a) ab.update(b) Решение #2 (обходной путь, через сложение списков): ab = dict(a.items() + b.items()) Решение #3 (через дополнительные параметры конструктора типа): ab = dict(a, **b) | | Friday, February 20th, 2009 | | 7:36 pm |
# есть такое
[(x + 1) ** 3 + (x + 1) ** 2 + (x + 1) for x in lst]
# хочется как-нибудь так
[k ** 3 + k ** 2 + k for x in lst
where k = x + 2]
# или так
[let k = x + 2 in
k ** 3 + k ** 2 + k for x in lst]
# но нельзя.
# однако, если очень хочется:
[(lambda k = x + 2:
k ** 3 + k ** 2 + k)() for x in lst]
| | Tuesday, January 13th, 2009 | | 6:44 pm |
| | Tuesday, November 18th, 2008 | | 10:16 pm |
Статистика использования браузеров Сайт А. Расчитан на интернет-аудиторию. 1000-500 посетителей в день (будни-выходные). Топ-5 браузеров:
| Firefox | 37 % |
| Internet Explorer | 31 % |
| Opera | 26 % |
| Chrome | 3 % |
| Safari | 2 % |
Сайт Б. Детское издательство. 100-250 посетителей в день (в зависимости от того, есть информационный повод или нет).
Топ-5 браузеров:
| Internet Explorer | 53 % |
| Firefox | 28 % |
| Opera | 14 % |
| Safari | 2 % |
| Chrome | 1,5 % |
Наиболее популярные разрешения экранов, соответственно:
| 1280x1024 | 30 % |
| 1024x768 | 28 % |
| 1280x800 | 15 % |
и
| 1280x1024 | 32 % |
| 1024x768 | 23 % |
| 1280x800 | 17 % |
| | Monday, November 10th, 2008 | | 12:55 am |
| | Friday, October 24th, 2008 | | 12:50 pm |
| | Friday, October 17th, 2008 | | 6:41 pm |
Разделить список на 2 одной сточкой. Python
К примеру, есть список чисел и надо разделить его на два списка: список чётных и список нечётных (а вообще условие деления и исходный список могут быть любыми). Один нюанс: разделить надо одним выражением. lst = range(0, 20) odds, evens = ....Пока придумалось только такое: ( Read more... )Upd: сравнение четырёх разных вариантов: ( Read more... ) | | Monday, September 29th, 2008 | | 11:22 pm |
def create_list():
"""[19, 20, 21, 22, 23, 24, 25, 26] list"""
return range(19, 27)
lst = create_list()
for i, item in enumerate(lst):
if item == 21:
del lst[i]
print lst # [19, 20, 22, 23, 24, 25, 26] -- OK
lst = create_list()
for i, item in enumerate(lst):
if item >= 21:
del lst[i]
print lst # [19, 20, 22, 24, 26] -- немного не то, правда?
А разгадка одна — нечего ходить по коллекции и из неё же попутно выкусывать куски (хотя некоторые так почему-то делают). Нумерация-то меняется...
lst = create_list()
for item in lst[:]:
if item >= 21:
lst.remove(item)
print lst # [19, 20] -- а так работает | | Saturday, September 20th, 2008 | | 10:53 pm |
Вы уж простите, что я достаю свои старые пелёнки и снова в них писаюсь... Но вот вам фп-quicksort на питоне ещё:
def qsort(lst):
return lst and (
qsort([e for e in lst[1:] if e < lst[0]]) +
lst[:1] +
qsort([e for e in lst[1:] if e >= lst[0]])
) or [] | | Wednesday, September 17th, 2008 | | 12:33 pm |
В php есть документированная псевдопеременная $_GLOBALS, которая содержит все глобальные переменные текущего запущенного скрипта. Помимо этого существуют 2 недокументированные псевдопеременные: $_SUPERGLOBALS, которая хранит глобальные переменные на протяжении времени существования одного отдельно взятого интерпретатора, и $_SUPERPUPERGLOBALS, которая хранит переменные всех интерпретаторов php, существующих в видимой вселенной. | | Thursday, March 27th, 2008 | | 10:11 pm |
Опять об сортировку...
Преимущество программирования на языке Haskell по сравнению с императивными языками принято иллюстрировать примерами кода реализации алгоритма быстрой сортировки. Дескать, вот вам программа на Хаскеле: ( Read more... ) | | Tuesday, March 4th, 2008 | | 4:04 pm |
Реализация быстрой сортировки Хоара на Haskellе:
( Read more... )
Те же яйца на PHP с небольшим сахарком в виде 2х функций listTail и listHead. Можно двинутья как в одну сторону, заменив listHead на reset -- и таким образом получив "чистый" пхп, так и в другую -- сделав обёртки для create_function (createComparator), array_merge (createList).
( Read more... ) | | Friday, February 29th, 2008 | | 11:49 am |
Программирование с акцентом "Программирование с акцентом" -- это использование (или попытка использования) привычек, полученных при работе с одним языком, в другом языке.
Попробуем рассмотреть реализацию возврата из функции двух параметров на php 5 с "акцентами" из некоторых других языков. Пример искуственный, ничего полезного не делает, просто возвращает два значения.
// 1. php-акцент
function getTwo() {
return array(
'first' => 111,
'second' => 222,
);
}
$result = getTwo();
print "First: $result[first], second: $result[second]";
// 2. Perl / LISP акцент
function getTwo() {
return array(111, 222);
}
list($first, $second) = getTwo();
print "First: $first, second: $second";
// 3a. C-акцент
function getTwo(&$first, &$second) {
$first = 111;
$second = 222;
}
$first;
$second;
getTwo($first, $second);
print "First: $first, second: $second";
// 3b. C-акцент
class structTwo {
public $first;
public $second;
}
function getTwo(&$first, &$second) {
$struct = new structTwo;
$struct->first = 111;
$struct->second = 222;
}
$struct = getTwo($first, $second);
print "First: $struct->first, second: $struct->second";
// 4. Java-акцент
class TransferObjectTwo {
private $first;
public function getFirst() { return $this->first; }
private $second;
public function getSecond() { return $this->second; }
public function __construct($first, $second) {
$this->first = $first;
$this->second = $second;
}
}
/**
* @return TransferObjectTwo
*/
function getTwo() {
return new TwoTransferObject(111, 222);
}
$obj = getTwo();
print "First: " . $obj->getFirst() . ", second: " . $obj->getSecond();
Поправляйте. | | Wednesday, February 27th, 2008 | | 12:18 pm |
О предупреждениях и объяснениях в интерфейсах web-страниц
Я считаю, что: - предупреждение "внимание! если ты сейчас это сделаешь, то..." лучше вешать НАД группой элементов управления. И помечать привлекающим внимание цветом. - объяснение "внимание! некоторые опции недоступны, потому что..." лучше вешать ПОД группой элементов управления, в которой эти некоторые опции недоступны. Разумеется, группа при этом должна быть небольшой. | | Thursday, January 17th, 2008 | | 11:11 am |
|
[ << Previous 20 ]
|