Posts Tagged ‘Python’
EBNF Parser Kata
Ката – то вправа в східних бойових мистецтвах, набір рухів які треба повторювати поки не засвоїш досконально. Термін застосовується також і для неробочого, неспортивного, самостійного учбового програмування поза якимось проектом.
На моєму домашньому модемі відвалився DSL, то я вчора ввечері не мав чим зайнятись. (Хоча звісно є купа важливіших речей) Зате біля мене була роздруківка книжечки Ніклауса Вірта “Compiler Construction“, то я взявся перекладати його парсер EBNF що ілюструє метод рекурсивного спуску з Oberon на Python. Вийшло ніби незле:
Прочитати решту цього запису »
Пишемо переглядач молекул з Pyglet
Я хотів створити серію уроків про графіку в OpenGL по слідах NeHe, але отримав іншу пропозицію, і пріоритети змінились. Ну й графіка в наш час людей не так цікавить. Але так як задачу я почав робити, просто витирати її з списку проектів буде не цікаво, краще опублікувати те що є і перенести в список закінчених проектів. Чим я зараз й займусь.
Ідея програми – намалювати атоми сферами різних кольорів і розмістити їх в різних місцях простору, таким чином отримавши молекулу. Для цього нам треба знати координати. Для цього ми використаємо Open Babel – хімічну експертну систему. Ось інструкції з інсталяції, apt-get install python-openbabel
якщо кому лінь їх читати.
Користуючись нею, ми можемо перетворити формулу SMILES, на список координат атомів:
Прочитати решту цього запису »
OpenGL в Python
Мене якось запитали про це, але без підготовки пояснити було важко, крім того мета була амбітна – намалювати молекулу, тому вийшло не так добре як би хотілось. Спробую написати короткий покроковий вступ в цю тему, який приблизно слідує послідовності в старих уроках Nehe (так, я чув що вони застаріли, але для нового OpenGL з шейдерами я якихось гарних послідовних уроків не бачив).
Інсталяція та перше вікно
Найперше що потрібно графічним програмам – вікно. Щоб створити вікно, нам треба якусь бібліотеку, наприклад PyQt, PySide, PyGtk, WxPython чи PyGame – їх купа. Потрібно також щоб це вікно підтримувало контекст OpenGL (тобто могло дозволити відеокарті виводити свої дані в область вікна). З цим може справитись багато бібліотек, але ми виберемо Pyglet. Тому що в ній мало зайвого, і вона ставиться традиційно:
pip install pyglet
Ну, і як годиться – почнемо з найпростішої програми:
import pyglet window = pyglet.window.Window(width=640, height=480, caption="Hello OpenGL!") pyglet.app.run()
Отримаємо вікно заданої ширини та висоти, і з заданим заголовком:
Елементарно, правда?
Фарби
Давайте ще зафарбуємо вікно в білий колір. Для цього потрібно знати що кольори задаються переважно інтенсивністю світла в моделі RGB (червоний, зелений, голубий), числами від 0 до 1. Тобто білий – це 1.0, 1.0, 1.0, сірий – 0.5, 0.5, 0.5, і т.п. Детальніше на вікіпедії.
import pyglet from pyglet.gl import * # імпортуємо всі функції OpenGL # вони починатимуться з префіксів gl або glu, тому простір імен надто не засмічуватимуть window = pyglet.window.Window(width=640, height=480, caption="Hello OpenGL!") # я не буду довго пояснювати що таке декоратор. Просто знайте, що # @window.event позначає функції що відповідають за обробку подій @window.event def on_draw(): # викликатиметься, коли операційна система вирішить що вікно треба перемалювати # наприклад, коли ми забрали вікно що було над нашим, або вперше виводимо його на екран glClearColor(1.0, 1.0, 1.0, 1.0) # Задати колір яким ми будемо очищати екран. # Четверте число - прозорість. # Я його сам не дуже розумію, але обов’язково треба чотири параметри. glClear(GL_COLOR_BUFFER_BIT) # очистити буфер кольору # (бувають і інші буфери, але про це пізніше) pyglet.app.run()
To be continued
В цьому уроці я хотів ще написати про те як намалювати трикутник, але часу мало (тобто є інші пріорітети). Зате ми створили вікно і навчились змінювати його колір. Ну й краще напевне писати менше але частіше. Якщо пілотний епізод цього курсу буде популярний – подумаю чи випускати перший сезон.
P.S. Май на увазі, якщо ти не хочеш навчити свою дівчину програмувати – вона може знайти когось хто схоче. 😛 Або взагалі сама з допомогою інтернету звикне вчитись.
Анонс Lvivpy4
Попередні три я пропустив бо не читаю новини, але от на цьому буду, тому що там я буду нести людям світло науки і знання.
Ви дізнаєтесь що таке компонент, інтерфейс, інваріант, утиліта, фабрика, адаптер (це не тільки шаблони), реєстр компонентів, і купу інших розумних слів. А також як можна застосовувати штуки що ці слова позначають щоб побудувати систему яку можна розширювати новими компонентами, і реалізувати “статичну типізацію” та “слабку типізацію”.
Одним словом те що ви могли почитати в трактаті про ZCA, тільки тепер в авторській озвучці, + можна буде задавати питання, і побачити мене в 3D. Головне руками не чіпати! 🙂
Тому якщо в кого виникне таке бажання – заходьте в Офіс Lohika Systems, Львів, вул. Лемківська 15а, 2-й поверх, 30-го травня. Реєстрація: http://www.meetup.com/uapycon/events/222342688/
І не переживайте, там доповідаю не тільки я.
Робота і життя після відпустки починається шалено (правда якщо врахувати що під час відпустки я більшість часу лише спав, їв і дихав), я навіть 10% всього цікавого зараз не розповів, але те що розповів – одне з найголовнішого. 🙂
Випадковий ідентифікатор в Python
Можна отримати так:
import random def random_id(length=6): return ''.join( random.choice(string.lowercase) for i in range(length) ) ############### >>> random_id() 'kqxmua'
Якщо треба особливо оформлений, як от IP, чи MAC-адреса, то можна зробити перетворення:
def asmac(val): """Convert a byte string to a MAC address string. """ return ':'.join('%02X' % ord(c) for c in val) def random_mac(): return asmac(random_id()) ################### >>> random_mac() '78:71:6A:72:6E:63'
Але такі ідентифікатори як “kqxmua” нормальній людині важко запам’ятати, бо вони не асоціюються з жодними поняттями. Ну окрім частинки “ua”, але й то вона туди випадково потрапила. Проте, в Linux можна легко отримати випадкове слово, бо в ньому є словник:
def random_word(): return random.choice( open('/usr/share/dict/words').readlines() # жертиме пам’ять! ).strip() ################# '.join(random_word() for i in range(5)) 'hermitical, Canter, Paryavi, mergences, Mind'
Хоча я знайомий лише з “hermitical” та “mind”, але асоціації вже легше побудувати, правда?
Зберегти всю стіну групи VK в таблицю
Якось під час чергового наближення економічної кризи захотілось проаналізувати ціну нерухомості в Львові. А ще, в той же час я наткнувся на документацію API Вконтакті. А так як своє житло я шукав в тому числі і в тій соціальній мережі, то вирішив проаналізувати наприклад спільноту vk.com/nomakler.
Ну, проаналізувати це легко сказати – важче зробити. Як витягти з повідомлення ціну, і як відрізнити попит від пропозиції? Га?
Але є половинний результат – ФСБ мусило поділитись частиною своєї бази даних розміром в 40450 оголошень. Тут можна її завантажити як tsv, xls чи інший зручний для вас формат. Може комусь, хто захоче збільшити конкуренцію серед львівськи маклерів/ріелторів знадобиться.
А якщо кому потрібна інформація з інших груп – ось скрипт. Викликаєте функцію save2tsv
з назвою групи і назвою файлу в який писати – і чекаєте поки завантажиться.
import requests import json from pprint import pprint from itertools import islice from datetime import datetime from butils.csv_wrapper import UnicodeWriter class APIError(Exception): pass def vk(method, **kwargs): ''' https://vk.com/dev/methods ''' r = requests.get( 'https://api.vk.com/method/%s' % method, params=kwargs ) js = json.loads(r.text) if js.get('error'): raise APIError(js['error']['error_msg']) return js['response'] def get_users(ids, known_users={}): request_ids = [i for i in ids if i not in known_users] if request_ids: user_ids=','.join(str(i) for i in request_ids if i > 0) if user_ids: users = vk('users.get', user_ids=user_ids) else: users = [] group_ids=','.join(str(-i) for i in request_ids if i < 0) if group_ids: groups = vk('groups.getById', group_ids=group_ids) else: groups = [] for user in users: known_users[int(user['uid'])] = dict( first_name = user['first_name'], last_name = user['last_name'], ) for group in groups: known_users[-int(group['gid'])] = dict( first_name = group['name'], last_name = group['gid'] ) return known_users def get_wall(domain): count = 50 offset = 0 def get_with_offset(offset): nonlocal count print('get_with_offset(%s)' % offset) total = vk('wall.get', domain=domain, count=1, )[0] off = total - offset - count if off < 0: count = count + off off = 0 return vk('wall.get', domain=domain, count=count, offset=off, )[1:][::-1] # remove first and reverse while True: posts = get_with_offset(offset) offset += count users = get_users(p['from_id'] for p in posts) for p in posts: yield p, users[p['from_id']] if count < 50: return def save2tsv(domain, dst): with UnicodeWriter(dst, encoding='utf-8', delimiter='\t') as writer: writer.writerow(( 'ID', 'Datetime', 'First name', 'Last name', 'Text', 'Type', 'Comments', 'Reposts', 'Likes', )) for p, user in get_wall(domain): writer.writerow(list(map(str, ( p['id'], # ID datetime.fromtimestamp(p['date']), # Datetime user['first_name'], # First name user['last_name'], # Last name p['text'], # Text p['post_type'], # Type p['comments']['count'], # Comments p['reposts']['count'], # Reposts p['likes']['count'], # Likes )))) # save2tsv('nomakler', 'nomakler.tsv')
Пишемо простий keylogger для Linux
Кейлоггер це така шкідлива корисна програма яка записує всі натискання клавіш користувачем в будь-яких інших програмах операційної системи. І сьогодні ми вивчатимемо як таке написати. Якщо ви навчитесь працювати з файлами в Linux – ви зможете все. Серйозно. Тому я колись планую детально вивчити і написати про файли там.
Все в лінуксі файл, і клавіатура – теж. Щоб знати який – відкриваємо /proc/bus/input/devices
. Нас цікавить абзац в якому написано про клавіатуру, і він зазвичай містить рядок EV=120013
, тому можете пошукати його. Коли знайшли абзац, читаємо в ньому рядок H: Handlers=sysrq kbd event3
.
Можна дістати однією командою:
cat /proc/bus/input/devices | grep EV=120013 -B 2 | grep event
Слово event3
означає що нам треба читати файл пристрою /dev/input/event3
.
Так як в заголовку було слово простий, ми спростимо собі життя і поставимо деяку бібліотеку:
pip-2.7 install evdev