Categories

Checkio.ORG

Subscribe to Posts

Email:

  • 07May

    Вчера для CheckIO придумали вам новую развлекуху, друзья мои, на эти выходные :)

    Идея развлекухи в том, что надо придумать максимально необычное решение для самой обычной задачи. Например, самое простое из раздела Funny, и проще уже не придумаешь - Funny addition. На вход – массив из 2х интов, а на выходе их сумма. Но функция sum(data) – это же не смешно. Смешнее что-то вроде max(data) + min(data).

    Заходим, пишем свое аморальное решение, и рейтенгуем решения друзей.

    По результатам выложу сюда топ аморальщины. Развлекайтесь и удачных вым выходных :)

    ЗЫ: У нас есть еще прикольные шортсы, но о них уже в другой раз

    Share and Enjoy:
    • Facebook
    • LinkedIn
    • Twitter
    • del.icio.us
    • StumbleUpon
    • MySpace
    • Reddit
    • Digg
    • Google Bookmarks
    • Technorati
    • email
    • Print
    • Sphinn
    • Mixx
    • Blogplay
    • Add to favorites
    • Linkter
    • Live
    • MSN Reporter
    • NewsVine
    • RSS
    • Yahoo! Bookmarks
    • Yahoo! Buzz
    • Yigg
    Rating 3.00 out of 5
    [?]

    Tags: , ,

  • 10Aug

    tolsti_i_tonkiРефакторинг – процесс полного или частичного преобразования внутренней структуры программы при сохранении её внешнего поведения.

    У кого, когда возникает мысль, о том, что пора бы переписать эту часть программы ( этот класс, эту функцию )?

    У меня, это начинается после пятого костыля. Костыль — это добавления не предусмотренной функциональности к объекту. Не предусмотренной изначальной архитектурой либо заложенной расширяемости в ней. О как закрутил. Если просто, то пример. Есть пользователь, к которого есть свойство «группа», возвращающее стринговое имя группы, в которую он входит, через некоторое время оказывается, что пользователь может входить в несколько групп и вы пока ставите костыль, но часть функционала по работе с группами надо будет потом переписать. И как я части видел — «костыльная» практика очень свойственно для изначально не формализованных проектов, когда заказчик точно еще понимает, что он хочет ( или пока не может это ясно выразить, а вы его ясно понять ).

    Делать полный рефакторинг после первого костыля, в таких проектах, дело очень расточительное. Но пометку о том, что в этом месте «костыль» – надо поставить. Добавьте функциональный тест на этот костыль. Когда обилие костылей — мешает вам жить, и перед добавлением нового функционала вы выпиваете корвалола. То пора. Пора делать инспектировать и рефакторить код.

    Но, как мне кажется, каждый программист — после первого месяца серьезного программирования уже знает, что такое рефакторинг. Возможно слово такого еще не знает, но точно знает, что ему это уже хочется.

    Рефакторинг кода может быть связан не только с изначальной архитектурной убогостью. Его проводят после понимания того что «что то у нас все очень тупит» ( хотя тут слово «оптимизация» подходит больше ). В этом случае проводится рефакторинг узкого места программы. Профилировка поможет его определить. Бывает это помогут вам определить и пользователи, просто говоря, в каком месте у них «долго думает». Был свидетелем того, как узкое место программы определяли на глаз. Более того, код которым заменяли «тупящий» – не факт, что работал быстрее. Проверяйте!!! Бенчмарк как и профилировка есть в любом языке программирования. Но это отдельная тема, которую сейчас я обсуждать не буду.

    И самая страшная причина, по которой могут проводить рефакторинг. Начинается примерно с таких слов. «Я тут прочитал одну статью на форуме, так вот там сказали, что лучше юзать вот эту штуку вместо этой. И на сайте у них говорится, что у них все круто и круче них только Чак Норис. Давайте переезжать!». В топку! Холивары оставляем на форумах. Безусловно, когда вы увидите, что место у вас и правда узкое, то эти знания будут вам крайне полезны. Но просто так оптимизировать все подряд — глупо и дорого. Возможно это даже не будет ваше самое узкое место.

    Да. Затянутое получилось введение.

    Вчера у меня день был посвящен рефакторингу одной компоненты системы, относящийся к авторизации пользователя и взаимодействию системы с ним. Т.е. с ядром системы, с его основным функционалом. По ходу этого действа я пытался делать пометки на отдельном листке, чтоб как то формализовать правила для себя, собрать их в отдельную статью и выставить на ваш суд.

    Итак начнем.

    1.Если ваш проект уже запущен у него есть аудитория, то без железобетонного набора тестов пускаться в удивительный мир рефакторинга я крайнее не советую. Если тестов нет, то с начало напишите их.
    2.Пройдитесь по коду (если есть возможность используйте дебаг) с каждой точки входа в программу до точки выхода. И простым языком описываем процедуру взаимодействия с объектом на отдельном листке. Можно также помечать какие свойства или методы связаны с описываемыми действиями — это может быть полезно в выявлении дублирующего кода. Как правило уже в процессе письма я вижу места, программы, которые либо выполняют ненужные телодвижения, дублируют друг друга. Выписываем их на отдельный листок. Вообще я считаю, что даже программисту иногда полезно взять ручку и листочек в руки, хоть сейчас просто море программ и сервисов, которые с легкостью из заменяют.
    3.После того, как вы опишите все это. Словесные описания можно сгруппировать в блоки. Вы сразу видите ( как бы сверху ) на поведение своего объекта, точки соприкосновения с другими объектами. Получается такой процесс, обратный проектирования. Если при проектировании я описания задачи свожу к написанию кода, то тут я код свожу к описанию задачи, которую он выполняет. И выражаю эти блоки уже кодом программы.
    4.Изменяя функцию, я не комментирую ее (полностью или частями) я просто добавляю к ней приставку __OLD и пишу новую без этой приставки это касается и свойств. Если функция переносится в другой объект, то я на против __OLD оставляю комментарий с описанием, куда она была перенесена.
    5.Приставка __OLD также полезна в случае, если вы, в процессе описания, увидили дублирующие функции или свойства. Или почти дублирующие. Одну из функций-близнецов переименовываем и прогоняем тесты. В местах ошибок заменяем на правильную.
    6.После проведенной предварительно описательной работы — написание кода у вас займет в разу меньше времени.
    7.Оставшуюся описательную макулатуру после рефакторинга переведите в документацию.

    Да, и самое главное. На дело лучше идти с утра, когда голова еще светла.

    У меня после описательной работы и кодирования наверно штук 20 функций были искалечены словами OLD, и над ними красовались 3-4 которые теперь были вместо них.

    И помните. Книга считается законченной не тогда, когда нечего больше добавить, а когда нечего больше выкинуть.

    Вот такой опыт. А как проводите это вы? Есть ли у вас какие-то обязательные предварительные условия? Возможно какие-то правила рефакторинга, которые вы используете? Было бы очень интересно услышать еще одно мнение.

    Спасибо за внимание и удачного для.

    Share and Enjoy:
    • Facebook
    • LinkedIn
    • Twitter
    • del.icio.us
    • StumbleUpon
    • MySpace
    • Reddit
    • Digg
    • Google Bookmarks
    • Technorati
    • email
    • Print
    • Sphinn
    • Mixx
    • Blogplay
    • Add to favorites
    • Linkter
    • Live
    • MSN Reporter
    • NewsVine
    • RSS
    • Yahoo! Bookmarks
    • Yahoo! Buzz
    • Yigg
    Rating 3.00 out of 5
    [?]

    Tags: , ,

  • 04Aug

    kombainПоследнее время мучает одна идея. Мне как всегда кажется, что она реально не нова, и если это так, скажите мне, как это дело называется.

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

    Что если проект разделить на 2, или создавать 2 его копии. Один будет для боевого сервера, а второй будет для сервера разработки. И проект для разработки будет отличатся от проекта для боевого только тем, что в него будут включены проверки входных данных для всех блоков программы ( или критичных, или точек взаимодействия модулей ), это бывает полезно, когда несколько человек работает на одним проекта и надо проверять, чтоб один разработки пользовался интерфейсом модуля другого разработчика правильно. Но все эти проверки не нужны на боевом, или не нужны с определенного времени. Т.е. чтоб от них можно было легко избавится и легко включить обратно.

    Так. Надеюсь общую задачу я описал адекватно. Если нет, то возможно из решения вы поймете о чем речь.

    Задача решается на python.

    У python есть массив каталогов, в которых он ищет модуль, как только вы хотите его импортировать. И этот список каталогов можно расширять во время работы программы.

    1. import sys
    2. sys.path.apend('/home/oduvan/list_of_my_cool_modules')

    Python позволяет один и тот же модуль импортировать с разными именами. Т.е. в области видимости, в которую мы импортируем модуль — мы можем дать ему несколько различных имен.

    1. import sys
    2. import sys as new_sys

    И можно все имена из одного модуля импортировать в другой модуль.

    1. from sys import *

    Вот по сути и весь необходимый функционал от python, который необходим для реализации этой идеи. Т.е. предполагаю, что любой другой язык с ООП, который имеет эти возможности может использовать эту идею.

    Решение.

    Модули для боевого сервера — будут включать в себя только функционал, т.е без каких либо проверок. А модули для деволова будут включать только проверки и никакого функционала. В них будут собраны функции, которые будут проверять входных параметры одноименных функций из девелопа. При чем возможности проверок вообще ничем не ограничены.

    Ниже приведена структура каталогов и файлов нашего проекта.

    modules
    	__init__.py
    	develop
    		__init__.py
    		t1.py
    	production
    		__init__.py
    		t1.py
    		t2.py
    run.py
    

    В modules/production собраны все модули для боевого сервера
    В modules/develop модули с проверками данных
    run.py скрипт, в котором они будут использоваться.

    Замете, что в папке modules тоже есть файл __init__.py, т.е. он также будет точкой отсчета для импорта.

    В папке develop есть файл t1.py для тестирования такого же модуля из продакшена, или его части. А также мы видим, что модуль t2 остается без тестов.

    ( Автор просит прощения, за такие без звучные имена, с фантазией у него совсем все плохо )

    Приведу пример модуля t1 из production

    1. def p_name():
    2.     print 'Production'
    3.    
    4. def just_in_prod():
    5.     print 'This just in prod'
    6.  
    7. def sum2(a,b):
    8.     return a+b
    9.    
    10. class A(object):
    11.     def b_prop(self,b):
    12.         return b.prop
    13.  
    14. class B(object):
    15.     def __init__(self,prop):
    16.         self.prop = prop

    функция p_name просто нужна для вывода имени модуля или репозитария, для нас она особой ценности не имеет.
    just_in_prod — тестироваться этой функции проводится не будет
    sum2 — складывает 2 числа. И мы хотим проверить, чтоб это на самом деле были 2 числа.
    Объект класс A имеет метод, который на вход получает один параметр — объект класса B, и возвращает его свойство. Класс B мы также тестировать не будем.

    Как сами уже можете видеть, в модуле нет ни одного слово о тестах. Вы видите чистый функционал.

    Теперь приведу вам пример модуля t1 из develop

    1. from production.t1 import *
    2. import production.t1 as P
    3. def p_name():
    4.     print 'Develop'
    5.     P.p_name()
    6.  
    7. def sum2(a,b):
    8.     if not isinstance(a, (int,float)):
    9.         raise ValueError('a must be int or float')
    10.     if not isinstance(b, (int,float)):
    11.         raise ValueError('a must be int or float')
    12.     return P.sum2(a,b)
    13.    
    14.    
    15. class A(P.A):
    16.     def b_prop(self,b,*args,**kwargs):
    17.         if not isinstance(b, B):
    18.             raise ValueError('first argument must be instance of B')
    19.         return super(A,self).b_prop(b,*args,**kwargs)

    Первые 2 строчки всегда должны быть в модуле тестирования.

    Функция p_name будет чисто информативная ( мы на ней покажем вам порядок импортирования) , и безусловно тестирование без нее лучше обойтись.

    Проверка для функции sum2 и проверка для свойства b_prop из класса A.

    Ну и текст скрипта, который демонстрирует процесс работы и тестирования run.py. Предполагается, что у вас это и будет точкой отсчета для запуска.

    1. import sys
    2. sys.path.append('modules/develop')
    3. sys.path.append('modules')
    4. sys.path.append('modules/production')
    5.  
    6. import t1,t2
    7. t1.p_name()
    8. print '—'
    9. t1.just_in_prod()
    10. t2.in_only_production()
    11. print '—'
    12. o_a = t1.A()
    13. o_b = t1.B('it_s prop')
    14. print o_a.b_prop(o_b)
    15.  
    16. print t1.sum2(1,2)
    17.  
    18. print o_a.b_prop(15)

    В этом скрипте важным является порядок добавления модулей в массив sys.path, ну и то, чтоб эти строчки были самые первые в вашем скрипте.

    Вывод скрипта будет следующий

    Develop
    Production
    ---
    This just in prod
    Only in production
    ---
    it_s prop
    3
    Traceback (most recent call last):
      File "run.py", line 18, in 
        print o_a.b_prop(15)
      File "modules/develop/t1.py", line 18, in b_prop
        raise ValueError('first argument must be instance of B')
    ValueError: first argument must be instance of B
    

    для боевого сервера он будет такой же, только в «шапке» скрипта будет не

    1. import sys
    2. sys.path.append('modules/develop')
    3. sys.path.append('modules')
    4. sys.path.append('modules/production')

    а

    1. import sys
    2. sys.path.append('modules/production')

    В этом случае поменяется только текст ошибки

    Production
    ---
    This just in prod
    Only in production
    ---
    it_s prop
    3
    Traceback (most recent call last):
      File "run.py", line 18, in 
        print o_a.b_prop(15)
      File "modules/production/t1.py", line 12, in b_prop
        return b.prop
    AttributeError: 'int' object has no attribute 'prop'
    

    Я думаю люди, которые часами разбирались в мало понятных ошибках модулей — оценят идею.

    Да, и еще одним плюсом является то, что вы можете делать легко несколько профилей тестирования и легко между ними переключатся, Добавив рядом с папкой develop, что нить типа develop_plusplus, или если вы хотите залить на продакшн тесты, но не хотите тестировать все, а только те чатити, которые подвержены изменения develop_light.

    Я же планирую у себя это использовать для своего сокет сервера. У меня именно так разнесен скрипт run.pay от функциональных модулей. И думаю при запуске его добавить еще параметр -t которому можно будет передать имя профиля тестирования.

    Файлы из примера split_develop.tar

    Вот и все. Жду жесткую критику, предложения по улучшению.

    Спасибо, что дочитали до конца :)

    Share and Enjoy:
    • Facebook
    • LinkedIn
    • Twitter
    • del.icio.us
    • StumbleUpon
    • MySpace
    • Reddit
    • Digg
    • Google Bookmarks
    • Technorati
    • email
    • Print
    • Sphinn
    • Mixx
    • Blogplay
    • Add to favorites
    • Linkter
    • Live
    • MSN Reporter
    • NewsVine
    • RSS
    • Yahoo! Bookmarks
    • Yahoo! Buzz
    • Yigg
    Rating 3.00 out of 5
    [?]

    Tags: , , ,

  • 17Jan

    programmersСтатья Peter Norvig. Она на аглийском, но тот, кто не уверен в языке, или просто боится чтото понять не так, то лучше выбрать свой, в правой панели перечисленны переводы этой статьи на различных языках, есть и русский.

    В статье много хороших и светлых мыслей, даже на всякий случай перечитал несколько раз, но одна меня зацепила более всех.

    “Будьте лучшим программистом в некоторых проектах; будьте худшим в некоторых других. Будучи лучшим, вы сможете проверить свои способности вести проект и внушать другим свои взгляды. Будучи худшим, вы сможете учиться у мастеров и сумеете понять, что им самим не нравится делать (потому что они будут заставлять вас делать это за них). “.

    В тех проектах, которые я сейчас веду – я ведущий. Поэтому буду стараться вклинится в какой нить опенсорс. По крайней мере по проекту Django у меня и правда есть много идей, и в этом проекте есть люди, у которых по настоящему есть чему поучится, и есть вещи, реализация которых мне не всегда понятна, при чем как правило не понятен местами подход и даже иногда реализации этих подходов. Возможно об этом я ещё напишу.

    И ещё хотел предложить вам почитать интересные статьи, Эльдара Мусаева “Как стать хорошим программистом” ( разбита на части 1 2 3 4 ). Очень легко написано, с юмором. А сравнение хакера и программиста при помощи анекдота про пасущихся быков – это просто ПЕРЛ.

    И на последок – чуть более прогматичная статья, из opennet.ru 25 самых опасных ошибок при создании программ.

    Share and Enjoy:
    • Facebook
    • LinkedIn
    • Twitter
    • del.icio.us
    • StumbleUpon
    • MySpace
    • Reddit
    • Digg
    • Google Bookmarks
    • Technorati
    • email
    • Print
    • Sphinn
    • Mixx
    • Blogplay
    • Add to favorites
    • Linkter
    • Live
    • MSN Reporter
    • NewsVine
    • RSS
    • Yahoo! Bookmarks
    • Yahoo! Buzz
    • Yigg
    Rating 3.00 out of 5
    [?]

    Tags: , , ,

  • 08Aug

    с утра проходился по жсной ленте Хабра..

    Ниче так себе ленточка скажу я вам… так вот…

    Их опросик. коменты не нужны.

    Хороший постик о шпорах. Но много хорошего пошло уже в коментах. Вот это больше понравилось про JQ. Но дальше народ прошелся по всем.

    Share and Enjoy:
    • Facebook
    • LinkedIn
    • Twitter
    • del.icio.us
    • StumbleUpon
    • MySpace
    • Reddit
    • Digg
    • Google Bookmarks
    • Technorati
    • email
    • Print
    • Sphinn
    • Mixx
    • Blogplay
    • Add to favorites
    • Linkter
    • Live
    • MSN Reporter
    • NewsVine
    • RSS
    • Yahoo! Bookmarks
    • Yahoo! Buzz
    • Yigg
    Rating 3.00 out of 5
    [?]

    Tags: , , , , ,

   

Recent Posts

Recent Comments

  • Благодарю, начал изучать fabric с вашей статьи....
  • Идея действительно отличная и очень радует то, что подобн...
  • Спасибо...
  • Там четыре круглых кнопочки. Подразумевается, что каждая ...
  • А в чем заключатеся неправильна работа?...