Namecheap.com - Cheap domain name registration, renewal and transfers - Free SSL Certificates - Web Hosting

Archive for the ‘Python’ Category

Функции map и zip и lambda. Python

Wednesday, November 17th, 2010 |

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

Функции map, zip и lambda в примерах.

Простая задача есть список a = [1, 2] и список b = [3, 4] одинаковой длины и нужно слить их парами. Проще простого – используя функцию zip :

a = [1,2]
b = [3,4]
print zip(a,b)
[(1, 3), (2, 4)]

или тройками :

a = [1,2]
b = [3,4]
c = [5,6]
print zip(a,b,c)
[(1, 3, 5), (2, 4, 6)]

или в более общем виде

list = [a, b, c]
print zip(*list)
[(1, 3, 5), (2, 4, 6)]

Звездочка * перед list как-бы говорит что передается список аргументов, т.е. Действовать эквивалентно тому как если бы передали a, b, c т.е. Можно даже так print zip(*[a, b, c]) результат не изменится.

Далее функция – map. Случаются ситуации, когда внезапно нужно применить какую-либо функцию к каждому элементу списка.
Нуб напишет так :

def f(x):
    return x*x
nums = [1, 2, 3]
results = []
for num in nums:
    results.append(f(num))
print results

Немного поизучавший мануалы так :

def f(x):
    return x*x
print [ f(num) for num in nums ]

Программист сделает проще :

def f(x):
    return x*x
print map(f, nums)

А вот тру-мэдскиллз кодер сделает следующим образом :

print map(lambda x: x*x, nums)

Последняя запись являет собой пример наиболее грамотного подхода. Дело в том, что когда человек пишет код как стихи в порыве вдохновения, крайне роляет скорость написания (отсюда растут корни трепетной любви многих питон кодеров к vim и emacs), а сильная сторона питона как раз в размере генерируемого кода – он очень компактный. Написать одну строчку естественно быстрее чем 7, да и изучать короткий код проще, однако написание подобного кода требует определенного навыка. Другая сторона медали – иногда про-devs очень любят писать в одну строчку целые последовательности достаточно сложных действий, да так что очень трудно понять что там происходит и что получается в конечном итоге.

Из примера понятно, что map применяет какую-либо функцию к списку и возвращает результат опять же в виде списка. Вы можете передать несколько списков, тогда функция (идущая первым параметром) должна принимать несколько аргументов (по количеству списков переданных в map) .

def f(x, y):
    return x*y

a = [1,3,4]
b = [3,4,5]
print map(f, a, b)
[3, 12, 20]

Жир, правда?

Однако если списки разной длины, т.е. Один короче другого, то он будет дополнен значениями None до нужной длины. Если убрать из списка b последнее значение – пример не будет работать, т.к. В функции f произойдет попытка умножения числа на None, а в питоне строгая типизация, что кстати выгодно отличает его от php, который в подобной ситуации работал бы дальше.
Поэтому если функция f достаточно объемна, неплохо бы проверять передаваемые значения. Например ;

def f(x, y):
    if (y == None):
        y = 1
    return x*y

Если же заместо функции стоит None – то map действует примерно так же как и zip, но если передаваемые списки разной длины в результат будет писаться None – что кстати очень уместно в некоторых моментах.

a = [1,3,4]
b = [3,4]
print map(None, a, b)
[(1, 3), (3, 4), (4, None)]

Теперь про лямбда функции в python. Они используются когда вам необходимо определить функцию, ведь часто (как в предыдущих примерах) функция настолько мала, что определять её отдельно смыла нет (ведь это лишние строчки кода и ухудшение читабельности).
Поэтому функцию можно определить “на месте” f = lambda x: x*x как бы говорит нам – принимает x, возвращает x*x

Так используя стандартные инструменты питона можно записать довольно сложные действия в одну строчку. К примеру функцию :

def f(x, y):
    if (y == None):
        y = 1
    return x*y

можно представить как :

lambda x, y: x * (y if y is not None else 1)

А теперь хорошо бы передавать списки отсортированные по длине – len(a) > (b) – проще простого – воспользуемся функцией sorted :

sorted([a, b], key=lambda x: len(x), reverse=True)

фунция sorted принимает список значений ([a,b] = [[1,2],[2,4,5]]) и сортирует по ключу key – который у нас задан функцией len(x) – возвращающей длину списка, сортируем в порядке убывания (reverse=True)

В конечном итоге вся операция записывается таким образом :

map(lambda x, y: x * (y if y is not None else 1), *sorted([a, b], key=lambda x: len(x), reverse=True))

списки a и b могут быть разной длины и передаваться в каком угодно порядке.
Лямбда-выражения удобны для определения не очень сложных функций, которые передаются затем другим функциям.

Самый быстрый способ удалить дубли из списка. Python

Sunday, November 14th, 2010 |

Задача классическая. Удалить повторы из какого-либо списка. Самый быстрый вариант сделать так :

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)]

Составление случайной последовательности из списка.

Saturday, November 13th, 2010 |

Часто встречающаяся задача – получить случайную последовательность, случайной длинны из какого-либо набора данных. Например – 5-10 кейвордов из списка кеев в несколько тысяч, или выбор последовательности действия для бота имитирующего поведение человека. Ну в простейшем варианте – все просто :

import random
data = ['add_friends', 'post_story', 'vote', 'comment']
chain = random.sample(data, 2)

А если хочется задать вероятность наступления события?

import random

def get_random_chain(chain, min_max=[1,1]):
    """ Get random chain from list """
    items_chain = []
    random.seed()
    for item, num in chain.iteritems():
        items_chain.extend([item] * num)
    random.shuffle(items_chain)
    chain_len = random.randint(min_max[0], min_max[1])
    return random.sample(items_chain, chain_len)

Вот так использовать (исходная последовательность задается в виде словаря key : value – где value вероятность наступления события) :

ACTIONS = {
    "post" : 20,
    "vote" : 80
}
what_to_do = get_random_chain(ACTIONS, [5,10])

Получить случайную цепочку действий длинной в данном случае от 5 до 10 элементов.
Обратите внимание длинна цепочки может быть сколь угодно длинной и превышать исходную последовательность.

Удалить html тэги из строки. Python Edition.

Saturday, November 13th, 2010 |

Вам нужен http://www.crummy.com/software/BeautifulSoup/ – отличная штука для работы с html/xml документами, работает даже если xml кривой. Очень часто встречающаяся задача – удалить html тэги из строки.

from BeautifulSoup import BeautifulSoup

''.join(BeautifulSoup(page).findAll(text=True))

Так же можно заюзать уже готовый код от Lorien’а (помните про open source?) – clean.py, не забудьте импортировать в проект так же и htmldata.py

Open Source Social Networks

Saturday, November 13th, 2010 |

Достаточно модный тренд, вообщем самое время поговорить о мощном движении Open Source и его пользе. Наверняка многие слышали о таких темах как sourceforge.net, code.google.com? Достаточно плотно сидят в выдаче. В чем заключается на данный момент работа программиста? Ведь почти все что нужно так или иначе есть в готовом виде, и нужно лишь протянуть руку чтобы использовать чужие разработки, а не терять время разрабатывая очередной велосипед. Настоящие развалы готового кода практически на все случаи жизни можно найти на социальных сайтах :

GitHub

BitBucket

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

Хранение настроек Python

Wednesday, November 10th, 2010 |

Часто настроек в приложении может быть дофига и невольно задумываешься о том, чтобы вынести их в отдельный файл – файл настроек. Бывает программисты по инерции начинают писать код который будет считывать и обрабатывать этот файл, и бывает даже строковыми методами. Однако в питоне ничего не мешает нам создать файл вроде settings.py и исполнять его на уровне кода.
Вот к примеру файл settings.py :

import os.path as path

template_dir = path.join(path.dirname(__file__), "templates")

user_record = {
    'id' : 1,
    'mail' : "xyu@gmail.com",
    'pass' : "1234"
}

А вот так его можно вызывать из кода :

import settings

def main():
    print settings.template_dir

if __name__ == "__main__":
    main()

или так (по модному) :

def main():
    mod = __import__("settings")
    print getattr(mod, 'template_dir')

if __name__ == "__main__":
    main()

Проверка количества проиндексированных страниц в Google

Tuesday, September 7th, 2010 |

Как определить кол-во проиндексированных страниц в гугле? реализация на Python. Недавно нужно было срочно, написал :

import urllib
import re

from urllib2 import urlopen
from urlparse import urlparse
from urllib import FancyURLopener

class GOpener(FancyURLopener):
    version = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6'

def web_getpage(url):
    g_opener = GOpener()
    page = g_opener.open(url)
    return page.read()

def get_index(url):
    request = 'http://www.google.com/search?q=site:' + url
    # About 105,000,000 results
    index = 0
    try:
        gs = web_getpage(request)
        p = re.compile('About (.*) results')
        index = int(p.findall(gs)[0].replace(",", ""))
    except SearchError, e:
        index = -1
        #print "Search Failed : %s" % e
    finally:
        #print "Index: %d\tURL: %s" % (int(index), url)
        return index

Проверка подключения к интернету

Thursday, September 2nd, 2010 |
from urllib2 import urlopen
""" Returns True if we appear to have an internet connection or False.
    It defaults to using google as a test server, but you can supply an alternative if you want."""
def isonline(reliableserver='http://www.google.com'):
    try:
        urlopen(reliableserver)
        return True
    except IOError:
        return False

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

Проверка Google PR на Python

Tuesday, August 31st, 2010 |

Собственно рабочая функция проверки Google Page Rank :

import urllib, sys

def get_pagerank(url):
    hsh = check_hash(hash_url(url))
    gurl = 'http://www.google.com/search?client=navclient-auto&features=Rank:&q=info:%s&ch=%s' % (urllib.quote(url), hsh)
    try:
        f = urllib.urlopen(gurl)
        rank = f.read().strip()[9:]
    except Exception:
        rank = 'N/A'
    if rank == '':
        rank = '0'
    return rank

def  int_str(string, integer, factor):
    for i in range(len(string)) :
        integer *= factor
        integer &= 0xFFFFFFFF
        integer += ord(string[i])
    return integer

def hash_url(string):
    c1 = int_str(string, 0x1505, 0x21)
    c2 = int_str(string, 0, 0x1003F)

    c1 >>= 2
    c1 = ((c1 >> 4) & 0x3FFFFC0) | (c1 & 0x3F)
    c1 = ((c1 >> 4) & 0x3FFC00) | (c1 & 0x3FF)
    c1 = ((c1 >> 4) & 0x3C000) | (c1 & 0x3FFF)

    t1 = (c1 & 0x3C0) << 4
    t1 |= c1 & 0x3C
    t1 = (t1 << 2) | (c2 & 0xF0F)

    t2 = (c1 & 0xFFFFC000) << 4
    t2 |= c1 & 0x3C00
    t2 = (t2 << 0xA) | (c2 & 0xF0F0000)

    return (t1 | t2)

def check_hash(hash_int):
    hash_str = '%u' % (hash_int)
    flag = 0
    check_byte = 0

    i = len(hash_str) - 1
    while i >= 0:
        byte = int(hash_str[i])
        if 1 == (flag % 2):
            byte *= 2;
            byte = byte / 10 + byte % 10
        check_byte += byte
        flag += 1
        i -= 1

    check_byte %= 10
    if 0 != check_byte:
        check_byte = 10 - check_byte
        if 1 == flag % 2:
            if 1 == check_byte % 2:
                check_byte += 9
            check_byte >>= 1

    return '7' + str(check_byte) + hash_str

print get_pagerank("http://twitter.com")

Легкая IDE для Pyhton

Tuesday, August 24th, 2010 |

Не так давно услышал про такую IDE как Pyscripter. Скачал отсюда, утсановил. Вообщем пара слов : легче чем NetBeans определенно. Рекомендую.

pyscripter IDE

Добавить категории через WordPress API

Wednesday, March 10th, 2010 |

Класс описанный в статье “Постинг в WordPress” позволяет прикрепить к посту уже созданные категории, что как бы несколько неудобно если их нужно создавать динамически. Это можно сделать через WordPress API (по XML-RPC), но в библиотеке эта функция не реализованна, впрочем как и многие другие. Пришлось написать самому :

import xmlrpclib

def uniq(input):
  output = []
  for x in input:
    if x not in output:
      output.append(x)
  return output

def getCategories(blog_url, blog_user, blog_pwd):
    _server = xmlrpclib.ServerProxy(blog_url)
    cat = _server.wp.getCategories(1, blog_user, blog_pwd)
    categories = []
    for item in cat:
        categories.append(item['categoryName'].replace("&", "&"))
    return categories

def addCategories(blog_url, blog_user, blog_pwd, categories):
    _server = xmlrpclib.ServerProxy(blog_url)
    categories = uniq(categories)
    created_cat = getCategories(blog_url, blog_user, blog_pwd)
    for item in categories:
        itm = item.replace("&", "&")
        if (itm not in created_cat):
            post_name = itm
            post_slug = itm.replace(" ", "-")
            post_slug = post_slug.replace("&", "")
            post_parent_id = 0
            post_description = itm
            catStructure = {'name' : post_name,
                            'slug' : post_slug,
                            'parent_id' : post_parent_id,
                            'description' : post_description}
            category_id = _server.wp.newCategory(1, blog_user, blog_pwd, catStructure)

Подобный образом можно реализовать вызов практически любого документированного метода. btw разработчики вордпресса сильно отстают с документацией, поэтому проще посмореть исходный код файла xml-rpc.php в последней сборке вордпресса, чтобы быть в курсе. Я так понимаю, используя вордпрессовскую реализацию metaWeblog API (metaWeblog.newPost) можно добавлять еще и тэги к посту, но саму функцию вроде addTags я не нашел, к сожалению.

Вот так это выглядит на практике :

        wp_cat.addCategories(category)
        cats_id = []
        for item in category:
            if (wp.getCategoryIdFromName(item) <> None):
                cats_id.append(wp.getCategoryIdFromName(item))
        post.categories = tuple(uniq(cats_id))
        idPost = wp.newPost(post, True)

Где wp – это экземпляр класса wordpresslib, а category – это список категрий в виде списка – ['look', 'here']. Типа того, вообщем разобраться несложно.

База данных WordNet. Словарь синонимов.

Thursday, December 3rd, 2009 |

Более подробно сабж можно оценить сходив по ссылке.

WordNet – большая лексическая база данных Английского языка разработанная под руководством George A. Miller.
В наличии имеются существительные, глаголы, прилагательные и наречия, которые сгруппированы в наборы когнитивных синонимов (synsets), каждый из которых выражает различные понятия. Synsets взаимосвязаны посредством концептуально-семантических и лексических отношений (жесть!!!).
Итоговую сеть связей между значениями слов и понятий, можно просматривать с помощью WordNet, который свободно распространяется и доступен для скачивания. Структура WordNet делает его полезным инструментом для компьютерной лингвистике и обработки естественного языка.

Я думаю, намек довольно прозрачен.

Скачать и посмотреть.

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

Библиотеки для работы с WordNet.

Там есть на что посмотреть. Например онлайн словари http://www.a2zdefined.com/ и http://www.memidex.com/

Рекомендую взглянуть на Natural Language Toolkit – это библиотека для Python. Примеры использования по ссылке.

Работа с Blogspot

Friday, September 4th, 2009 |

Да-да, теперь не лезет, в свое время многие постарались на славу, чтобы ушатать этот блогхост кодеками и прочими интересными вещами. Но тем не менее даже на данный момент блогспот можно использовать для привлечения траффика, хотя для этого теперь нужно приложить хоть какие-то усилия. Помимо этого хост можно использовать в качестве индексируемой базы данных (я например какое-то время сохранял результаты google hot trends), собрания каких-либо тематических ссылок. На самом деле вариантов масса, в результате будут получаться различные блоги, и если обновленеи будет поставленно на поток, то эти сайты в конечном итоге послужат фундаментом SEO-империи.

Помимо этого гугл любезно предоставляет API для работы с большей частью своих сервисов, все это дело регулярно апдейтится и документируется, скачать библиотеку для Python можно на официальной странице Google GData Python Client. В данном случае нас интересует работа с blogspot.com. Внутри архива Google GData есть подробная (и короткая) инструкция по установке пакетов (package) для Python.

По поводу использования, на активстэйт как обычно все уже сделали до нас, однако в этом примере мой питон выдает ошибку :
TypeError: CreatePost() takes exactly 6 arguments (5 given)
Это легко исправить, функция CreatePost() помимов всего прочего принимает список тэгов которые нужно добавить к посту. В примере не хватает как раз этого параметра, хз в чем прикол, возможно защита от дурака =) Я пофиксил баг (пример работы с blogspot через API), чтобы все запускалось без проблем, нужно только разобраться в коде и использовать уже готовые функции, единственная не поддающаяся автоматизации через API задача – регистрация аккаунтов, но гмыла можно купить, а регистрировать и оформлять блог или руками, или используя софт эмулирующий работу браузера вроде Human Emulator, хардкорные кодеры, конечно могут реализовать это через curl.

Работать через API конечно удобно, если собирать более-менее красивые блоги в небольшом количестве. В остальных случаях, крайне желательно использовать прокси и как вы понимаете этого (во всяком случае прямо) в API не предусмотрено, нужно или хитрить запуская код через различные проксификаторы или править код самой библиотеки.

My blog is Do-Follow


Пишу код, делаю сайты.
Check out my about.me profile!

парсинг сайтов, форумов, интернет магазинов

Want to subscribe?

istinspring twitter account
istinspring facebook account

 Subscribe in a reader Or, subscribe via email:
Enter your email address:  
Find entries :