Блоги Virtuos86
Tue, 19 Oct 2010 22:24:40 +0400Tue, 19 Oct 2010 22:24:40 +0400
\"А помнишь как всё начиналось...\"
-
Каким путём я пришёл к тому, что является на данный момент моим основным хобби: программирование вообще, и программирование на Python в частности?
-
Начну издалека.
На тот момент, когда в начале 2007 года у меня на руках очутился б/у\'шный Nokia 3250, почти ничего не предвещало такого интереса.
Хотя я был знаком очень \"шапочно\" с такими ЯП как Паскаль и QBasic, впрочем особых лавров мне это не принесло. Спасибо системе народного образования и методикам, в нём господствующим.
Единственное, я понял, что у меня есть интерес к программированию. Ну и плюс, в моём сердце навеки поселилась нелюбовь ко всему в чьем названии фигурирует слово \"Basic\".
-
Итак у меня есть смарт.
Процесс освоения Интернета шёл тяжело.
Естественно, я обшаривал все сайты с подходящим софтом.
Среди таких мне попался и dimonvideo.ru.
Правда зарегистрировался я здесь далеко не сразу, так как по-сравнения с аналогичными сайтами это вызвало у меня какие-то проблемы, которые сейчас и не вспомнишь.
\"Прогрессивная\" 3-я редакция Symbian довольно скоро стала поперек глотки из-за невозможности поставить желаемый софт.
Также оказалось что многие приложения под 9-ку очень любят устанавливаться в память телефона, а у меня её всего-то 10 мб!
Поэтому мой интерес привлекали приложения:
а) Небольшие
б) Полезные
в) Подписанные
Оказалось, что под первые два требования хорошо подходят приложения, написанные на Python (под третье мало что подходило, пока я последовательно не получил сертификат и затем не осуществил взлом).
Попутно я искал нельзя ли каким-либо программировать на смарте.
В процессе поисков наткнулся на замечательную статью Альберта Газетдинова с обзором всех доступных средств для программирования на смартфонах Нокиа.
Среди прочих мобайлбейсиков-дросов ...
Тут стоит сделать небольшое отступление.
-
Дрос -- это не ругательное слово, DROS -- это DOS-подобная оболочка, написанная на J2ME, со встроенными примитивным редактором с возможностью запуска программ и фтп-клиентом, для которой можно писать программы на некоем бейсикоподобном языке; можно также создать файл autoexec.bat, в котором указать файл с программой - расширение *.bas - которая будет запущена при запуске DROS. Одно время я даже переводил туториал к этой милой вещице, и написал парочку программ. Увы, огонь формата поглотил их безвозвратно.
Так вот среди прочих я обратил внимание на загадочный \"Python\".
-
Ага, подумал я.
На Python можно писать программы прямо на смартфоне.
И это не \"Basic\" (см. выше ^).
Это был первый шаг.
Когда же я обнаружил форум Python, понял что это -- то, что надо.
Воодушевленный этим энтузиазмом я приступил к КМБ - курсу молодого бойца - в виде цикла статей уже известного мне Альберта Газетдинова о программировании на PyS60.
Несмотря на ряд осложнений: большинство документации по Python собирали люди с \"ветеранами\", где стандартом для представления документов де-факто считался тогда (наверное и сейчас) формат *.rgo приложения ReplyGo.
На 9-ку его не было и нет, а читать *.pdf на 176/208 в PDF++ было чистейшей воды тихим ужасом.
Adobe Reader 2.5 с режимом подгонки изображения под экран вроде уже был, но я про него ещё не знал.
Текстовые же варианты статей изобиловали не то чтобы опечатками, но скорее сбитым форматированием текста.
И если русский язык я легко разбирал даже в таком виде, то питоновский код ...
Тем не менее процесс изучения пошёл.
С типичными вопросами новичков на форуме я не усердствовал, ибо во-первых читать доки можно не дожидаясь, когда тебя туда отправят , а во-вторых цель у меня была не написать поскорее что-то работающее, а научиться программированию.
-
Этими же принципами я в-принципе обхожусь и теперь.
Текущие мои помыслы связаны с редактором Kaapython.
Тут у меня противоречивые чувства.
С одной стороны Kaapython по сравнению с Ped -- большой шаг вперёд в плане удобства написания кода.
Ped сам по себе очень дружественен к пользователю. Все основные действия есть в главном меню и знать про шорткаты, чтобы использовать основные возможности редактора, совсем необязательно.
Мультиоконность Ped среди других Python-редакторов аналогов, кажется, не имеет.
Можно подумать их авторы никогда не редактировали больше одного скрипта зараз (в Pysaka другой подход используется, интересный, но это не совсем мульти-пульти).
Себе в актив я могу занести полную русификацию редактора. Это сделало его ещё более дружественным к пользователю.
Да, из коробки в редакторе включен по умолчанию английский язык. Но ведь не секрет, что программы на Python никак не защищены от тырения заграничными товарищами.
Пускай уж пользуются моим, более-менее адекватным переводом, чем если те же китайцы вздумают переводить с русского.
А переключить язык редактора довольно просто.
Кроме того очень важная фича это подсветка синтаксиса языка. Фича уникальная, поэтому рассуждать о ней особо не стану -- пусть сначала её где-нибудь ещё реализуют, вот тогда я расскажу чем подсветка синтаксиса в Kaapython лучше .
Ещё одной фичей я доволен -- расширенным автодополнением. Теперь я практически не боюсь давать длинные и путаные идентификаторы переменным и функциям.
Например я пишу:
Any_long_NAme_with_underlines = 5
Теперь мне достаточно нажать 2-6, затем Green-Select и я могу выбрать это имя из списка автодополнения. Заметьте я не говорю, набрать \"an\", речь идёт именно о клавишах 2 и 6. А будет ли набрано \"An\", \"aN\", \"AN\", \"an\" или \"Бу\", \"бу\" etc. неважно.
-
Но есть одно \"но\".
Редактор стал менее стабильным, а при продолжительной работе начинает тормозить.
Ещё у меня претензии к схеме перехвата нажатий на клавиши.
Аркадиус большой молодец, что придумал, как осуществить перехват нажатий без использования модуля keycapture. Это плюс. Но минус хуже: при достаточно больших размерах скрипта эта схема тормозит, особенно когда используешь цепочку из нескольких шорткатов.
-
Недавно уговаривали написать редактор с нуля.
Времени нет, но я начал.
Virtuos86
\"А помнишь как всё начиналось...\" - Каким путём я пришёл к тому, что является на данный момент моим основным хобби: программирование вообще, [...]
читать полностью
1011
Комментарии: 7
Блоги Virtuos86
Tue, 21 Sep 2010 22:12:59 +0400Tue, 21 Sep 2010 22:12:59 +0400
Есть такая штучка хорошая в редакторе Kaapython как плагины.
Они могут помочь умелому пользователю сгладить шероховатости, возникающие при работе с редактором.
По настоящему стоящие плагины могут впоследствие быть переведены непосредственно в код редактора.
Простейшее руководство по их написанию и идеи-приемы, используемые при этом, я сейчас и изложу.
Итак, начнем.
|
---- Предварительные..., гм, приготовления
|
1.) Для написания любого плагина Вам понадобится в первую очередь иметь перед глазами и под рукой исходный код редактора в удобном для чтения и копирования виде.
Я использую для этого отличный текстовый редактор Dedit Юрия Бакунина aka jbak.
Почему я не использую для этого сам Kaapython, спросят зловредные злопыхатели?
По кочану и по кочерыжке.
На данный момент главный скрипт -- kaapython.py -- имеет размер около 140 кб.
Экземпляры appuifw.Text не могут вместить столько текста!
Извините, это был вопль души.
Разбить kaapython.py на несколько связанных модулей? Вариант, но и тут подводных камней хватает, поверьте мне на слово. Или можете не верить, но тогда... просто сделайте это сами и подарите мне результат ваших бескорыстных трудов.
2.) Теперь небольшая справка.
Каждый плагин по сути это подпакет (я буду так называть пакет, вложенный в другой, "родительский", пакет) в пакете "plugins", размещенном в папке программы.
При старте редактора, упрощено говоря, происходит импорт всех этих подпакетов, то есть (для тех, кто не в курсе, как работает импорт модулей) файлов __init__.py, размещенных в папках подпакетов.
|
---- И, начали! Документация
|
Напишем, вернее создадим, простой плагин "Hello, World!".
Как и полагается плагину с таким названием, он будет делать ровно ничего.
Сначала создадим в папке plugins папку hello_world.
Добавим к нашему плагину документацию (да, именно так, солидно и серьезно): для этого храброго дела создадим подпапку help для встроенной в Kaapython утилиты для просмотра документации.
В этой папке должны быть размещены текстовые файлы с именами English, Russian, Deutsch etc.
Таким образом, в них размещается справочная информация по плагину и, в зависимости от установленного в редакторе языка, откроется соответствующий файл помощи.
Как вы понимаете, если у вас нет олбанской локализации для всего редактора, то нет смысла и для плагина создавать файл помощи "Olbanian".
Я рекомендую создавать файл English. Английский язык используется в редакторе дефолтно. И справочную информацию рекомендую предоставлять на английском.
Но в данном случае мы создадим файл Russian.
Пропишем в хелпе назначение плагина, способ использования и наш копирайт :) -- стандартная сборная солянка:
|
Простой плагин для вывода информационного сообщения с текстом "Hello, World!". Чтобы использовать плагин, назначьте функцию "Hello, World!" на какой-либо шорткат, используя диалог Установок.
Copyright (c) 2010, %username%
Distributed under the new BSD license.
|
---- Продолжаем. Локализация
|
Теперь добавим локализацию для нашего плагина, то бишь русификатор в моем конкретном случае.
Создаем подпапку lang в папке hello_world (директория нашего плагина, если вы помните), в ней файл Russian.
В нём будет одна пара ключ-значение:
'Hello, World!': 'Привет, Мир!'.decode('utf-8')
Как уже неоднократно говорилось, в зависимости от текущего языка редактора (English по умолчанию) будут использоваться соответствующие строки.
|
---- Ага! Объявляем манифест.
|
Далее заполняем манифест.
Что прописывается в манифесте?:
Kaapython-Version-Max: 1.0.0
Version: 1.00.0
Kaapython-Version-Min: 0.00.0
Name: Hello, World!
Package: hello_world
Имя и версия будут отображаться в списке установленных плагинов. Максимальная/минимальная версии Kaapython'а покажут под какими версиями редактора плагин будет работать корректно.
Лучше всего указывать в качестве максимальной текущую версию.
Так как я не гарантирую, что даже минорные релизы не повлекут за собой кардинальные изменения и не сломают работу плагинов :).
Пункт Сверток предназначен для установки плагина из зип-архива. Это имя домашней папки плагина.
При его установке через стандартный инсталлятор редактора (Инструменты -> Плагины -> Установить...) будет создана папка с таким именем, и в ней будут размещены все файлы плагина.
|
---- Пишем код
|
Так, теперь, разобравшись с рутиной, вернемся к собственно плагину.
Создаем новый файл __init__.py (впоследствие, как и любой другой модуль, можно его скомпилировать для экономии времени загрузки редактора) в папке плагина.
#
Первыми строками укажем
import kaapython
import ui
Так или иначе, работа любого плагина состоит либо в изменении стандартной функциональности редактора, либо в дополнении оной.
Поэтому мы подключаем весь доступный функционал редактора.
Модуль ui содержит классы, функции и константы для работы с интерфейсом и представляет из себя по сути минифреймворк, который можно использовать отдельно.
Модуль kaapython представляет сам редактор со всем его функционалом.
#
Итак, код плагина. Пояснения ниже.
def get_shortcuts(cls):
menu = old_get_shortcuts()
menu.append(ui.MenuItem(_('Hello, World!'), target=hello_world))
return menu
def hello_world():
note(_('Hello, World!'))
_ = kaapython.get_plugin_translator(__file__)
old_get_shortcuts = kaapython.repattr(kaapython.PythonFileWindow, 'get_shortcuts', classmethod(get_shortcuts))
|
---- Что к чему
|
Начнем с этой строчки
...
_ = kaapython.get_plugin_translator(__file__)
...
В Ped/Kaapython переменная "_" обычно является транслятором-переводчиком дефолтных ascii-строк в Юникод, для решения проблемы национальной локализации редактора.
Транслятор принимает на вход обычную строку (ключ в словарных файлах типа ".../lang/Russian"), и возвращает, грубо говоря, её "перевод".
В __file__ содержится путь к файлу плагина, так как он импортируется как модуль.
Таким образом, в строке кода, приведенной выше, мы получаем языковой транслятор для нашего плагина. Он будет оперировать ключами и значениями, определенными в подготовленном нами файле plugins/hello_world/lang/Russian (естественно, если текущий язык редактора - русский). Там всего один ключ "Hello, World!", и соответствующее ему значение "Привет, Мир!". Но нам для наших нужд больше и не потребуется :).
##############
...
def get_shortcuts(cls):
menu = old_get_shortcuts()
menu.append(ui.MenuItem(_('Hello, World!'), target=hello_world))
return menu
...
и
...
old_get_shortcuts = kaapython.repattr(kaapython.PythonFileWindow, 'get_shortcuts', classmethod(get_shortcuts))
...
Утилитная функция repattr устанавливает новое значение атрибута некоторого объекта, ссылку на который в неё передают, в данном случае это метод PythonFileWindow.get_shortcuts, и возвращает старое.
В get_shortcuts мы вызываем старый, дефолтный, метод для получения списка шорткатов и добавляем в этот список наш новый шорткат.
Класс kaapython.PythonFileWindow представляет собой основу для каждого скрипта, редактируемого в редакторе. Отличный пример тавтологии, кстати :-).
Если вы создаете или открываете Python скрипт, то он будет представлен внутри редактора экземпляром этого класса.
Небольшое большое отступление: внутри редактора выстроена целая иерархия классов. Так, например, PythonFileWindow наследует от TextFileWindow, TextFileWindow от TextWindow, TextWindow от Window, Window от ui.Window.
Это даёт гибкость, которую, думаю, оценят понимающие толк в ООП, которой к сожалению, никак не удается воспользоваться в полной мере :( по причине нехватки свободного времени.
Отсюда же становится понятным для чего в Установках Kaapython есть несколько разделов с установкой шорткатов.
Метод get_shortcuts возвращает список шорткатов. Понятное дело не для каждого экземпляра класса, а для класса как класса данных. Для текстовых файлов, являющихся экземплярами класса TextFileWindow вернется один список шорткатов, для скриптов (PythonFileWindow) этот же список, но дополненный Python-специфичными фичами.
Соответственно, если вам придет в голову добавить новый класс для работы, например, с вебстраницами (*.html), то лучше всего наследовать этот класс WebPageFileWindow от класса TextFileWindow.
Ещё немного "химии" и вы получите автоматом простой вебредактор.
Возвращаясь к теме шорткатов, можно добавить, что если есть шорткаты, которыми вы привыкли пользоваться везде и всюду, то помещайте их ближе к корню наследования: если возможно, установите их в глобальных шорткатах, или текстовых шорткатах, чтобы не дублировать их в нескольких наборах.
##############
Итак, плагин написан.Теперь остается только перезапустить редактор, и испытать наш хелловорлд в действии.
Если упаковать папку плагина в зип-архив (в X-plore для этого достаточно выделить Карандашом папку и нажать клавишу вызова, на 9-ках без Карандаша нужно зажать Решетку и нажать клавишу вызова), то его можно распространять для установки непосредственно из самого редактора.
##############
Кстати говоря, в процессе испытания плагина я обнаружил и устранил (благодаря счастливой случайности :)) очень неприятный баг, который, судя по всему достался в наследство от Ped'а.
Вот такой он старый и замшелый. Неприятен он был тем, что был непонятен. Потому что написав несколько строк кода, которые понятны насквозь, трудно найти причины возникающей ошибки, которая ни на первый, ни на второй взгляд никак не связана с добавочным кодом.
################
Я оставляю неосвещенным такой момент как работа с главным меню, а также со всевозможными стандартными менюшками и диалогами.
Здесь тоже немного запутано и оригинально. Но на самом деле довольно хорошо придумано.
Virtuos86
Есть такая штучка хорошая в редакторе Kaapython как плагины. Они могут помочь умелому пользователю сгладить шероховатости, возникающие при работе [...]
читать полностью
1455
Комментарии: 7
Блоги Virtuos86
Fri, 10 Sep 2010 10:20:14 +0400Fri, 10 Sep 2010 10:20:14 +0400
Пока переписывал игру неоднократно возникала мысль о том, что в Kaapython нет инструмента для работы не с одиночным скриптом, а с целым проектом. То есть это произвольное количество связанных модулей, прочих ресурсов к проекту (например, картинок, файлов настроек) и т.д..
Существующий механизм сессий не слишком хорош для этого.
Думаю этим заняться, когда управлюсь с текущими задачами.
Соответственно, должно где-то быть записано имя проекта и все зависимости к нему.
Возможно, некоторую инфу придётся помешать непосредственно в код модулей в виде неких тегов.
Самое главное, что есть четкое представление что нужно делать, чтобы получилось хорошо. И закладки можно будет реализовать лучше, чем сейчас сделано.
Так что ждите.
Думаю, это будет отличная идешная фича для реально пишущих питонщиков.
Virtuos86
Пока переписывал игру неоднократно возникала мысль о том, что в Kaapython нет инструмента для работы не с одиночным скриптом, а с целым проектом. [...]
читать полностью
607
Комментарии: 6
Блоги Virtuos86
Sun, 01 Aug 2010 10:41:14 +0400Sun, 01 Aug 2010 10:41:14 +0400
Откопал рассылку на сабскрайб.ру "Создание ролевой компьютерной игры".
Полностью описан процесс создания РПГ на турбопаскале(а затем и дельфи).
Ни то, ни другое мне не доступно, зато есть Python.
Да и меня интересует больше теория.
Kaapython на время оставлен.
Virtuos86
Откопал рассылку на сабскрайб.ру "Создание ролевой компьютерной игры". Полностью описан процесс создания РПГ на турбопаскале(а затем и дельфи). [...]
читать полностью
745
Комментарии: 10
Блоги Virtuos86
Sat, 31 Jul 2010 12:26:10 +0400Sat, 31 Jul 2010 12:26:10 +0400
Symbian 9
---------------------
Symbian 7-8
---------------------
Сделано косметическое изменение в Установках, повлекшее, несмотря на свою незначительность, несовместимость с прежними настройками.
Поэтому приготовьтесь настраивать всё заново :-).
Добавлена возможность добавления закладок в редактируемые файлы.
Самое значимое изменение, оправдывающее релиз -- подхачено Автодополнение.
Читайте хелп, там подробно всё описано.
Virtuos86
Symbian 9 --------------------- Symbian 7-8 --------------------- Сделано косметическое изменение в Установках, повлекшее, несмотря на свою незначительность, несовместимость [...]
читать полностью
1012
Комментарии: 8
Блоги Virtuos86
Tue, 06 Jul 2010 22:09:14 +0400Tue, 06 Jul 2010 22:09:14 +0400
===========
Ликбез: цикл - это то, что повторяется "по кругу".
===========
Цикл for: осваиваем школьный английский.
-----------
Цикла for в Python НЕТ!
Есть цикл for ... in ...
Поэтому не надо говорить, что де, вон, к примеру, в C ("Си") for так for (далее следует псевдокод из смеси C и Python :)):
<!--code1--><!--ecode1-->
for (i=0; i < len('a little string'); i ) ...
<!--code2--><!--ecode2-->
- а в Python то же самое придётся писать так:
<!--code1--><!--ecode1-->
i = 0
for i in 'a little string':
i = i 1
...
<!--code2--><!--ecode2-->
(правильно, конечно, писать "for i in 'a little string': ...")
--
Цикл for-in может называться циклом только с версии Python 2.2. Именно начиная с неё, for-in обрабатывает итератор, который может (но не обязан) быть циклическим.
Более того. Цикл for-in умеет обрабатывать говорящее само за себя исключение StopIteration, которое возбуждает итератор, когда исчерпывается, умалчивая его, и принимая его за команду завершить свою работу.
Обычно же for-in, грубо говоря, аналогичен тривиальному обходу последовательности, который выполняют функции map-filter-reduce.
Чем хороши итераторы в отличии от последовательностей?
Последовательности создаются сразу и целиком, размещаются в памяти, и Python не может их удалить, пока цикл не обойдет их до конца.
Это дорого. Большие последовательности занимают много места, но ведь в каждом витке цикла используется только один член последовательности. Зачем же нам все остальные?
Итераторы решают эту проблему. Они выдают значения по-одному по какому-либо правилу, при этом нет таких затрат памяти.
--
Как я уже отметил классического цикла for в Python нет, поэтому придирки выглядят просто неумно: как можно спорить о том, чего нет?! :)
--
Как выглядит цикл for-in:
<!--code1--><!--ecode1-->for("для") <переменная цикла> in("в") <итератор или объект, который может предоставить итератор при получении специального сообщения>:
<делать что-нибудь, в том числе и ничего не делать><!--code2--><!--ecode2-->
===========
Ликбез:
--
Сообщения, передаваемые объекту - в объектной модели Python так называются методы объекта, в данном случае подразумевается метод next.
--
Итератор - объект, у которого есть метод next. Чтобы проще понять что это такое, представьте себе очередь перед кабинетом врача, например. Когда врач высовывается и говорит 'Следующий', очередь двигается.
При этом врачу не нужно всех созывать в кабинет. В кабинете находится всегда только один пациент, отсюда нет толкучки, тесноты и давки в кабинете (иначе, моё описание подошло бы и к последовательностям, а не только к итераторам).
Врач может также сказать "Женщина, которая последняя сидит (стоит), с грудным ребенком(из середины, третья с конца и т.д.) подойдите".
Вы скажете, нет таких врачей и|или очередей. Согласен, почти нет. Вот и итераторы в Python ведут себя так же - одни умеют только в порядке очереди (тавтология :-)) выдавать "следующего", и если попросить их нарушить этот порядок, возмутятся, а другие, м-м-м, более покладисты, что ли.
===========
Итак:
--
Цикл(врач) говорит (отправляет сообщение, то бишь обращается(вызывает) метод) очереди (итератору) "следующий" ("next" по-английски => метод next)
--
Также чтобы как-то общаться с пациентами (называть их) врач выбирает какую-то условную форму. Это либо вежливое "Вы", или свойское "ты", или там "голубчик/голубушка" и т.д..
--
Запишем это в псевдосинтаксисе:
<!--code1--><!--ecode1-->для Вы в очередь:
Вы = очередь.__следующий__()
...<!--code2--><!--ecode2-->
Да вот беда. Python интерпретатор. Когда он встречает какое-либо имя в тексте программы, он должен непременно узнать, кто за этим именем скрывается. Когда Python доходит до Вы, то он ещё не знает, что Вы это очередь.__следующий__(), поэтому Вы = очередь.__следующий__() не пишется, и подразумевается, что если уж есть очередь, то Вы - это каждый "следующий" кто-то из неё.
Таким образом брюки превращаются...:
<!--code1--><!--ecode1-->
для Вы в очередь:
...
<!--code2--><!--ecode2-->
--
Или на Python
<!--code1--><!--ecode1-->
for You in queue:
...
<!--code2--><!--ecode2-->
--
Теперь в теле цикла (это то самое загадочное многоточие ;-)) вы (читатели) вольны делать что угодно с You (Вы).
Конечно же, в рамках текущего законодательства вашего государства.
---
Нужно также упомянуть два оператора: break и continue. Применение первого прерывает цикл (врач говорит, что его рабочий день закончен, с завтрашнего дня начинается отпуск, а потом он вообще уволится - иными словами, приём закончен); второй позволяет циклу сказать 'следующий', не дожидаясь когда закончится текущая итерация (то бишь тело цикла).
---
Казалось бы всё? Нет.
А что если вместо итератора for-in получит строку, список или кортеж? Допустим мы с вами не умеем готовить итераторы. Никаких проблем.
Как я и оговорил в описании цикла, for-in принимает либо итератор, либо объект, имеющий метод __iter__, который должен возвращать итератор.
Поскольку в Python к специальным методам, чьи имена начинаются с двух символов подчеркивания и на них же и заканчиваются, не принято обращаться напрямую (в самом деле, Object.__iter__() смотрится коряво), довольно часто есть одноименная встроенная функция, в данном случае iter.
Цикл вызывает iter(), и обрабатывает полученный итератор.
---
Напоследок изюминка:
iter(f, sentinel)
Вот такой вот вызов возвращает итератор, который при работе в цикле будет вызывать вызываемый объект f, пока тот не вернет значение (объект) sentinel.
---
Virtuos86
===========Ликбез: цикл - это то, что повторяется "по кругу".===========Цикл for: осваиваем школьный английский.-----------Цикла for в Python НЕТ!Есть цикл for ... in [...]
читать полностью
1102
Комментарии: 4
Блоги Virtuos86
Mon, 05 Jul 2010 21:35:00 +0400Mon, 05 Jul 2010 21:35:00 +0400
Вот в такую же ночь (на Ивана Купала) герой гоголевского произведения поимел диковинные приключения на свою голову. Жгите костры, плетите венки, кружите хороводы, но только не пытайтесь искать цветок папоротника.
Вот как-то так.
Virtuos86
Вот в такую же ночь (на Ивана Купала) герой гоголевского произведения поимел диковинные приключения на свою голову. Жгите костры, плетите [...]
читать полностью
904
Комментарии: 1


-
Каким путём я пришёл к тому, что является на данный момент моим основным хобби: программирование вообще, и программирование на Python в частности?
-
Начну издалека.
На тот момент, когда в начале 2007 года у меня на руках очутился б/у\'шный Nokia 3250, почти ничего не предвещало такого интереса.
Хотя я был знаком очень \"шапочно\" с такими ЯП как Паскаль и QBasic, впрочем особых лавров мне это не принесло. Спасибо системе народного образования и методикам, в нём господствующим.
Единственное, я понял, что у меня есть интерес к программированию. Ну и плюс, в моём сердце навеки поселилась нелюбовь ко всему в чьем названии фигурирует слово \"Basic\".
-
Итак у меня есть смарт.
Процесс освоения Интернета шёл тяжело.
Естественно, я обшаривал все сайты с подходящим софтом.
Среди таких мне попался и dimonvideo.ru.
Правда зарегистрировался я здесь далеко не сразу, так как по-сравнения с аналогичными сайтами это вызвало у меня какие-то проблемы, которые сейчас и не вспомнишь.
\"Прогрессивная\" 3-я редакция Symbian довольно скоро стала поперек глотки из-за невозможности поставить желаемый софт.
Также оказалось что многие приложения под 9-ку очень любят устанавливаться в память телефона, а у меня её всего-то 10 мб!
Поэтому мой интерес привлекали приложения:
а) Небольшие
б) Полезные
в) Подписанные
Оказалось, что под первые два требования хорошо подходят приложения, написанные на Python (под третье мало что подходило, пока я последовательно не получил сертификат и затем не осуществил взлом).
Попутно я искал нельзя ли каким-либо программировать на смарте.
В процессе поисков наткнулся на замечательную статью Альберта Газетдинова с обзором всех доступных средств для программирования на смартфонах Нокиа.
Среди прочих мобайлбейсиков-дросов ...
Тут стоит сделать небольшое отступление.
-
Дрос -- это не ругательное слово, DROS -- это DOS-подобная оболочка, написанная на J2ME, со встроенными примитивным редактором с возможностью запуска программ и фтп-клиентом, для которой можно писать программы на некоем бейсикоподобном языке; можно также создать файл autoexec.bat, в котором указать файл с программой - расширение *.bas - которая будет запущена при запуске DROS. Одно время я даже переводил туториал к этой милой вещице, и написал парочку программ. Увы, огонь формата поглотил их безвозвратно.
Так вот среди прочих я обратил внимание на загадочный \"Python\".
-
Ага, подумал я.
На Python можно писать программы прямо на смартфоне.
И это не \"Basic\" (см. выше ^).
Это был первый шаг.
Когда же я обнаружил форум Python, понял что это -- то, что надо.
Воодушевленный этим энтузиазмом я приступил к КМБ - курсу молодого бойца - в виде цикла статей уже известного мне Альберта Газетдинова о программировании на PyS60.
Несмотря на ряд осложнений: большинство документации по Python собирали люди с \"ветеранами\", где стандартом для представления документов де-факто считался тогда (наверное и сейчас) формат *.rgo приложения ReplyGo.
На 9-ку его не было и нет, а читать *.pdf на 176/208 в PDF++ было чистейшей воды тихим ужасом.
Adobe Reader 2.5 с режимом подгонки изображения под экран вроде уже был, но я про него ещё не знал.
Текстовые же варианты статей изобиловали не то чтобы опечатками, но скорее сбитым форматированием текста.
И если русский язык я легко разбирал даже в таком виде, то питоновский код ...
Тем не менее процесс изучения пошёл.
С типичными вопросами новичков на форуме я не усердствовал, ибо во-первых читать доки можно не дожидаясь, когда тебя туда отправят , а во-вторых цель у меня была не написать поскорее что-то работающее, а научиться программированию.
-
Этими же принципами я в-принципе обхожусь и теперь.
Текущие мои помыслы связаны с редактором Kaapython.
Тут у меня противоречивые чувства.
С одной стороны Kaapython по сравнению с Ped -- большой шаг вперёд в плане удобства написания кода.
Ped сам по себе очень дружественен к пользователю. Все основные действия есть в главном меню и знать про шорткаты, чтобы использовать основные возможности редактора, совсем необязательно.
Мультиоконность Ped среди других Python-редакторов аналогов, кажется, не имеет.
Можно подумать их авторы никогда не редактировали больше одного скрипта зараз (в Pysaka другой подход используется, интересный, но это не совсем мульти-пульти).
Себе в актив я могу занести полную русификацию редактора. Это сделало его ещё более дружественным к пользователю.
Да, из коробки в редакторе включен по умолчанию английский язык. Но ведь не секрет, что программы на Python никак не защищены от тырения заграничными товарищами.
Пускай уж пользуются моим, более-менее адекватным переводом, чем если те же китайцы вздумают переводить с русского.
А переключить язык редактора довольно просто.
Кроме того очень важная фича это подсветка синтаксиса языка. Фича уникальная, поэтому рассуждать о ней особо не стану -- пусть сначала её где-нибудь ещё реализуют, вот тогда я расскажу чем подсветка синтаксиса в Kaapython лучше .
Ещё одной фичей я доволен -- расширенным автодополнением. Теперь я практически не боюсь давать длинные и путаные идентификаторы переменным и функциям.
Например я пишу:
Any_long_NAme_with_underlines = 5
Теперь мне достаточно нажать 2-6, затем Green-Select и я могу выбрать это имя из списка автодополнения. Заметьте я не говорю, набрать \"an\", речь идёт именно о клавишах 2 и 6. А будет ли набрано \"An\", \"aN\", \"AN\", \"an\" или \"Бу\", \"бу\" etc. неважно.
-
Но есть одно \"но\".
Редактор стал менее стабильным, а при продолжительной работе начинает тормозить.
Ещё у меня претензии к схеме перехвата нажатий на клавиши.
Аркадиус большой молодец, что придумал, как осуществить перехват нажатий без использования модуля keycapture. Это плюс. Но минус хуже: при достаточно больших размерах скрипта эта схема тормозит, особенно когда используешь цепочку из нескольких шорткатов.
-
Недавно уговаривали написать редактор с нуля.
Времени нет, но я начал.



\"А помнишь как всё начиналось...\" - Каким путём я пришёл к тому, что является на данный момент моим основным хобби: программирование вообще, [...] читать полностью
1011


Они могут помочь умелому пользователю сгладить шероховатости, возникающие при работе с редактором.
По настоящему стоящие плагины могут впоследствие быть переведены непосредственно в код редактора.
Простейшее руководство по их написанию и идеи-приемы, используемые при этом, я сейчас и изложу.
Итак, начнем.
|
---- Предварительные..., гм, приготовления
|
1.) Для написания любого плагина Вам понадобится в первую очередь иметь перед глазами и под рукой исходный код редактора в удобном для чтения и копирования виде.
Я использую для этого отличный текстовый редактор Dedit Юрия Бакунина aka jbak.
Почему я не использую для этого сам Kaapython, спросят зловредные злопыхатели?
По кочану и по кочерыжке.
На данный момент главный скрипт -- kaapython.py -- имеет размер около 140 кб.
Экземпляры appuifw.Text не могут вместить столько текста!
Извините, это был вопль души.
Разбить kaapython.py на несколько связанных модулей? Вариант, но и тут подводных камней хватает, поверьте мне на слово. Или можете не верить, но тогда... просто сделайте это сами и подарите мне результат ваших бескорыстных трудов.
2.) Теперь небольшая справка.
Каждый плагин по сути это подпакет (я буду так называть пакет, вложенный в другой, "родительский", пакет) в пакете "plugins", размещенном в папке программы.
При старте редактора, упрощено говоря, происходит импорт всех этих подпакетов, то есть (для тех, кто не в курсе, как работает импорт модулей) файлов __init__.py, размещенных в папках подпакетов.
|
---- И, начали! Документация
|
Напишем, вернее создадим, простой плагин "Hello, World!".
Как и полагается плагину с таким названием, он будет делать ровно ничего.
Сначала создадим в папке plugins папку hello_world.
Добавим к нашему плагину документацию (да, именно так, солидно и серьезно): для этого храброго дела создадим подпапку help для встроенной в Kaapython утилиты для просмотра документации.
В этой папке должны быть размещены текстовые файлы с именами English, Russian, Deutsch etc.
Таким образом, в них размещается справочная информация по плагину и, в зависимости от установленного в редакторе языка, откроется соответствующий файл помощи.
Как вы понимаете, если у вас нет олбанской локализации для всего редактора, то нет смысла и для плагина создавать файл помощи "Olbanian".
Я рекомендую создавать файл English. Английский язык используется в редакторе дефолтно. И справочную информацию рекомендую предоставлять на английском.
Но в данном случае мы создадим файл Russian.
Пропишем в хелпе назначение плагина, способ использования и наш копирайт :) -- стандартная сборная солянка:
|
Простой плагин для вывода информационного сообщения с текстом "Hello, World!". Чтобы использовать плагин, назначьте функцию "Hello, World!" на какой-либо шорткат, используя диалог Установок.
Copyright (c) 2010, %username%
Distributed under the new BSD license.
|
---- Продолжаем. Локализация
|
Теперь добавим локализацию для нашего плагина, то бишь русификатор в моем конкретном случае.
Создаем подпапку lang в папке hello_world (директория нашего плагина, если вы помните), в ней файл Russian.
В нём будет одна пара ключ-значение:
'Hello, World!': 'Привет, Мир!'.decode('utf-8')
Как уже неоднократно говорилось, в зависимости от текущего языка редактора (English по умолчанию) будут использоваться соответствующие строки.
|
---- Ага! Объявляем манифест.
|
Далее заполняем манифест.
Что прописывается в манифесте?:
Kaapython-Version-Max: 1.0.0
Version: 1.00.0
Kaapython-Version-Min: 0.00.0
Name: Hello, World!
Package: hello_world
Имя и версия будут отображаться в списке установленных плагинов. Максимальная/минимальная версии Kaapython'а покажут под какими версиями редактора плагин будет работать корректно.
Лучше всего указывать в качестве максимальной текущую версию.
Так как я не гарантирую, что даже минорные релизы не повлекут за собой кардинальные изменения и не сломают работу плагинов :).
Пункт Сверток предназначен для установки плагина из зип-архива. Это имя домашней папки плагина.
При его установке через стандартный инсталлятор редактора (Инструменты -> Плагины -> Установить...) будет создана папка с таким именем, и в ней будут размещены все файлы плагина.
|
---- Пишем код
|
Так, теперь, разобравшись с рутиной, вернемся к собственно плагину.
Создаем новый файл __init__.py (впоследствие, как и любой другой модуль, можно его скомпилировать для экономии времени загрузки редактора) в папке плагина.
#
Первыми строками укажем
import kaapython
import ui
Так или иначе, работа любого плагина состоит либо в изменении стандартной функциональности редактора, либо в дополнении оной.
Поэтому мы подключаем весь доступный функционал редактора.
Модуль ui содержит классы, функции и константы для работы с интерфейсом и представляет из себя по сути минифреймворк, который можно использовать отдельно.
Модуль kaapython представляет сам редактор со всем его функционалом.
#
Итак, код плагина. Пояснения ниже.
def get_shortcuts(cls):
menu = old_get_shortcuts()
menu.append(ui.MenuItem(_('Hello, World!'), target=hello_world))
return menu
def hello_world():
note(_('Hello, World!'))
_ = kaapython.get_plugin_translator(__file__)
old_get_shortcuts = kaapython.repattr(kaapython.PythonFileWindow, 'get_shortcuts', classmethod(get_shortcuts))
|
---- Что к чему
|
Начнем с этой строчки
...
_ = kaapython.get_plugin_translator(__file__)
...
В Ped/Kaapython переменная "_" обычно является транслятором-переводчиком дефолтных ascii-строк в Юникод, для решения проблемы национальной локализации редактора.
Транслятор принимает на вход обычную строку (ключ в словарных файлах типа ".../lang/Russian"), и возвращает, грубо говоря, её "перевод".
В __file__ содержится путь к файлу плагина, так как он импортируется как модуль.
Таким образом, в строке кода, приведенной выше, мы получаем языковой транслятор для нашего плагина. Он будет оперировать ключами и значениями, определенными в подготовленном нами файле plugins/hello_world/lang/Russian (естественно, если текущий язык редактора - русский). Там всего один ключ "Hello, World!", и соответствующее ему значение "Привет, Мир!". Но нам для наших нужд больше и не потребуется :).
##############
...
def get_shortcuts(cls):
menu = old_get_shortcuts()
menu.append(ui.MenuItem(_('Hello, World!'), target=hello_world))
return menu
...
и
...
old_get_shortcuts = kaapython.repattr(kaapython.PythonFileWindow, 'get_shortcuts', classmethod(get_shortcuts))
...
Утилитная функция repattr устанавливает новое значение атрибута некоторого объекта, ссылку на который в неё передают, в данном случае это метод PythonFileWindow.get_shortcuts, и возвращает старое.
В get_shortcuts мы вызываем старый, дефолтный, метод для получения списка шорткатов и добавляем в этот список наш новый шорткат.
Класс kaapython.PythonFileWindow представляет собой основу для каждого скрипта, редактируемого в редакторе. Отличный пример тавтологии, кстати :-).
Если вы создаете или открываете Python скрипт, то он будет представлен внутри редактора экземпляром этого класса.
Небольшое большое отступление: внутри редактора выстроена целая иерархия классов. Так, например, PythonFileWindow наследует от TextFileWindow, TextFileWindow от TextWindow, TextWindow от Window, Window от ui.Window.
Это даёт гибкость, которую, думаю, оценят понимающие толк в ООП, которой к сожалению, никак не удается воспользоваться в полной мере :( по причине нехватки свободного времени.
Отсюда же становится понятным для чего в Установках Kaapython есть несколько разделов с установкой шорткатов.
Метод get_shortcuts возвращает список шорткатов. Понятное дело не для каждого экземпляра класса, а для класса как класса данных. Для текстовых файлов, являющихся экземплярами класса TextFileWindow вернется один список шорткатов, для скриптов (PythonFileWindow) этот же список, но дополненный Python-специфичными фичами.
Соответственно, если вам придет в голову добавить новый класс для работы, например, с вебстраницами (*.html), то лучше всего наследовать этот класс WebPageFileWindow от класса TextFileWindow.
Ещё немного "химии" и вы получите автоматом простой вебредактор.
Возвращаясь к теме шорткатов, можно добавить, что если есть шорткаты, которыми вы привыкли пользоваться везде и всюду, то помещайте их ближе к корню наследования: если возможно, установите их в глобальных шорткатах, или текстовых шорткатах, чтобы не дублировать их в нескольких наборах.
##############
Итак, плагин написан.Теперь остается только перезапустить редактор, и испытать наш хелловорлд в действии.
Если упаковать папку плагина в зип-архив (в X-plore для этого достаточно выделить Карандашом папку и нажать клавишу вызова, на 9-ках без Карандаша нужно зажать Решетку и нажать клавишу вызова), то его можно распространять для установки непосредственно из самого редактора.
##############
Кстати говоря, в процессе испытания плагина я обнаружил и устранил (благодаря счастливой случайности :)) очень неприятный баг, который, судя по всему достался в наследство от Ped'а.
Вот такой он старый и замшелый. Неприятен он был тем, что был непонятен. Потому что написав несколько строк кода, которые понятны насквозь, трудно найти причины возникающей ошибки, которая ни на первый, ни на второй взгляд никак не связана с добавочным кодом.
################
Я оставляю неосвещенным такой момент как работа с главным меню, а также со всевозможными стандартными менюшками и диалогами.
Здесь тоже немного запутано и оригинально. Но на самом деле довольно хорошо придумано.



Есть такая штучка хорошая в редакторе Kaapython как плагины. Они могут помочь умелому пользователю сгладить шероховатости, возникающие при работе [...] читать полностью
1455


Существующий механизм сессий не слишком хорош для этого.
Думаю этим заняться, когда управлюсь с текущими задачами.
Соответственно, должно где-то быть записано имя проекта и все зависимости к нему.
Возможно, некоторую инфу придётся помешать непосредственно в код модулей в виде неких тегов.
Самое главное, что есть четкое представление что нужно делать, чтобы получилось хорошо. И закладки можно будет реализовать лучше, чем сейчас сделано.
Так что ждите.
Думаю, это будет отличная идешная фича для реально пишущих питонщиков.



Пока переписывал игру неоднократно возникала мысль о том, что в Kaapython нет инструмента для работы не с одиночным скриптом, а с целым проектом. [...] читать полностью
607


Полностью описан процесс создания РПГ на турбопаскале(а затем и дельфи).
Ни то, ни другое мне не доступно, зато есть Python.
Да и меня интересует больше теория.
Kaapython на время оставлен.



Откопал рассылку на сабскрайб.ру "Создание ролевой компьютерной игры". Полностью описан процесс создания РПГ на турбопаскале(а затем и дельфи). [...] читать полностью
745


---------------------
Symbian 7-8
---------------------
Сделано косметическое изменение в Установках, повлекшее, несмотря на свою незначительность, несовместимость с прежними настройками.
Поэтому приготовьтесь настраивать всё заново :-).
Добавлена возможность добавления закладок в редактируемые файлы.
Самое значимое изменение, оправдывающее релиз -- подхачено Автодополнение.
Читайте хелп, там подробно всё описано.



Symbian 9 --------------------- Symbian 7-8 --------------------- Сделано косметическое изменение в Установках, повлекшее, несмотря на свою незначительность, несовместимость [...] читать полностью
1012


Ликбез: цикл - это то, что повторяется "по кругу".
===========
Цикл for: осваиваем школьный английский.
-----------
Цикла for в Python НЕТ!
Есть цикл for ... in ...
Поэтому не надо говорить, что де, вон, к примеру, в C ("Си") for так for (далее следует псевдокод из смеси C и Python :)):
<!--code1--><!--ecode1-->
for (i=0; i < len('a little string'); i ) ...
<!--code2--><!--ecode2-->
- а в Python то же самое придётся писать так:
<!--code1--><!--ecode1-->
i = 0
for i in 'a little string':
i = i 1
...
<!--code2--><!--ecode2-->
(правильно, конечно, писать "for i in 'a little string': ...")
--
Цикл for-in может называться циклом только с версии Python 2.2. Именно начиная с неё, for-in обрабатывает итератор, который может (но не обязан) быть циклическим.
Более того. Цикл for-in умеет обрабатывать говорящее само за себя исключение StopIteration, которое возбуждает итератор, когда исчерпывается, умалчивая его, и принимая его за команду завершить свою работу.
Обычно же for-in, грубо говоря, аналогичен тривиальному обходу последовательности, который выполняют функции map-filter-reduce.
Чем хороши итераторы в отличии от последовательностей?
Последовательности создаются сразу и целиком, размещаются в памяти, и Python не может их удалить, пока цикл не обойдет их до конца.
Это дорого. Большие последовательности занимают много места, но ведь в каждом витке цикла используется только один член последовательности. Зачем же нам все остальные?
Итераторы решают эту проблему. Они выдают значения по-одному по какому-либо правилу, при этом нет таких затрат памяти.
--
Как я уже отметил классического цикла for в Python нет, поэтому придирки выглядят просто неумно: как можно спорить о том, чего нет?! :)
--
Как выглядит цикл for-in:
<!--code1--><!--ecode1-->for("для") <переменная цикла> in("в") <итератор или объект, который может предоставить итератор при получении специального сообщения>:
<делать что-нибудь, в том числе и ничего не делать><!--code2--><!--ecode2-->
===========
Ликбез:
--
Сообщения, передаваемые объекту - в объектной модели Python так называются методы объекта, в данном случае подразумевается метод next.
--
Итератор - объект, у которого есть метод next. Чтобы проще понять что это такое, представьте себе очередь перед кабинетом врача, например. Когда врач высовывается и говорит 'Следующий', очередь двигается.
При этом врачу не нужно всех созывать в кабинет. В кабинете находится всегда только один пациент, отсюда нет толкучки, тесноты и давки в кабинете (иначе, моё описание подошло бы и к последовательностям, а не только к итераторам).
Врач может также сказать "Женщина, которая последняя сидит (стоит), с грудным ребенком(из середины, третья с конца и т.д.) подойдите".
Вы скажете, нет таких врачей и|или очередей. Согласен, почти нет. Вот и итераторы в Python ведут себя так же - одни умеют только в порядке очереди (тавтология :-)) выдавать "следующего", и если попросить их нарушить этот порядок, возмутятся, а другие, м-м-м, более покладисты, что ли.
===========
Итак:
--
Цикл(врач) говорит (отправляет сообщение, то бишь обращается(вызывает) метод) очереди (итератору) "следующий" ("next" по-английски => метод next)
--
Также чтобы как-то общаться с пациентами (называть их) врач выбирает какую-то условную форму. Это либо вежливое "Вы", или свойское "ты", или там "голубчик/голубушка" и т.д..
--
Запишем это в псевдосинтаксисе:
<!--code1--><!--ecode1-->для Вы в очередь:
Вы = очередь.__следующий__()
...<!--code2--><!--ecode2-->
Да вот беда. Python интерпретатор. Когда он встречает какое-либо имя в тексте программы, он должен непременно узнать, кто за этим именем скрывается. Когда Python доходит до Вы, то он ещё не знает, что Вы это очередь.__следующий__(), поэтому Вы = очередь.__следующий__() не пишется, и подразумевается, что если уж есть очередь, то Вы - это каждый "следующий" кто-то из неё.
Таким образом брюки превращаются...:
<!--code1--><!--ecode1-->
для Вы в очередь:
...
<!--code2--><!--ecode2-->
--
Или на Python
<!--code1--><!--ecode1-->
for You in queue:
...
<!--code2--><!--ecode2-->
--
Теперь в теле цикла (это то самое загадочное многоточие ;-)) вы (читатели) вольны делать что угодно с You (Вы).
Конечно же, в рамках текущего законодательства вашего государства.
---
Нужно также упомянуть два оператора: break и continue. Применение первого прерывает цикл (врач говорит, что его рабочий день закончен, с завтрашнего дня начинается отпуск, а потом он вообще уволится - иными словами, приём закончен); второй позволяет циклу сказать 'следующий', не дожидаясь когда закончится текущая итерация (то бишь тело цикла).
---
Казалось бы всё? Нет.
А что если вместо итератора for-in получит строку, список или кортеж? Допустим мы с вами не умеем готовить итераторы. Никаких проблем.
Как я и оговорил в описании цикла, for-in принимает либо итератор, либо объект, имеющий метод __iter__, который должен возвращать итератор.
Поскольку в Python к специальным методам, чьи имена начинаются с двух символов подчеркивания и на них же и заканчиваются, не принято обращаться напрямую (в самом деле, Object.__iter__() смотрится коряво), довольно часто есть одноименная встроенная функция, в данном случае iter.
Цикл вызывает iter(), и обрабатывает полученный итератор.
---
Напоследок изюминка:
iter(f, sentinel)
Вот такой вот вызов возвращает итератор, который при работе в цикле будет вызывать вызываемый объект f, пока тот не вернет значение (объект) sentinel.
---



===========Ликбез: цикл - это то, что повторяется "по кругу".===========Цикл for: осваиваем школьный английский.-----------Цикла for в Python НЕТ!Есть цикл for ... in [...] читать полностью
1102


Вот как-то так.



Вот в такую же ночь (на Ивана Купала) герой гоголевского произведения поимел диковинные приключения на свою голову. Жгите костры, плетите [...] читать полностью
904