You are viewing [info]ao_mmm's journal

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
    unzip в Python
    def unzip(lst):
        return zip(*lst)
    Tuesday, November 18th, 2008
    10:16 pm
    Статистика использования браузеров

    Сайт А. Расчитан на интернет-аудиторию. 1000-500 посетителей в день (будни-выходные). Топ-5 браузеров:

    Firefox37 %
    Internet Explorer31 %
    Opera26 %
    Chrome3 %
    Safari2 %

    Сайт Б. Детское издательство. 100-250 посетителей в день (в зависимости от того, есть информационный повод или нет). Топ-5 браузеров:

    Internet Explorer53 %
    Firefox28 %
    Opera14 %
    Safari2 %
    Chrome1,5 %

    Наиболее популярные разрешения экранов, соответственно:

    1280x102430 %
    1024x76828 %
    1280x80015 %

    и

    1280x102432 %
    1024x76823 %
    1280x80017 %
    Monday, November 10th, 2008
    12:55 am
    О воде в текстах
    1) возьмём статью Дмитрий Сатин. Юзабилити Интернет-магазинов. Поиск должен быть! и внимательно прочитаем.

    2) попробуем записать основные мысли текста:
    Read more... )

    3) сравним количество знаков в выжимке и в статье, и узнаем, сколько в тексте воды:
    Read more... )

    Правда, забавно?
    Friday, October 24th, 2008
    12:50 pm
    Страницы-психоделики
    Лёгкий психоделик: http://www.tel-tel.ru/numbers.html
    Сильный психоделик: http://www.arngren.net/
    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
    Заметки на полях. Три расширения для firefox
    https://addons.mozilla.org/ru/firefox/addon/4287 -- SplitBrowser - позволяет разделять окно браузера на несколько независимых "браузеров".
    https://addons.mozilla.org/ru/firefox/addon/3255 -- Cookieswap -- переключение профилей кук.
    https://addons.mozilla.org/ru/firefox/addon/539 -- MeasureIt -- линейка для измерения объектов на странице
[ << Previous 20 ]
About LiveJournal.com