Общее·количество·просмотров·страницы

Java Dev Notes - разработка на Java (а также на JavaScript/Python/Flex и др), факты, события из АйТи

Показаны сообщения с ярлыком python. Показать все сообщения
Показаны сообщения с ярлыком python. Показать все сообщения

среда, 2 ноября 2011 г.

Скрипт для подсчета числа файлов java, xml и др.

Нужно было посчитать статистику по файлам java и др. Вот что получилось:
import os
 
startPath = os.getcwd()
 
java = 0
xmlxsd = 0
 
def findFiles(path):
    global java
    global xmlxsd
    files = os.listdir(path)
    for f in files:
        p = os.path.join(path, f)
        if os.path.isdir(p):
            findFiles(p)
        else:
            fn, fe = os.path.splitext(p)
            print fe
            if fe == '.java':
                java = java+1
            elif fe in ['.xsd', '.xml', '.html', '.xhtml']:
                xmlxsd = xmlxsd + 1 
 
def main():
    findFiles(startPath)
    print 'java = %d ' % java
    print 'xmlxsd = %d' % xmlxsd
 
 
if __name__ == "__main__":
    main()   

пятница, 3 июня 2011 г.

Небольшой скрипт на python для удаления .svn директорий

Скрипт, который рекурсивно удаляет каталоги .svn из дерева директорий:

import os
import shutil
 
startPath = 'C:\\usr\\dbTracer\\fennel-webapp-OBO\\FENNEL_OBO'
 
def findDeleteSvn(path):
files = os.listdir(path)
for f in files:
p = os.path.join(path, f)
if os.path.isdir(p):
print p
if f == '.svn':
shutil.rmtree(p, True)
else:
findDeleteSvn(p)
 
def main():
findDeleteSvn(startPath)
 
if __name__ == "__main__":
main()

вторник, 30 ноября 2010 г.

Установка драйвера MySQL для Python (MySQLdb)

Понадобилось из скрипта на Python обращаться к БД на MySQL - задача стояла распарсить огромную кучу информации и положить результаты в какое-либо хранилище.

Скрипт, который скачивает и парсит данные, я написал на Python за несколько часов. В качестве хранилища была выбрана MySQL. Теперь нужно было найти драйвер мускула для питона. Драйвер называется MySQLdb и поддерживается сторонним разработчиком, а не фирмой MySQL. Дравер лежит по адресу http://pypi.python.org/pypi/MySQL-python. Я взял было последнюю версию драйвера (версия 1.2.3, в этой версии были только исходники) - и обломался, т.к. она никак не хотела компилиться у меня ни на Windows 7, ни на Windows XP (мне пришлось поставить setuptools и MinGW, чтобы поиметь на машине компилятор gcc). Также нужно, чтобы в файлах MySQL были заголовочные файлы (каталог include).

Тогда я решил поставить яйцо - т.е. egg-файл модуля. К сожалению, версия 1.2.3 поставляется только в исходниках, поэтому мне пришлось ставить яйцо версии 1.2.2 (это версия для MySQL 5.0). Egg-Файл можно скачать отсюда - http://pypi.python.org/pypi/MySQL-python/1.2.2 (MySQL_python-1.2.2-py2.5-win32.egg). Забыл добавить, что на машине у меня стоит версия Python 2.5.

Итак, скачав egg-файл, устанавливаем его командой easy_install:

easy_install MySQL_python-1.2.2-py2.5-win32.egg


Получаем вывод:

D:\temp>easy_install MySQL_python-1.2.2-py2.5-win32.egg
Processing MySQL_python-1.2.2-py2.5-win32.egg
Copying MySQL_python-1.2.2-py2.5-win32.egg to d:\python25\lib\site-packages
Adding MySQL-python 1.2.2 to easy-install.pth file

Installed d:\python25\lib\site-packages\mysql_python-1.2.2-py2.5-win32.egg
Processing dependencies for MySQL-python==1.2.2
Finished processing dependencies for MySQL-python==1.2.2


Чтобы работала команда easy_install, необходимо добавить в PATH %PY_HOME%/Scripts

P.S. Для версии Python 2.6 бинарники модуля можно скачать отсюда: MySQL-python Windows 64bit and 32bit distributions

UPDATE:

Для Ubuntu все намного проще. Установка MySQLdb:

sudo apt-get install python-mysqldb

воскресенье, 4 июля 2010 г.

Генератор паролей на Питоне

Нужно было написать генератор паролей, который бы генерировал случайные пароли заданной длины. Приведенный ниже код решает эту задачу:

import random
 
passwordSymbols = ";*()_+=-,.[]{}1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
 
def genRandomSymbols(len):
"""
:param len: length of random symbols sequence
:raise BadValueError: If len < 0
:return: The random sequence of len length.
"""

if len < 0:
raise ValueError("len should be greater or equal than 0")
elif len == 0:
return ""
else:
result = ""
for i in range(len):
result = result + random.choice(passwordSymbols)
return result
 
def main():
print genRandomSymbols(12)
 
if __name__ == "__main__":
main()

четверг, 1 июля 2010 г.

Вышел релиз Google App Engine SDK 1.3.5

Вышел релиз Google App Engine SDK 1.3.5. Release notes: http://code.google.com/p/googleappengine/wiki/SdkReleaseNotes

Новое:

  • Можно включить прекомпиляцию Питона

  • Конфигурирование лимита хранения Task Queue

  • Task Queues теперь могут иметь до 50 задач на очередь (раньше - 50 задач на приложение)

  • Программный доступ к блобам используя BlobReader - файлоподобный интерфейс для чтения блобов

  • Улучшения в BulkLoader

  • Команды remote_api_shell могут посылаться через HTTPS или HTTP.

  • Admin Console логгирует теперь время задержки запросов (request time latency).

  • Db.delete теперь принимает коллекции

  • Хранилище поддерживает концевые курсоры (end cursors)

  • Исправлено несколько багов

пятница, 14 мая 2010 г.

Итерация по словарю в шаблонах Google App Engine

Возникла задачка: как отрендерить в шаблон GAE данные, которые содержатся в словаре. В шаблон передается словарь, который содержит статистику по регионам. Ключами являются названия регионов, а значениями - количество неких объектов в этом регионе.

Нам нужно в шаблоне выводить список регионов + соответсвуюшую цифру. Делается это так:



"area" : {
{% for i in areaStat.items %}
"{{ i.0 }}" : "{{ i.1 }}"{% if not forloop.last %},{% endif %}
{% endfor %}
}



Здесь areaStat - это имя словаря, i.0 - ключ, i.1 - значение.

вторник, 30 марта 2010 г.

Обратное геокодирование на Google Maps, получение региона

Понадобилось мне как-то получить регион для множества гео-объектов. У меня есть координаты точек, и более ничего. А хочется для каждого гео-объекта иметь следующее: Страну-Регион-Субрегион. После этого я смогу, например, делать кластеризацию по регионам.

Пример данных вида Страна-Регион-Субрегион: Россия-Ленинградская область-Всеволожский район. Или: Россия-город Санкт-Петербург-Фрунзенский район.

Получение адреса (хотя бы приблизительного) объекта по его географическим координатам называется обратным геокодированием. В разделе Геокодирование можно почитать о том, что это такое, и как этим пользоваться в Google Maps.

Обратное геокодирование в Google Maps выполняется следующим образом: передается запрос вида

http://maps.google.com/maps/geo?q=60.6462623161,29.7290039063&output=xml&oe=utf8

Он возвращает информацию об адресе объекта с координатами (60.6462623161,29.7290039063), формат возвращаемых данных XML (т.е. KML). Можно еще получать данные в CSV, JSON. Информация об адресе содержится в xml-контейнерах Placemark. Этих контейнеров обычно бывает несколько в XML-документе. Каждый из них содержит информацию о ближайшей к объекту точке и ее адресе. В Placemark есть контейнер AddressDetails с атрибутом Accuracy. Если Accuracy=1, то в данном плейсмарке определена только страна, если Accuracy=2, то определена страна и регион, а если Accuracy=3, то дополнительно определен и субрегион. На большие значения Accuracy я не заглядывал, т.к. значения 3 мне хватало для моих целей за глаза и за уши.

Итак, у нас есть KML-документ, теперь мы его будем парсить. Парсер написан на Python.
Сначала нам потребуются две дополнительные функции: для извлечения текста из XML-ноды, а также для получения первого дочернего элемента. Вот эти функции:

def getFirstChildNode(parent,childNodeName):
choices = [e for e in parent.childNodes if e.nodeType == e.ELEMENT_NODE and e.nodeName == childNodeName]
for c in choices:
return c
return None
 
def getNodeText(node):
result = None
for c in node.childNodes:
if c.nodeType == Node.TEXT_NODE:
result = c.data
return result


Теперь представим всю функцию под названием getRegionFromKml:

def getRegionFromKml(kml):
kmldoc = minidom.parseString(kml)
 
result = {}
 
result['ok'] = False
 
result['CountryNameCode'] = None
result['CountryName'] = None
result['AdministrativeAreaName'] = None
result['SubAdministrativeAreaName'] = None
 
nodelist_status = kmldoc.getElementsByTagName("Status")
if len(nodelist_status)==0:
return result
node_status = nodelist_status[0]
node_code = getFirstChildNode(node_status,"code")
if not node_code: return result
code = getNodeText(node_code)
if not code == '200':
return result
 
nodelist_Placemark = kmldoc.getElementsByTagName("Placemark")
 
for node_Placemark in nodelist_Placemark:
if result['ok']:
break;
node_AddressDetails = getFirstChildNode(node_Placemark,"AddressDetails")
if not node_AddressDetails: continue
attribute_Accuracy = node_AddressDetails.getAttribute("Accuracy")
if not attribute_Accuracy: continue
accuracy = int(attribute_Accuracy)
if accuracy < 2: continue
node_Country = getFirstChildNode(node_AddressDetails,"Country")
if not node_Country: continue
 
node_CountryNameCode = getFirstChildNode(node_Country,"CountryNameCode")
if not node_CountryNameCode: continue
result['CountryNameCode'] = getNodeText(node_CountryNameCode)
#logging.info("country code: %s" %(result['CountryNameCode']) )
 
node_CountryName = getFirstChildNode(node_Country,"CountryName")
if not node_CountryName: continue
result['CountryName'] = getNodeText(node_CountryName)
 
#logging.info("CountryName: '%s'" % (CountryName))
node_AdministrativeArea = getFirstChildNode(node_Country,"AdministrativeArea")
if not node_AdministrativeArea: continue
 
node_AdministrativeAreaName = getFirstChildNode(node_AdministrativeArea,"AdministrativeAreaName")
if not node_AdministrativeAreaName: continue
result['AdministrativeAreaName'] = getNodeText(node_AdministrativeAreaName)
 
node_SubAdministrativeArea = getFirstChildNode(node_AdministrativeArea,"SubAdministrativeArea")
if node_SubAdministrativeArea:
node_SubAdministrativeAreaName = getFirstChildNode(node_SubAdministrativeArea,"SubAdministrativeAreaName")
if node_SubAdministrativeAreaName:
result['SubAdministrativeAreaName'] = getNodeText(node_SubAdministrativeAreaName)
 
node_Locality = getFirstChildNode(node_AdministrativeArea,"Locality")
if node_Locality:
node_LocalityName = getFirstChildNode(node_Locality,"LocalityName")
if node_LocalityName:
result['SubAdministrativeAreaName'] = getNodeText(node_LocalityName)
 
result['ok'] = True
 
return result
 


Для парсинга XML мы пользуемся пакетом minidom, так что в код нужно добавить пару импортов:

from xml.dom import minidom 
from xml.dom.minidom import Node


А вот как может выглядеть функция, которая а вход принимает широту и долготу, а на выход выдает объект, содержащий Страну/Регион/Субрегион данных координат:

def getRegionByLatLon(lat,lon):
result = {}
result['ok'] = False
 
try:
url = "http://maps.google.com/maps/geo?q=%10.8f,%10.8f&output=xml&oe=utf8" % (lat,lon)
urlResult = urlfetch.fetch(url)
 
if urlResult.status_code == 200:
kml = urlResult.content
result = getRegionFromKml(kml)
except:
logging.info('error occured when adding station: %s' % (sys.exc_info()[0]))
exceptionType, exceptionValue, exceptionTraceback = sys.exc_info()
logging.error('exceptionType: %s' % exceptionType)
logging.error('exceptionValue: %s' % exceptionValue)
logging.error('exceptionTraceback: %s' % exceptionTraceback)
 
return result


Подробнее о парсинге XML на Питоне можно прочитать по следующим ссылкам:

xml.dom.minidom — Lightweight DOM implementation

Dive in Python - Chapter 5. XML Processing

Python & XML - Chapter 1

четверг, 11 февраля 2010 г.

Вышел релиз Google App Engine SDK 1.3.1. Новые возможности Datastore

Это мой первый пост в новом 2010 году!!!

Итак, вышел релиз Google App Engine SDK 1.3.1. Основные изменения касаются хранилища данных! По порядку:

  • Появились курсоры - курсоры позволяют приложению ставить "закладки" при проходе по набору записей, полученных в результате запроса.

  • Отменен лимит на 1000 записей!!! Юхуууу! Хранилище теперь может возвращать столько записей, сколько потребуется!

  • Уменьшилось количество ошибок хранилища Теперь App Engine автоматически повторяет все запросы к хранилищу, если произошла ошибка доступа к Bigtable. Это уменьшает количество ошибок при put-запросах в 3-4 раза, при get-запросах в 10-30 раз


Дополнительно еще есть много других изменений (см. лист изменений для Python SDK).

По мотивам поста App Engine SDK 1.3.1, Including Major Improvements to Datastore! в блоге Google App Engine.

четверг, 26 ноября 2009 г.

Как узнать версию Python

Через командную строку:

python --version


Программно:
import sys
print sys.version_info


П.С. Многострочные комментарии в Питоне создаются с помощью тройных апострофов:
'''
This is
multiline comment
in Python
'
''

понедельник, 2 ноября 2009 г.

Python, Django, and Google App Engine

Выступление Гвидо Ван Россума на Google I/O 2008. См. видео-трансляцию.

Постоянные читатели