Archive for the ‘Code’ Category
Tuesday, February 28th, 2012 |
Долго не писал, был крайне занят в разных проектах, получая madskillz в различных областях программирования. Ну что могу сказать, программировать мне пока нравится больше чем предыдущие занятия SEO. Сама оптимизация канешно весьма полезное умение и имеет скажем так прикладное значение, но я считаю трЪ вебмастер должен уметь собственно делать сайты. Причем не на вордпрессе или на какой-нибудь сраной point-and-click CMS, а уметь писать легковесные, быстрые, заточенные под задачу решения.
Это было интро, собственно переходим к сути статьи. Итак, как правило программист нуждается в редакторе в котором он будет набирать код. Некоторые предпочитают огромный монстроподобные, тяжеловесных, кросплатформенных java-IDE (eclipse, netbeans и т.д.) весь функционал которых как правило не исползуется, в то время лаги gui достаточно ощутимы, кто бы что не говорил. Однако линуксу уже не первый год и на нем существуют достаточно хорошие нэйтивные решения, которым уже по 30 (с хуем) лет, но которые тем не менее активно развиваются и многие предпочитают набирать код именно в этих редакторах, я имею в виду Emacs и Vim. Звезды сложились так что я стал использовать emacs, сначала для того чтобы набирать небольшие программки параллельно с netbeans, затем понял что netbeans мне уже не нужен.
Собственно уже не первый раз устанавливая Ubuntu на разные компьютеры я сталкиваюсь с необходимостью заново создавать рабочее окружение Emacs’а.
И вот в очередной раз решил записать последовательность действий.
Установка и настройка Emacs для разработки на Python

Для начала все свои настройки и плагины я храню в репозитории на гитхабе, который доступен мне из любой точки мира где есть интернет.
Сперва поставим сам емакс, открываем терминал и пишем:
sudo apt-get install emacs
Поставим гит если его нет (а если система совсем новая то нужно еще перед этим сделать sudo apt-get update)
user@machine:~$ sudo apt-get install git-core
Coбственно осталось кланировать репозиторий куда-нибудь в папке юзера.
user@machine:~$ cd ~
user@machine:~$ mkdir temp
user@machine:~$ cd temp
user@machine:~$ git clone https://github.com/istinspring/iemacs
Затем копируем файлы конфигурации в папку юзера
user@machine:~$ cp -r iemacs ~/.emacs.d
user@machine:~$ cd iemacs
user@machine:~$ cp .emacs ~/.emacs
Если сейчас запустить Emacs он покажет ошибку, т.к. нет нужных плагинов.
Ставим их:
user@machine:~$ sudo apt-get install pymacs
user@machine:~$ sudo apt-get install python-ropemacs
user@machine:~$ sudo apt-get install python-mode
Все. Остальные плагины уже установленны в папочке. Я использую минимальный набор плагинов, хотя можно при желании наворотить очень много всякого, и проверку синтаксиса на лету и соответствие PEP8.
YASnippets – сниппеты. очень удобно вбить туда повторяющиеся паттерны кода. Например у меня вбиты сниппеты для быстрого создания скелета паука – grab:spider.
Autocomplete – тут и сказать нечего автокомплит. Так же ускоряет процесс набивание кода.
Далее можно начать разбираться и потихоньку выстраивать удобное окружение для работы с кодом.
Posted in Code, Linux, Notes, Python | 4 Comments »
Tuesday, June 7th, 2011 |
Многим очень нравится дизайн гитхаба, один из элементов, на который стоит обратить внимание отдельно это – кнопки (сининькие такие). Такие динамические кнопки смотрятся очень круто и с легкостью впишутся в интерьер любого сайта. Вообщем ближе к делу: в основе github buttons лежат 3и технологии – CSS, HTML и jQuery. Архив с ксс стилями и js можно скачать CSS3 Buttons, посмотреть как это выглядит – github style кнопки.
Posted in Code, html & css, OpenSource | No Comments »
Saturday, June 4th, 2011 |
Сервис GitHub предоставляет возможность размещать свой open source код бесплатно и использует для этого достаточно сложную систему контроля версий – git. Приватные репозитории на гитхабе доступны только для оплаченных аккаунтов. А что делать если хотелось бы скрыть код, но в то же время использовать все удобства которые предоставляют системы контроля версий?
Есть 2а пути, простой и сложный. Простой – воспользоваться сервисом который предоставляет bitbucket или поднять на сервере свой репозиторий кода.
Битбакет это примерно такая же социальная сеть для кода как и гитхаб, с той разницей что заместо git используется mercurial или hg, работать с которым как мне показалось проще. Плюс он позволяет абсолютно бесплатно создавать приватные репозитории для своих проектов код которых вы не хотите транслировать на весь веб.
Собственно, старт проекта выглядит примрно так (сначала нужно создать приватный репозиторий на bitbucket):
Start new bitbucked project
create folders etc.
>> hg init
>> hg add
make “hgrc” file in .hg folder with :
[paths]
default = https://bitbucket.org/user/project
[ui]
username = Your Name
verbose = True
also will be good idea to put .hgignore file :
# use glob syntax.
syntax: glob
# Common
*.pyc
*.pyo
*.swp
*.swo
*.orig
*~
# Project specific
.env
pip-log.txt
>> hg commit -m “Here we go”
>> hg push
.hgignore файл который задаёт как бы говорит hg не помещать в репозиторий разные ненужные файлы – бэкапы которые создаёт редактор кода, невидимые файлы и т.д.
На текущий момент кол-во приватных репозиториев на Bitbucket.org не ограничено – пользуйтесь =)
Posted in Code, Notes | 1 Comment »
Tuesday, May 31st, 2011 |
Давным-давно, в доисторические времена, программистам приходилось изучать и конструировать сложные запросы к реляционным базам данных, что несколько усложняло работу с базой данных. А когда появилось ООП увязать SQL запросы, код и новый стиль программирования стало еще сложнее. Впрочем, многие пхп проекты как-то обходятся и без ORM, что несомненно свидетельствует о высоком скилле и безмерном трудолюбии разработчиков.
Итак что же такое ОРМ (orm)? Это не более чем абривиатура от Object Relational Mapping и по простому обозначает работу с таблицами баз данных как с объектами языка программирования. ОРМ является по сути дела высокоуровневой надстройкой над драйвером БД который переводит ваши запросы в язык SQL; может быть где-то и проигрывая в производительности, но зато существенно упрощая разработку и поддержку проектов, делая работу с базами данных простой и понятной.
ORM (англ. Object-relational mapping, русск. Объектно-реляционное отображение) — технология программирования, которая связывает базы данных с концепциями объектно-ориентированных языков программирования, создавая «виртуальную объектную базу данных». Существуют как коммерческие, так и свободные реализации этой технологии.
На текущем этапе своей карьеры программиста я использую sqlite практически в каждом скрипте, это гораздо удобнее и быстрее чем работать с кучей текстовых файлов. Если возникает потребность в редактировании данных – нет проблем существует отличный плагин для FF – http://code.google.com/p/sqlite-manager/
Итак к делу. Для питона есть отличная реализация ORM с подробнейшей документацией – SQLAlchemy
Базово работа с БД выглядит так :
# -*- coding: utf-8 -*-
from sqlalchemy import create_engine
from sqlalchemy import MetaData
from sqlalchemy.orm import mapper
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, Text, String
Base = declarative_base()
# определяем формат таблицы в БД.
# как бы пост для блога.
class CData(Base):
__tablename__ = 'cdata'
id = Column(Integer, primary_key=True)
url = Column(String)
image = Column(String)
title = Column(String)
text = Column(Text)
def __init__(self, url, image, title, text):
self.url = url
self.image = image
self.title = title
self.text = text
def __repr__(self):
return "CData '%s'" % (self.url)
db_engine = create_engine('sqlite:///data.db', echo=True)
# создадём таблицы
Base.metadata.create_all(db_engine)
# начинаем новую сессию работы с БД
Session = sessionmaker(bind=db_engine)
session = Session()
# таким образом можно добавить новый элемент
new_element = CData("http://blog.com", "http://coolpix.com/img434.jpg", "Nice Post", "Mark spomoni as a faggot")
session.add(new_element)
# посмотрим что уже есть в базе данных
for instance in session.query(CData).order_by(CData.id):
print instance.title
# совершаем транзакцию
session.commit()
Как видите все достаточно просто. Работать с базой данных становится так же легко и естественно как и со структурами языка программирования. В современных фрэймворках для разработки сайта так или иначе используется ОРМ, в джанге это своя реализация django-orm, но во множестве других, таких как flask, pyramids используется как раз SQLAlchemy.
Дополнительные материалы.
Еще одна хорошая статья на русском языке SQLAlchemy: как втянуться
Официальная документация SQLAlchemy
Posted in Code, Python | No Comments »
Saturday, May 21st, 2011 |
Многие (почти все) используют такую замечательную библиотеку как curl (ну, или в нашем случае pycurl), работать с ней конечно можно – но не слишком удобно. Приходится думать о разных вещах – куках, установке параметров и т.д. а ведь это время и в конечном итоге – деньги. Как правило, на определенном этапе многие пишут свои “функции” разной степени кривости облегчающие работу с curl’ом .
Однако грамотные программисты предпочитают реюзать чужой код и не изобретать колесо, особенно в том случае если он хорошо написан и часто обновляется.
(установка в убунте – sudo pip install grab)
Grab идеально подходит для большинства типичных задач (парсинг, регистрации), фактически освобождая программиста от рутины прямой работы с курлом и значительно сокращает размер кода. Я бы сказал, что Grab в какой-то степени эмулирует браузер (естественно без js). Итак, что внутри?
- Отправка разных HTTP запросов
- Обработка HTTP ответа
- Парсинг и заполнение HTML форм
- Работа с HTML DOM через XPath.
- XPath для обхода html
Использование XPath сильно упрощает задачу выбора элементов, это гораздо более удобно чем иметь дело с мутными регулярками.
Более подробно про XPath - http://www.w3schools.com/xpath/default.asp
В качестве примера – простой код.
# выделяем каждый элемент td с классом "postbody"
for item in document.xpath('//td[@class="postbody"]//'):
print item.text
Документация по Grab достаточно подробна, примеры использования тут и тут (в этих примерах граб создается в объекте parser). Как орудовать самим грабом можно посмотреть тут (парсинг форума), пример не рабочий, сразу предупреждаю, служит только для наглядной демонстрации того как можно его использовать.
Posted in Code, OpenSource, Python | No Comments »
Sunday, May 8th, 2011 |
Решил потратить свободное воскресенье на написание чего-нибудь интересного, размять мозги, освоить какие-нибудь новые приемы, короче говоря разбавить рутину повседневных дел. Задача достаточно тривиальна – написать аналог Hello World используя генетические алгоритмы.
Выложил код на github – Hello World генетическими алгоритмами. Там же лог где можно посмотреть как происходит решение задачи.

Что представляют собой эти генетические алгоритмы? Они решают задачи точно так же как это делает природа, т.е. через “естественный отбор”, соответственно критерии этого отбора должны быть достаточно просто вычисляемы – в моём случае это так называемая fitness функция которая посимвольно сравнивает решение с оригинальной строкой, чем лучше решение – тем ближе выход функции к нулю.
def fitness(dnk, goal):
f = 0
for index, gene in enumerate(dnk):
if gene != goal[index]:
f -= 1
return f
Решение задачи представляется в виде вектора значений [a, b, c, d, ..., x] (в нашем случае это строка) длина которого известна, я обернул это в класс методы которого предоставляют интерфейс для взаимодейтсвия (class GeneticCode), на начальном этапе создаётся “популяция” (скажем 100) этих векторов инициализируемых случайными значениями.
self.pool = [GeneticCode(goal=goal) for item in range(self.pool_size)]
Затем fitness функция делает оценку каждого вектора популяции в коде, и далее лучшие образцы (скажем 10% от всей популяции) переходят на следующий круг. Существуют разные вариации генетических алгоритмов, кто хоть немножко разбирается в биологии и знает как происходит естественный отбор без труда могут придумать различные улучшения. Напоминаю, на данный момент у нас, после “естественного отбора” осталось 10% от популяции, где-то нужно взять остальные 90%, я решил на этом этапе провести “скрещивание”, т.е. различные простейшие рекомбинации исходных векторов данных (одна часть берется от одного вектора, другая от второго и в результате получается, что-то новое). Детали этого этапа реализованы в методе def darvin(self, winners=0.1) класса GenePool.
Далее происходит “эволюция”, т.е. кажый вектор испытывает какие-то случайные мутации (не затрагивая те элементы которые уже совпадают с оригинальной строкой). Затем опять приходит старик Дарвин, выбирает лучшие решений и процесс начинается заново. И так до тех пор пока решение не будет найдено. Если строка достаточно длинная + популяция мала и слишком много решений проходит отбор – генетический алгоритм может работать очень долго, поэтому неплохо будет ограничить кол-во итераций, скажем 1000 будет вполне достаточно.
Собственно классический “Hello world” получился примерно так (каждая строчка – лучший результат на каждом шаге) :
s(_soclbi!P*
{k&soclbil^!
oiYloC>otPC!
Evlso$>oil^!
EvlmoC>oild!
oil!oC>orld!
?vlloC>orld!
?elloCqorld!
GelloCqorld!
GelloCqorld!
Tello qorld!
oello qorld!
Tello world!
Tello world!
Tello world!
Hello world!
Естественно я только немного коснулся этой темы, спектр применений генетических алгоритмов достаточно широк, в том числе их используют совместно с нейросетями.
- Оптимизация функций
- Оптимизация запросов в базах данных
- Разнообразные задачи на графах (задача коммивояжера, раскраска, нахождение паросочетаний)
- Настройка и обучение искусственной нейронной сети
- Задачи компоновки
- Составление расписаний
- Игровые стратегии
- Теория приближений
- Искусственная жизнь, проекты типа EvoGrid
- Биоинформатика (свертка белков)
Для тех кто хочет попробовать, есть уже готовые библиотеки для python которые избавят вас от рутины написания лишнего кода.
http://www.freenet.org.nz/python/pygene/
http://pyevolve.sourceforge.net/
Posted in Code | No Comments »
Tuesday, March 22nd, 2011 |
Очень часто нужно обработать файл и удалить дубли. Особенно это актуально при работе с кейвордами и урлами. Самый быстрый (без шуток!) способ сделать это – использовать следующий скрипт.
# -*- coding: utf-8 -*-
__author__ = "istinspring"
__version__ = "1.0"
import os
import sys
import time
import logging
from optparse import OptionParser
logger = logging.getLogger('uniqkeylist')
def uniq(seq):
"""The fastest way to unique list"""
seen = set()
seen_add = seen.add
return [ x for x in seq if x not in seen and not seen_add(x)]
def main():
usage = '%s [options] [source]' % sys.argv[0]
parser = OptionParser(usage)
parser.add_option('-d', '--dst', default='',
help='redirect logs to file')
parser.add_option("-l", "--log", default="-",
help="Write logs to file (default: stdout)")
opts, args = parser.parse_args()
# setup logging
if opts.log == "-":
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
else:
logging.basicConfig(stream=opts.log, level=logging.DEBUG)
if args:
src = os.path.abspath(args[0])
if not os.path.isfile(src):
logger.info("Can't locate file")
sys.exit(1)
else:
logger.info("Enter source filename")
sys.exit(1)
# open source file
try:
with open(src, "r+") as f:
lines = f.readlines()
except IOError:
logger.info("Can't open file")
sys.exit(1)
result = uniq(lines)
logger.info("In\t:\t{0}".format(len(lines)))
logger.info("Out\t:\t{0}".format(len(result)))
dst = opts.dst or (os.path.splitext(src)[0] + ".unq")
# save result
try:
with open(dst, "w+") as f:
for item in result:
f.write(item)
except IOError:
logger.info("Can't save file")
sys.exit(1)
start_time = time.time()
main()
print "Elapsed time:\t%s" % (time.time() - start_time)
использовать python scriptname.py имя файла
Posted in Code, Python | 2 Comments »
Thursday, March 3rd, 2011 |
Вообщем удаленные репозитории это очень хорошо. Во первых появляется какая-то строгость в работе, во вторых безопасность данных и удобство управления, список можно продолжить, но собственно, думаю, основная мысль понятна : “репозитории это хорошо”. К сожалению GitHub бесплатно предоставляет только открытый репозитории, т.е. если вы не хотите чтобы код вашего проекта смотрел кто-то еще придется заплатить кэш, что не всегда целесообразно. Однако bitbucket.com позволит вам абсолютно бесплатно содержать 5 закрытых репозиториев кода.
Резюмирую выше написанное – GitHub хорошо подходит для OpenSource проектов.
Как добавить файлы на github?
Теперь расскажу как это сделать. На примере небольшой утилиты которая разбивает текст на предложения : textsplitter.py
Для тех кто еще не зарегистрировался и не создал ключи для гитхаба ранее была статья :
Работа с Github. Генерация SSH ключей.
На гитхабе создаем новый репозиторий – New Repository
Далее все просто. На своей рабочей Linux машине пишем следующее :
$ mkdir Utils # создаем папку Utils
$ cd Utils # заходим туда
$ git init # инициализируем гит
$ touch README # создаем ридми файл
# каким нибудь редактором пишем в этот файл пару строк о проекте или оставляем пустым
$ git add README # добавляем ридми в список коммитов
$ git commit -m 'first commit' # проводим первый коммит, с комментарием к нему
До этого момента все действия были совершены локально. Настало время присоединится к гитхабу и применить изменения которые были проведены на локальной машине.
$ git remote add origin git@github.com:username/Utils.git # связываем локальный прокт с репозиторием на гитхабе
$ git push origin master # применяем изменения попросят ввести пароль который вы задали для ключей.
# если ключи генерировали под root юзером нужно писать sudo git....
Теперь таким же образом можно создавать файлы, добавлять их в проект (git add filename), делать коммиты, загружать новые версии и т.д.
Все теперь можно заходить GitHub и смотреть что получилось.
Posted in Code, social networks | No Comments »
Monday, December 13th, 2010 |
Как получить список всех папок и файлов в определенной директории? Очень просто – используя функцию os.walk()
import os
def getsubs(dir):
# get all
dirs = []
files = []
for dirname, dirnames, filenames in os.walk(dir):
dirs.append(dirname)
for subdirname in dirnames:
dirs.append(os.path.join(dirname, subdirname))
for filename in filenames:
files.append(os.path.join(dirname, filename))
return dirs, files
Posted in Code, Python | 2 Comments »
Sunday, December 12th, 2010 |
Наверняка многие из вас знают как организуется работа нескольких человек над одним проектом с помощью систем управления версиями. В наши дни технология улучшилась на столько, что появился отдельный вид веб сайтов – хостниги для проектов. Один из них – github основанный на системе контроля версий git.
что внутри?
Можно создать аккаунт, фалловить другие проекты, делать коммиты. Размещение OpenSource проектов абсолютно бесплатно, но есть возможность сделать приватный проект (за $). Вообщем нет лучше места для храниения и поддержки своего OpenSource кода. Так же думают ребята из :
Расчет прост – выкладывать части своих проектов которые могут пригодится другим, при этом получая поддержку коммунити и сообща доводя компоненты до совершенства.
Там же можно найти массу готового кода, чтобы каждый раз не изобретать велосипед.
Как начать свой проект?
Практически все серьезные девелоперы сидят на Linux.
Для начала вам понадобится сам git.
http://help.github.com/linux-git-installation/
sudo apt-get install git-core
я поставил только git-core. далее нужно сгенерировать ssh кеи.
http://help.github.com/linux-key-setup/
# идем в папку где должны хранится ключи
$ cd ~/.ssh
# смотрим есть ли файлы типа id_rsa, id_dsa или identity
ls
# если нет - генерируем новые
$ ssh-keygen -t rsa -C "youmail@gmail.com"
Я несколько раз создавал удалял, так что можно снести если у вас уже есть ключи но вы что называется don’t give a fuck (т.е. не знаете откуда они и зачем). предварительно лучше всего все же скопировать то что есть в отдельную папку. На всякий случай. Мне еще пришлось скопировать ключи в /root/.ssh (создавал в /home/(youruser)/.ssh)
Теперь нужно добавить свой public key в https://github.com/account. Public Key находится в файле id_rsa.pub – скопировать его в clipboard можно с помощью xclip :
$ sudo apt-get install xclip
$ cat ~/.ssh/id_rsa.pub | xclip -sel clip
Тестируем что получилось :
$ ssh git@github.com
....
ERROR: Hi tekkub! You've successfully authenticated,
but GitHub does not provide shell access
Connection to github.com closed.
Если все окей можно приступать к созданию проекта. Если нет – troubleshooting common issues
Posted in Code, social networks | 1 Comment »
Sunday, December 12th, 2010 |
Когда-нибудь нужно начинать… Вчера открыл счет, зарелизив небольшую библиотеку в OpenSource. Это обертка API сервиса Mag.ma который является чистой воды машапом – агрегатором видео с различных источников, которые предоставляет API.
Mag.ma API Python на GitHub

Реализованы следующие интерфейсы.
- search – поиск видео по кею. пока не работает.
- info/video – информация о видео
- embed – получить embed код для видео
- thumbnail – получить thumbnail для видео
но самое интересное
- leaderboard – получить список топ видео за определенный интервал
- mustwatch – список горячих видео которые жарят прям сейчас
- channel – информация о канале включая видео по категориям.
Вполне можно использовать этот модуль для наполнения своих Entertainment сайтов.
Posted in Code, OpenSource | No Comments »
Sunday, December 5th, 2010 |
В рамках программы публикации полезных сниппетов (кусочков кода). Распространенная задача – нужно собрать все URL со страницы, например, это нужно чтобы спарсить сайт. Для разбора xml/html есть замечательная библиотека – BeautifulSoup, которая будет работать даже в том случае, если документ не валидный (с ошибками, типа пропущены тэги, перепутан порядок и т.д.) Воспользуемся BeautifulSoup и Python’ом :
# get all urls
import BeautifulSoup
def get_all_urls(html):
soup = BeautifulSoup.BeautifulSoup(html)
urls = [tag['href'] for tag in soup.findAll('a')]
result = []
for val in urls:
if (val[:7] == "http://") or (val[:8] == "https://"):
result.append(val)
return result
или так (с помощью filter и lambda):
# get all urls
import BeautifulSoup
def get_all_urls(html):
soup = BeautifulSoup.BeautifulSoup(html)
urls = [tag['href'] for tag in soup.findAll('a')]
f = lambda x: True if (x[:7] == "http://") or (x[:8] == "https://") else False
return filter(f, urls)
Posted in Code, Python | 4 Comments »
Thursday, November 25th, 2010 |
Бывает различные сервисы используют url-прокладку тем самым скрывая оригинальный url ссылки, а узнать оригинальный урл очень хочется. Примеров масса – различные сервисы сокращения ссылок (shorurl), ссылки feedburner через feedproxy.google.com. Короче, очень жизненный пример : мне нужно получать данные из кучи RSS, часть из них проходит через этот самый feedburner который преобразует ссылки таким образом – http://feedproxy.google.com/~r/somesite/~3/H_xFNwC1ikE/ не, ну это блядство, срочно нужна ссылка на оригинал.
Как получить оригинальный url ссылки shorturl?
Делается это элементарно, дергаем этот линк, проходим все редиректы и возвращаем тот url куда в конечном итоге пришли.
Используя urllib2. Самый простой метод, поэтому наиболее предпочтительный.
import urllib2
fp = urllib2.urlopen('http://feedproxy.google.com/~r/somesite/~3/H_xFNwC1ikE/')
print fp.geturl()
Используя httplib. Замороченный, нужно разбивать урл на части, что как бы не очень удобно.
import httplib
""" http://feedproxy.google.com/~r/somesite/~3/H_xFNwC1ikE/ """
conn = httplib.HTTPConnection('feedproxy.google.com')
conn.request('HEAD', '/~r/somesite/~3/H_xFNwC1ikE/')
response = conn.getresponse()
print response.getheader('location')
Используя культовый curl
import pycurl
conn = pycurl.Curl()
conn.setopt(pycurl.URL, 'http://feedproxy.google.com/~r/somesite/~3/H_xFNwC1ikE/')
conn.setopt(pycurl.FOLLOWLOCATION, 1)
conn.setopt(pycurl.CUSTOMREQUEST, 'HEAD')
conn.setopt(pycurl.NOBODY, True)
conn.perform()
print conn.getinfo(pycurl.EFFECTIVE_URL)
Кстати, первый спамм на .РФ – онлайн-гипермаркет.рф
Posted in Code, Notes, Python | No Comments »