def rUpdate(targetDict, itemDict):
«Recursively updates nested dicts»
for key, val in itemDict.items():
if type(val) == type({}):
newTarget = targetDict.setdefault(key,{})
rUpdate(newTarget, val)
else:
targetDict[key] = val
Posts By: fedorishev
Сцепляем значения двух словарей по ключу
def func(*dicts):
keys = set().union(*dicts)
return {k: «».join(dic.get(k,») for dic in dicts) for k in keys}
Считаем непустые элементы в списке
len(filter(None, iterable))
Сжать все картинки в каталоге до размеров не более 800×600
sudo apt-get install imagemagick
mogrify -resize «800×600>» *.jpg
Bonus: bash-версия, для обхода вложенных каталогов и сжатия файлов там:
CDIR=$(pwd)
for i in $(ls -R | grep :); do
DIR=${i%:}
cd $DIR
mogrify -resize "800x600>" *.jpg
cd $CDIR
done
Причины неудач стартапов по отраслям в США
Industry | Percent Still Operating After 4 Years |
Finance Insurance and Real Estate | 58 % |
Education and Health | 56 % |
Agriculture | 56 % |
Services | 55 % |
Wholesale | 54 % |
Mining | 51 % |
Manufacturing | 49 % |
Construction | 47 % |
Retail | 47 % |
Transportation, Communication and Utilities | 45 % |
Information | 37 % |
Year | Percent Failed |
Year 1 | 25 % |
Year 2 | 36 % |
Year 3 | 44 % |
Year 4 | 50 % |
Year 5 | 55 % |
Year 6 | 60 % |
Year 7 | 63 % |
Year 8 | 66 % |
Year 9 | 69 % |
Year 10 | 71 % |
Major Cause | Percentage of Failures | Specific Pitfalls | |
1 | Incompetence |
46 %
|
Emotional Pricing |
Living too high for the business | |||
Nonpayment of taxes | |||
No knowledge of pricing | |||
Lack of planning | |||
No knowledge of financing | |||
No experience in record-keeping | |||
2 | Unbalanced Experience or Lack of Managerial Experience |
30 %
|
Poor credit granting practices |
Expansion too rapid | |||
Inadequate borrowing practices | |||
3 | Lack of Experiences in line of goods or services |
11 %
|
Carry inadequate inventory |
No knowledge of suppliers | |||
Wasted advertising budget | |||
5 | Neglect, fraud, disaster |
1 %
|
Leading Management Mistakes | |
1 | Going into business for the wrong reasons |
2 | Advice from family and friends |
3 | Being in the wrong place at the wrong time |
4 | Entrepreneur gets worn-out and/or underestimated the time requirements |
5 | Family pressure on time and money commitments |
6 | Pride |
7 | Lack of market awareness |
8 | The entrepreneure falls in love with the product/business |
9 | Lack of financial responsibility and awareness |
10 | Lack of a clear focus |
11 | Too much money |
12 | Optimistic/Realistic/Pessimistic |
Businesses with Best Rate of Success After Fifth Year | |
1 | Religious Organizations |
2 | Apartment Building Operators |
3 | Vegetable Crop Productions |
4 | Offices & Clinics of Medical Doctors |
5 | Child Day Care Services |
Business with Worst Rate of Success After Fifth Year | |
1 | Plumbing, Heating, Air Conditioning |
2 | Single-Family Housing Construction |
3 | Grocery Stores |
4 | Eating Places |
5 | Security Brokers and Dealers |
6 | Local Trucking |
via http://www.statisticbrain.com/startup-failure-by-industry/
SQLFORM.grid — коробочный настраиваемый броузер таблиц
Быстро вывести табличку с базой данных поможет такая простая конструкция в web2py :
grid = SQLFORM.grid(db.table)
А вот и параметры ее
SQLFORM.grid( query, fields=None, # выборка полей для вывода field_id=None, # id - поле left=None, # LEFT JOIN headers={}, # Заголовки orderby=None, # сортировка groupby=None, # группировка searchable=True, # поле поиска sortable=True, # кнопки сортировки paginate=20, # записей на страницу deletable=True, # кнопка удалить editable=True, # кнопка редактировать details=True, # кнопка Подробнее selectable=None, # чекбокс для выбора create=True, # можно создавать новые элементы csv=True, # экспорт в csv links=None, # поля - ссылки links_in_grid=True, # показывать в главной таблице ссылки upload='<default>', # args=[], # user_signature=True, # maxtextlengths={}, # максимальная длина текста в полях maxtextlength=20, # onvalidation=None, # функция вызываемая при проверке формы oncreate=None, # функция при создании нового элемента onupdate=None, # функция при редактировании элемента ondelete=None, # функция при удалении элемента sorter_icons=(XML('↑'), XML('↓')), # иконки сортировки ui = 'web2py', # можно поставить jquery-ui, либо описать все компоненты индивидуально словарем showbuttontext=True, # Текст на кнопках _class="web2py_grid", # класс формы formname='web2py_grid', # имя формы search_widget='default', # поисковая форма ignore_rw = False, # formstyle = 'table3cols', # exportclasses = None, # formargs={}, # аргументы формы createargs={}, # аргументы функции создания нового элемента editargs={}, # аргументы функции редактирования элемента viewargs={}, # аргументы функции просмотра элемента buttons_placement = 'right', # кнопки справа links_placement = 'right' # ссылки справа )
Credits : http://www.web2py.com/book/default/chapter/07#SQLFORM.grid
logging : пишем логи в файл
Выводим время, уровень ошибки, файл и строку вызова, ну и естественно, текст сообщения:
import logging logging.basicConfig(format = u'%(filename)s[LINE:%(lineno)d]# %(levelname)-8s [%(asctime)s] %(message)s', level = logging.DEBUG, filename = u'applog.log') logging.debug('This is just a debug')
via http://habrahabr.ru/post/144566/
upd: лучший пример со stackoverfow :
import logging
log = logging.getLogger("mylog")
log.setLevel(logging.DEBUG)
formatter = logging.Formatter(
"%(asctime)s %(threadName)-11s %(levelname)-10s %(message)s")
# Alternative formatting available on python 3.2+:
# formatter = logging.Formatter(
# "{asctime} {threadName:>11} {levelname} {message}", style='{')
# Log to file
filehandler = logging.FileHandler("debug.txt", "w")
filehandler.setLevel(logging.DEBUG)
filehandler.setFormatter(formatter)
log.addHandler(filehandler)
# Log to stdout too
streamhandler = logging.StreamHandler()
streamhandler.setLevel(logging.INFO)
streamhandler.setFormatter(formatter)
log.addHandler(streamhandler)
# Test it
log.debug("Some message")
log.error("An error!")
try:
something()
except:
log.exception("An exception occured!")
via http://stackoverflow.com/questions/4722745/logging-between-classes-in-python
scrapy — кроулим, парсим и грабим
scrapy — весьма ценная библиотека для тех, кому нужно пройти по большому массиву страниц (с большой вложенностью, заранее не ограниченному), и добыть оттуда набор однотипной информации.
В общем, пойди туда — пока не знаю куда, принеси то — пока не знаю что. И сформируй из этого таблицу csv или файл json.
pip install scrapy # создаем новый проект - ScrapySample scrapy startproject ScrapySample
Редактируем конфигурационные файлы. Сначала что собирать — файл item.py в папке webcrawl
from scrapy.item import Item, Field class ScrapySample(Item): title = Field() link = Field() content = Field() pass
Теперь сам паук. В папкe ScrapySample/spiders создаем ScrapySpider.py
from scrapy.spider import BaseSpider from scrapy.selector import HtmlXPathSelector from scrapy.http.request import Request from scrapy_sample.items import ScrapySampleItem class ScrapyOrgSpider(BaseSpider): name = "scrapy" allowed_domains = ["scrapy.org"] start_urls = ["http://blog.scrapy.org/"] def parse(self, response): hxs = HtmlXPathSelector(response) next_page = hxs.select("//div[@class='pagination']/a[@class='next_page']/@href").extract() if next_page: yield Request(next_page[0], self.parse) posts = hxs.select("//div[@class='post']") items = [] for post in posts: item = ScrapySampleItem() item["title"] = post.select("div[@class='bodytext']/h2/a/text()").extract() item["link"] = post.select("div[@class='bodytext']/h2/a/@href").extract() item["content"] = post.select("div[@class='bodytext']/p/text()").extract() items.append(item) for item in items: yield item # возвращаем генератор собранных объектов
Запускаем:
scrapy crawl ScrapySample -o ScrapySample.json -t json
(можно в csv или xml)
Thanks :
http://amaral.northwestern.edu/blogs/2013/apr/8/quick-introduction-web-crawling-using-scrapy-part-/
dataset — еще одна обертка баз данных для ленивых
import dataset db = dataset.connect('sqlite:///:memory:') table = db['sometable'] table.insert(dict(name='John Doe', age=37)) table.insert(dict(name='Jane Doe', age=34, gender='female')) john = table.find_one(name='John Doe') # Внимание, теперь самое вкусное! # Запросы: table = db['users'].table statement = table.select(table.c.name.like('%Snoopy%')) result = db.query(statement) # Сохраняем в json/csv всех result = db['users'].all() dataset.freeze(result, 'users.json', format='json') # Или каждого пользователя в свой файл # export one JSON file per user dataset.freeze(result, 'users/{{ id }}.json', format='json', mode='item')
Быстрая база данных с gluon.sql
from gluon.sql import DAL, Field
# Подключаемся. В наличии полтора десятка драйверов - MySQL, PostgreSQL, MongoDB and more...
db=DAL('sqlite://database.db')
# Создаем таблицу (если ее нет). Мигрируем (если она изменилась), просто открываем (если она не изменилась)
db.define_table('taskList',Field('title'),Field('done','boolean'))
# Добавляем данные
db['taskList'].insert(title='Beat old sql interfaces',done=False)
db.taskList.insert(title='Beat old sql interfaces',done=False)
# Делаем запрос
for task in db(db.taskList.done==True).select():
print task.title
Via http://stackoverflow.com/a/2976972
Disclaimer: web2py required
Официальная документация: http://www.web2py.com/book/default/chapter/06