Любой обладатель смартфона знает, что мобильная операционная система делает телефон похожим на старшего брата -- настольный компьютер. Можно на свой вкус устанавливать разнообразные программы, которые кардинально влияют на удобство работы. Но мало кто знает, что на смартфоне, как и на компьютере, имеется возможность самостоятельно писать программы. Я расскажу о бесплатном языке программирования Python, который стараниями Nokia и Symbian адаптирован для смартфонов с интерфейсом S60. С помощью «змеиного» языка легко побеждать рутинные задачи: составлять отчеты, выявлять в документах типичные ошибки -- повторения слов или неработающие гиперссылки, и многое другое.
В начале 90-х сотрудник Национального голландского исследовательского института Гвидо Ван Россум в свободное от работы время написал на домашнем Apple Macintosh интерпретируемый язык Python. Интерпретируемые языки программирования Термин «интерпретируемый» значит, что для запуска программы требуется специальное приложение-консоль, которое будет переводить код программы в понятный машине язык. Для примера: известные многим со школы языки Pascal и C не интерпретируемые -- созданную программу надо скомпилировать в exe-файл, который может быть запущен на любом компьютере.
Не без помощи энтузиастов Python быстро оброс множеством функций и сегодня широко представлен не только в настольных ОС семейства Windows, Linux, OS X (Apple), но и мобильных: Symbian, Windows Mobile и Palm.
Расчехляем дудочку факира
Начнем с того, что установим Python на смартфон. Для этого потребуются файлы PythonScriptShell и PythonForS60. Первый -- приложение-консоль, которое необходимо для запуска и написания программ. Второй -- набор библиотек, отвечает за функционирование программ.
Разработчики постоянно радуют обновлениями (на момент написания статьи самая новая версия -- 1.3.20). Таким образом компания Symbian стимулирует появление новых программ и игр, что делает смартфоны с интерфейсом S60 более привлекательными для покупателей.
Как же понять, что именно нужно? Предлагаю посмотреть на таблицу 1, где приведены имена установочных файлов для каждой редакции Symbian.
Symbian OS 6.1 (S60 1-st Edition)
Nokia: N-Gage, 7650, 3650 и 3660; RoverPC: Sendo X1; Siemens: SX1
PythonForS60_1stEd_1_3_1.SIS
Symbian OS 7.0 (S60 Edition 2)
Nokia: 6600, 7610, 6260, 3230, 6670; Panasonic: X700, X800; Samsung: D720 и D730
PythonForS60_1_3_20_2ndEd.SIS, PythonScriptShell_1_3_20_2ndEd.SIS
Symbian OS 8.0a (S60 Edition 2 Feature Pack 2)
Nokia: 6630, 6680 и 6681; Lenovo: P930
PythonScriptShell_1_3_20_2ndEdFP2.SIS
Symbian OS 8.1 (S60 Edition 2 Feature Pack 3)
Nokia: N70, N72 и N90
PythonScriptShell_1_3_20_2ndEdFP3.SIS
Symbian OS 9.0 (S60 Edition 3)
Nokia: 3250, N71, N80, N91, N92, E60, E61 и E70
PythonForS60_1_3_20_3rdEd_selfsigned.SIS или PythonForS60_1_3_20_3rdEd_ unsigned_freedevcert.SIS, PythonScriptShell_1_3_20_3rdEd_ unsigned_freedevcert.SIS
Для Symbian 6 доступна только самая ранняя версия мобильного Python, и ситуация НЕ изменится (смотрим шапку темы).Находится файл для него в самой нижней вкладке с номером версии 1.3.1.
У Symbian 9, на которой построены последние телефоны Nokia, ситуация диаметрально противоположная -- новые версии Python регулярно выходят раз в несколько месяцев. Одновременно появляются обновления для 7-й и 8-й версии Symbian, так что владельцы аппаратов под этой ОС могут вздохнуть свободно.
Существуют две разновидности установочных файлов Python для Symbian 9: подписанные и не подписанные. Подпись введена компанией Symbian для защиты операционной системы от вирусов. Не подписанное ПО доступом к функциям операционной системы обладает крайне ограниченным. Любопытно, что пользователь сам может зарегистрировать несертифицированное ПО.
Установочные файлы Python, имеющие окончание selfsigned, подписаны. Такой вариант лучше всего подойдет для начинающих. Файлы, у которых в названии стоит окончание unsigned_freedevcert, предназначены для самостоятельной подписи, при этом Python получит максимальный доступ к ОС.
Скачав нужные файлы на компьютер, необходимо перенести их любым доступным способом на смартфон. При наличии data-кабеля и установленного Nokia PC Suite можно воспользоваться мастером «Установка приложений».
Первым устанавливается PythonForS60, вторым -- PythonScriptShell, после чего в меню смартфона появится значок Python. Клик по иконке вызывает консоль, которая встречает справкой об авторских правах и версиях программы (см. скришнот).
После нажатия на левую софт-клавишу консоль выдаст список из четырех функций: Run script, Interactive console, Bluetooth console и About Python. Нажатие на правую софт-клавишу приведет к ожидаемому выходу из приложения. Ну а нам -- вперед!
Здравствуй, мир!(классика от Кернигана и Ричи... hello, world)
Interactive console. При нажатии на этот пункт меню программа перейдет в так называемый интерактивный режим, в котором можно вводить команды на языке Python и немедленно видеть результат их выполнения.
Интерактивная консоль встречает приглашением, которое состоит из трех знаков: >>>. Попробуйте набрать следующую строку: «print «Hello World S60!» и нажать на джойстик. Если все сделано правильно, то на экране у вас то же, что и на нашем скриншоте.
Разберем этот пример. Команда «print» предназначена для вывода различной информации, в данном случае «Hello World S60!». Запомните: все, что находится в кавычках, является текстом, сами кавычки при этом не выводятся. С помощью «print» удастся выводить не только текст и цифры, но и значения переменных.
Пример:
a = 1
b = 2
print «a-b =»,a-b
В первых двух строках задаются переменные. Переменная -- это буквенное обозначение области памяти, в которой хранится некоторое значение. В данном случае программа указывает Python, что переменная a должна равняться единице. Во второй строке создается переменная b со значением 2. А в третьей строке происходит следующее: сначала оператор print выведет текст «a-b =», затем будет вычислена разность a и b и выведен ее результат. Таким образом, на экране отобразится «a-b = -1», и после этого курсор будет переведен на новую строку. Заметьте, пробел между выводимыми объектами вставляется автоматически.
Предыдущий пример был с целыми числами, но Python без проблем справится и с дробными (вещественными). Кроме сложения ( ), над числами можно произвести операции умножения (*), вычитания (-), деления (/) и возведения в степень (**).С помощью скобок в интерактивной консоли Python можно задать вычисление сложных математических выражений вида 485*738 (203**2)/234-1456, что дает право жить Python в памяти вашего смартфона хотя бы в виде сложного калькулятора.
На скриншоте приведен и пример «общения» с интерактивной консолью, результатом которого стала вычисленная длина (в виде вещественного числа) окружности с радиусом равным пяти.
К запуску готов!
Run script. Выбор этой функции приведет к отображению списка программ на языке Python (см. скриншот). Для запуска выбранной программы необходимо нажать на ОК.
В списке отображаются примеры, поставляемые вместе с Python и находящиеся в рабочей папке -- systemappsPython -- того диска, где был установлен PythonScriptShell. Объясню немного про каждый пример:
1) ball.py -- любопытная программа, в которой дается возможность управлять шариком. Предмет стремится оказаться на «полу» под действием виртуальной гравитации, что можно предотвратить, двигая джойстик.
2) default.py -- сама консоль Python. При запуске программа перезапускается.
3) filebrowser.py -- браузер файловой системы (рис. 4). Позволяет просматривать содержимое всех дисков смартфона (C: -- внутренняя память, D: -- виртуальный диск, создаваемый в оперативной памяти, E: -- флэш-карта, Z: -- прошивка). Нажатие на папки приведет к отображению их содержимого, если же щелкнуть по файлу, то появится меню действий. В случае когда открываемый файл имеет расширение py, то есть это программа на Python, он будет автоматически запущен.
4) gles_demo.py и simplecube.py -- демонстрируют 3D-возможности Python, которые представлены набором инструкций (API) OpenGL ES. В первом примере просто вращаются красивые кубы, во втором -- только один куб, но у него можно менять атрибуты внешнего вида через меню.OpenGL ES
OpenGL ES -- кроссплатформенная графическая библиотека для создания качественных игр с использованием 3D-объектов с эффектами текстурирования, освещения и другого. К сожалению, данная библиотека недоступна смартфонам с Symbian 6 и 7.
5) imgviewer.py -- просмотрщик картинок. Рабочая папка программы -- e:images. Позволяет просматривать картинки на весь экран, имеется возможность скроллинга изображения, если оно выходит за пределы экрана, прокручивание списка (нажатие на клавиши 1 и 3) и множество других функций.
6) keyviewer.py -- программа для отображения кодов нажатых клавиш. Нажимая на различные комбинации клавиш, можно увидеть их код в десятичном и шестнадцатеричном виде.
7) snake.py -- бессмертная змейка. Управляйте джойстиком и направляйте змею (вероятно питона) к спасительной пище.
Голубой передатчик
Bluetooth Console. С помощью «голубого зуба» смартфон можно подключить к настольному компьютеру или ноутбуку. Пользователь может работать в интерактивной консоли с помощью полноценной клавиатуры.Работаем со смартфоном на ПК через Bluetooth Console
1) Запустите HyperTerminal на компьютере (Пуск -- Программы -- Стандартные -- Связь).
2) В появившемся окне «Описание подключения» введите имя нового подключения и выберите ему любой понравившийся значок, нажмите ОК.
3) В окне «Подключения» из списка «Подключаться через» выберите тот COM-порт, который был создан после установки Bluetooth-адаптера на компьютер (серийный порт Bluetooth RFCOMM) и нажмите ОК.
4) Запустите Python на смартфоне и в меню «Функции» выберите пункт «Bluetooth Console».
5) Появится окно найденных Bluetooth-устройств, из них выберите то, которое принадлежит компьютеру, и нажмите «Выбрать».
6) Если соединение прошло успешно, то на смартфоне появится окно с вопросом «Set as default?», нажмите ОК.
7) Перейдите к окну HyperTerminal, там будет надпись «Connected», замечания об авторских правах и версия программы Python, ниже будет находиться приглашение >>>.
Таким образом, был получен аналог мобильного «Interactive Console» на компьютере: можно вводить команды с клавиатуры и видеть результат их выполнения на мониторе. На телефоне это видимым образом не отображается, однако Bluetooth-канал активен, а процессор на смартфоне нагружается для обработки набранных команд.
Перед выходом из HyperTerminal сохраните подключение (Файл -- Сохранить). Теперь при последующих запусках можно не настраивать подключение заново, а загрузить его (Файл -- Открыть). После, при запуске «Bluetooth Console», на смартфоне будет появляться окно «Connect to:», где достаточно нажать «Default host».
Итоги
About Python. При нажатии на этот пункт меню появится окошко с предложением посетить официальный сайт www.python.org для получения дополнительной информации.
Альтернатива Python
Кроме Python, имеется возможность писать программы на смартфонах S60 и на таком языке, как mShell. Сайт разработчиков: www.m-shell.net.
Плюсы mShell:
-- Синтаксис языка похож на Pascal. Во многих школах обучение этому языку входит в стандартный курс информатики, поэтому привыкнуть к mShell будет несложно. Python же, хоть и прост, имеет мало общего с популярными языками программирования.
-- Высокая скорость выполнения программ, особенно работающих с графикой. И это несмотря на то, что mShell, как и Python, интерпретируемый язык.
-- Наличие версии для Symbian UIQ.
А теперь минусы:
-- Меньший функционал по сравнению с Python.
-- Невозможность создания самостоятельных приложений -- запуск программ возможен только из консоли mShell.
-- Платность. Распространяется программа в двух версиях: Free и Full. Free -- бесплатная, но у нее отсутствуют некоторые функции. Full -- полнофункционален, но стоит денег. Следует отметить, с недавних пор Full-версия для Symbian 7-8 бесплатная, обладателей смартфонов с Symbian 9 эта новость не касается.
После прочтения статьи у некоторых (хотя, надеюсь, у всех) появилось огромное желание сделать свою программу на языке Python.
В следующих статьях мы расскажем:
Как смотреть код программы и сохранять его. Как создать иконки в меню для быстрого запуска Python-приложений.
А также напишем первую полезную программу. Полученные навыки позволят самостоятельно делать приложения, заточенные под личные нужды.
Наша задача — разобраться, с помощью чего надо писать программы на мобильном Python и как создавать из них Symbian-приложения со значком в меню.
Вооружаемся!
Файлы формата *.py содержат голый код языка Python и могут быть открыты любым текстовым редактором. Надеемся, что на компьютере текстовый редактор для вас не проблема, поэтому уделим внимание исключительно мобильному ПО.
Встроенный редактор обычно плохо подходит. Лучший выбор, по моему мнению, программа YEdit, которая выделяется богатыми настройками и широким диапазоном поддерживаемых кодировок.
Необходим и браузер файловой системы, который имеет доступ в системные папки. Недолго мучаясь, можно в качестве браузера взять приложение из примеров к Python; местонахождение браузера — systemappsPython (для Symbian 6-8). Если хотите массу настроек — рекомендую функциональную программу FileMan (рис. 2).
Интересным вариантом будет также браузер X-plore, который (рис. 5) имеет встроенный редактор текстовых файлов (рис. 6). Примечательно, что X-plore — единственный редактор под ОС Symbian 9 с поддержкой кодировки UTF-8. Упускать из виду эту программу владельцам соответствующих телефонов, например Nokia 3250, категорически не рекомендуется.
Скорее в бой!
Считаем, что необходимый инструментарий уже на руках, а навыки работы с редакторами и браузерами имеются. Начнем!
Создайте в редакторе файл, содержащий следующие две строки:
import appuifw
appuifw.note("Hello World!")
(мини-программка создаст окно с надписью).
Сохраните файл в любом месте (например, в корне диска) с именем my_program и расширением *.py . Если изменение расширения не доступно в редакторе, выход один — изменить расширение вручную через файловый браузер.
В этом месте я вынужден предупредить обладателей смартфонов с 9-ой версии Symbian, что весь нижеследующий текст применим только для смартфонов с Symbian 6-8, и предлагаю перейти к последнему абзацу статьи.
В комплекте с PythonScriptShell идет скрытая (то есть не отображаемая в меню) программа AppMgr. Ее предназначение — установка программ и библиотек Python, а также создание на их основе Symbian-приложений. Файлы *.py имеют ассоциацию с AppMgr, если открыть my_program.py в любом файловом браузере, запустится именно AppMgr с табличкой вариантов действий.
Выбираем пункт Python script. AppMgr установит файл в подпапку my рабочей папки Python. Если запустить Python и выбрать в меню «Функции» пункт Run script, в конце списка теперь будет находиться my_program.py.
Нажмите ОК и любуйтесь результатом: должно появиться информационное окошко с сообщением «Hello World!», после чего программа завершится.
Таким образом, нами получена первая относительно самостоятельная программа. Но именно что относительно, потому что запуск возможно осуществлять только через оболочку Python. Однако та же программа AppMgr может создать и Symbian-приложение, для этого предназначена функция Standalone app. К сожалению, разработчики эту возможность.
В решении проблемы нам поможет сам Python, точнее — его принцип открытости. Напоминаем, что код программ Python находится в файлах *.py в виде текста; любой может легко изменить код по своему усмотрению.
Текст программы AppMgr находится в файле default.py в папке systemappsappmgr. Необходимо открыть файл текстовым редактором и найти ближе к концу следующий текст:
...
actions = [lambda: script_install(filename),
#lambda: standalone_install(filename),
lambda: lib_install(filename)]
menu = [u"Python script",
#u»Standalone app",
u»Python lib module"]
...
Символ # означает комментарий — все, что после него идет в этой строке, игнорируется интерпретатором. Закомментирована может быть информация, которая поясняет действия тех или иных строк кода и значительно облегчает редактирование программы в будущем. Как видим, разработчики использовали комментарий, чтобы скрыть функцию программы. Нам необходимо убрать два символа # в обеих строках.
Для применения изменений сохраните файл default.py. Чтобы проверить результат редактирования, необходимо перейти файловым браузером к программе my_program.py и открыть ее. Если все изменения произведены правильно, то запустится AppMgr и предложит не 2, а уже 3 варианта действий, среди которых будет и Standalone app. Активация этого пункта приведет к появлению окна с предложением ввести UID. Это последний этап, который придется преодолеть.
UID — 8-значный (в шестнадцатеричном виде) уникальный номер. Именно по нему ОС Symbian различает установленные на смартфоне программы друг от друга. На одном смартфоне не может работать две программы с одним UID, запуск любой из них приведет к ошибке. Получать идентификатор, по идее, нужно от разработчиков Symbian, причем единственное преимущество такого UID будет в том, что он 100% уникален. Если же придумать номер самим, то появляется шанс встретить программу с таким же UID. Однако вероятность такого события ничтожно мала. Идентификатор должен лежать в определенных диапазонах, и если введенный UID не укладывается в рамки, то AppMgr уведомит сообщением «Failed Error».
Вот пример «рабочего» UID: «0x31243ABC», который необходимо ввести в окно запроса Give UID и нажать на ОК. Если все прошло успешно, появится сообщение «Installation complete», которое напрямую говорит: «приложение создано, и значок с именем my_program появился в меню (на Nokia 6600 чудо свершится почти сразу, а вот на Nokia N70 нужно подождать секунд 5-10)». Запуск новоявленного приложения приведет к появлению все того же сообщения «Hello World!». После программа перейдет в режим ожидания, и для выхода из нее необходимо нажать на «Выйти».
Внимательный читатель может заметить, что здесь говорится о Symbian-приложении, тогда как Python — интерпретируемый язык и возможности создавать приложения в машинных кодах не имеет. Действительно, автор чуть лукавит. AppMgr создает не приложение с введенным UID и с именем, как у файла *.py: он создает на основе этих данных загрузчик программы. Чтоб удостовериться, достаточно зайти файловым браузером в папку systemappsmy_program того диска, где установлен PythonScriptShell. Там находится: my_program.app — непосредственно загрузчик, default.py — сама программа и my_program.rsc. Файл default.py является полной копией my_program.py, что проверяется текстовым редактором.
Если присмотреться, то созданное приложение my_program по структуре похоже с рассмотренным выше AppMgr. Более того, заглянув в рабочую папку Python, можно и там найти те же Python.app, default.py и Python.rsc. Эти три файла и есть минимальный набор любого Symbian-приложения, созданного на основе *.py программы.
Таким образом, нами под моим руководством, надеюсь, вами получено «самостоятельное» приложение — долгожданный значок в меню. Если скопировать папку my_program в папку systemapps другого смартфона, то в его меню появится значок, но запуск my_program ни к чему не приведет. Здесь опять видны «уши» интерпретатора: чтобы все-таки запустить приложение, необходим PythonForS60. Напомним, что установка мобильного Python включает различные модули — в его папке systemlibs находится огромное количество файлов с расширением *.py и *.pyd.
Вот такая развязка. Python дает владельцам смартфонов революционную возможность создавать приложения со значком в меню.
Приручаем Python под Symbian 9
А теперь информация для обладателей смартфонов с Symbian 9: все программы на языке Python должны находиться в корневой папке Python того диска, где был установлен PythonScriptShell. Новые (например, my_program.py) необходимо вручную с помощью файлового браузера перемещать туда, где находятся примеры. Все эти программы доступны при запуске Python в меню Run Script.
Начнём углубленное изучение языка Python с функций
Функции в Python, как и в любом другом языке программирования, предусмотрены для упрощения работы с часто повторяющимися действиями в программе.
Функция состоит из имени, аргументов и тела, выглядит она так:
def name(arguments):
тело функции
Как видно, после def указывается имя функции, а в скобках – её аргументы. Если аргументов для функции не предусмотрено, то скобки оставляются пустыми. В конце строки обязательно ставят двоеточие.
При каждом вызове функции выполняются записанные в её тело выражения. Следует отметить, что тело функции надо выделять. В языке программирования Pascal это делают с помощью инструкций begin…end, а в С – с помощью фигурных скобок {…}.
Наберём в интерактивной консоли нашу первую функцию. Сначала вводится “def hello():”. После нажатия на джойстик произойдет переход на новую строку и вместо привычного “>>>” появится приглашение вида “…”. На этой строке необходимо сделать отступ, обычно 4-8 пробелов (однако число пробелов может быть любым). Только затем можно печатать тело функции «print “Hello!”». Если нажать еще раз на джойстик, то снова выйдет приглашение “…”. Так как выражений, принадлежащих функции, больше нет, нажимаем на джойстик. Переход на новую строку без наличия отступа уведомляет интерпретатор о завершении ввода тела функции. Теперь введите “hello()” и нажмите на джойстик, что приведет к выводу в консоль текста “Hello!” (на экране смартфона это выглядит так, как представлено на Рис.1). Рис. 1
Пример:
>>> def hello():
… print “Hello!”
…
>>> hello()
Hello!
>>>
Рис. 1.
Наша первая функция не содержала аргументов. Следующий шаг – научиться их использовать!
Пример:
>>> def hello(name):
… print “Hello”,name,”!”
…
>>> hello(“Albert”)
Hello Albert!
>>>
Или еще один пример, уже с числами:
>>> def summa(a,b):
… print "a + b =",a+b
…
>>> summa(1,2)
a + b = 3
>>>
Переменные, которые используются в функции, называются локальными. Это означает, что после того, как функция отработала, её переменные попросту уничтожаются. Любопытно, что заданные в функции переменные не конфликтуют с глобальными. Поясним на примере:
>>> c=5
>>> def check():
… c=10
… print c
…
>>> check()
10
>>> print c
5
>>>
Как видно, работа с переменной внутри функции никак не сказывается на её однофамильца вне этой функции. В случае, когда внутри функции необходимо использовать глобальные переменные, используется оператор global, за которым следует их список через запятую.
Пример:
>>> pi=3.14
>>> def len(radius):
… global pi
… print "Dlina kruga =",pi*radius
…
>>> len(2)
>>> Dlina kruga = 6.28
>>>
Нетрудно представить, что результат работы функции, который был сохранен в переменной, может понадобиться для дальнейшей работы, но после завершения функции, как было сказано, эта переменная будет удалена. Для этого случая предназначена команда return, возвращающая указанные переменные. Пример:
>>> def summa(a,b):
… c=a+b
… return c
…
>>> summa(1,2)
3
>>>
В нашем примере функция возвращает “с” в любом случае, однако если вдруг понадобится, в зависимости от каких-либо условий, совершить другое действие? Вот пример с решением проблемы:
>>> def summa(a,b):
… if a<0:
… print “Error! a”,a,”< 0”
… return
… elif b<0:
… print “Error! b”,b,”< 0”
… return
… else:
… c=a+b
… return c
…
>>> summa(1,2)
3
>>> summa(-1,2)
‘Error! -1 < 0’
>>> summa(1,-2)
‘Error! -2 < 0’
>>>
В примере функция summa() успешно возвращает результат, только если оба аргумента больше нуля. Для определения этого используется конструкция if…elif…else и условия.
Начинается конструкция с if, и если условие, записываемое после него, истинно (например, a<0), то выполняется нижеследующий блок выражений (например, print “Error! а”,a,”< 0”). Эта часть конструкции должна присутствовать всегда.
Если условие является ложным, то проверяются все elif. В нашем случае он был один, однако их может быть неограниченное количество и интерпретатор будет проверять их все, пока в каком-либо из них условие не станет истинным. Т.е. если бы параметров было на два больше - def summa(a,b,c,d) - то необходимо было бы дописать еще две elif: >>> def summa(a,b,c,d):
… if a<0:
… print “Error! a”,a,”< 0”
… return
… elif b<0:
… print “Error! b”,b,”< 0”
… return
… elif c<0:
… print “Error! c”,c,”< 0”
… return
… elif d<0:
… print “Error! d”,d,”< 0”
… return
И т.д…
Если же ни в одном из if и elif условие не будет истинно, то выполняется блок выражений, следующий за else. В нашем случае это происходит, только если все аргументы больше нуля. И еще два замечания:
1) команда return может быть использована для выхода в любом месте тела функции, причем даже без аргументов (в этом случае функция по умолчанию возвращает значение None);
2) в зависимости от ситуации, в if и elif могут быть использованы условия проверки “<” для меньше, “>” для больше, “>=” для больше или равно, “<=” для меньше или равно, “==” для равно, “<>” или “!=” для не равно.
Перейдем к рассмотрению типов данных и начнем со списков.
Список в языке Python предназначен для группирования нескольких значений. Наиболее близким аналогом из других языков программирования является понятие массив. Создается список путем заключения нужных значений, перечисленных через запятую, в квадратные скобки:
>>> [1, 2, 3]
[1, 2, 3]
>>> [“one”, “two”", “three”]
[“one”, “two”, “three”]
>>>
Первый пример – список четырех целых чисел, а второй – список трех строк. Элементы списков вовсе не обязательно должны быть одного типа. Следующий список содержит строку, целое, вещественное число и другой список:
>>> [“hello”, 5, 2.0, [10, 20]]
[“hello”, 5, 2.0, [10, 20]]
>>>
Список, являющийся элементом другого списка, называют вложенным.
Кроме того, Python предоставляет возможность быстрого создания списков целых
значений, без необходимости их надо перечислять:
>>> range(1,5)
[1, 2, 3, 4]
>>>
В данном примере функция range() принимает два целых аргумента и возвращает список, который содержит все целые числа в промежутке между заданными значениями, включая первое и исключая второе.
Существует еще два способа вызова функции range(). Если ей передано только одно значение, то в результате она вернет список с целыми значениями от 0 до N, где N –значение параметра:
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
Если же range() вызвана с тремя аргументами, то последний из них рассматривается как размер шага. Т.е. в полученном списке значения будут идти не подряд, а через промежутки:
>>> range(1, 10, 2)
[1, 3, 5, 7, 9]
>>>
Список, не содержащий ни одного элемента, называют пустым. Он обозначается пустыми квадратными скобками [].
Как и любые другие значения, списки могут сохраняться в переменных:
>>> numbers = [17, 123, 537]
>>> empty = []
>>> print numbers, empty
[17, 123, 537] []
>>>
Значение в списке может быть получено по порядковому номеру – индексу. Индексом может быть любое выражение, возвращающее целое число, в том числе отрицательное. Нумерация индексов начинается с нуля. Если индекс меньше нуля, то отсчет индекса будет начат с конца списка:
>>> numbers[0]
17
>>> numbers[-1]
537
>>>
После создания списка его элементы можно изменять:
>>> numbers[1] = 5
>>> numbers
[17, 5, 537]
>>>
Для вычисления длины списка используется функция len():
>>>mylist = [“one”, “two”, “three”, “four”, [1, 2, 3, 4]]
>>>len(mylist)
5
>>>
Обратите внимание, что если список содержит в качестве элемента другой список, то этот вложенный список будет считаться как один элемент.
В Python есть еще один тип данных, называемый кортеж. Он полностью аналогичен списку – за исключением того, что элементы изменять не допускается.
Для того чтобы создать кортеж, необходимо заключить в обычные скобки нужные значения через запятую:
>>> tuple = (“a”, “b”, “c”, “d”, “e”')
>>> len(tuple)
5
>>> tuple[0]
‘a’
>>>
Как видно, можно получить размер кортежа и значение любого элемента по индексу – так же, как и в случае со списком. Однако выражение вида tuple[0]=”z” приведет к ошибке – повторяю, элементы кортежа изменять нельзя.
Таким образом, было рассмотрены понятия список и кортеж. Необходимость изучения была продиктована тем, что эффективное их использование делает программу элегантной и простой в понимании. К тому же множество функций принимают списки и кортежи в виде аргументов или возвращают их как результат.
Теперь перейдем к нашей программе my_program. Там было две строки:
import appuifw
appuifw.note(u”Hello World!”)
Если выполнить (т.е. ввести и нажать на джойстик) сначала первую строку, то ничего не произойдет. На самом деле инструкция import подключает модуль appuifw, после чего его возможности будут доступны в программе. А направлены они на создание интерфейса программы, т.е. инициирование всплывающих сообщений, окошек с запросами для ввода данных, холста для рисования и многое другое. Для вызова функций данного модуля сначала необходимо указать собственно имя модуля, затем точку и, наконец, имя функции.
После выполнения второй строки появится окошко с сообщением “Hello World!”. Ответственно за это функция note, имеющая один обязательный аргумент – текст сообщения. На данном этапе обучения примем, что текст должен быть на английском и обязательно начинаться с символа “u”.
У этой функции есть и второй необязательный аргумент, который указывает характер выводимого сообщения. По умолчанию он равен “info”, т.е. подразумевается, что сообщение информирует пользователя о чем-либо. Кроме него возможны значения “error” (часто используется при выводе сообщения об ошибке) и “conf” (используется, например, когда пользователю необходимо сообщить о завершении операции). Подставьте эти значения сами и посмотрите на результат.
Также данный модуль предоставляет функцию query, которая пригодится в случае, когда программе требуется получить какую-то информацию от пользователя. Например, в результате выполнения appuifw.query(u”Give UID”, “text”, u“0xXXXXXXXX”) появится абсолютно то же окно запроса, что и при вводе UID в программе AppMgr при создании приложения (Рис. 2). После нажатия на «ОК» в консоли отобразятся введенные данные. Т.е. функция вернула результат своей работы, и эти данные впоследствии могут быть использованы по ходу работы программы.
Рис. 2
Разберем параметры функции query: первый – имя окна запроса (заголовок), второй – тип вводимых данных, третий – значение по умолчанию, которое будет отображено в окне при его создании. Сразу отмечу, третий аргумент необязателен, т.е. если он будет отсутствовать, то окно появится пустое изначально. Теперь подробнее о втором аргументе. Кроме “text”, существуют варианты:
1) “code” – предназначено для запроса пароля, т.е. в окне введенные данные будут отображены звездочками;
2) “number” – предназначено для запроса целых чисел;
3) “date” – предназначено для запроса даты (день, месяц, год);
4) “time” – предназначено для запроса времени (час, минута);
5) “float” – предназначено для запроса вещественных чисел;
6) “query” – предназначено для запроса подтверждения.
При этом:
1) “code” и “text” возвращают набранный пользователем текст;
2) “date” и “time” возвращают набранную дату и время в секундах;
3) “number” возвращает целое число, а “float” – вещественное;
4) если тип данных указан “float”, то значение по умолчанию не может быть установлено.
Остановлюсь на последнем. Выполнение appuifw.query(u”You want exit?”, “query”) приведет к появлению окна выбора с заголовком ”You want exit?” и с двумя вариантами действия: “ОК” (над левой софт-клавишей) и “Отмена” (над правой софт-клавишей). Т.е. данный вид запроса может быть использован, например, для подтверждения действий пользователя (Рис. 3). В случае нажатия на “ОК” query вернет число 1, в противном случае ничего не возвращается. Пример:
>>> def exit():
… if appuifw.query(u”You want exit?”, “query”)==1:
… appuifw.note(u“OK”)
… else:
… appuifw.note(u “Cancel”)
…
>>>
Рис. 3
Вызов exit() в любом месте программы инициирует появление окна с вопросом You want exit?, причем результат выбора будет немедленно отмечен соответствующим сообщением.
В случае, когда имеется необходимость предусмотреть выход из программы, модуль appuifw предлагает использовать функцию app.set_exit(). Если предыдущий пример переписать и вместо appuifw.note(u“OK”) ввести appuifw.app.set_exit(), то после вызова exit() и нажатия на «ОК», произойдет ожидаемый выход из программы.
Последняя описываемая в этой статье возможность – создание меню. Для этого используется переменная app.menu. Пример:
>>> def exit():
… if appuifw.query(u”You want exit?”, “query”)==1:
… appuifw.app.set_exit()
…
>>> appuifw.app.menu([(u”Exit”,exit)])
>>>
Теперь при нажатии на «Функции» будет появляться список предлагаемых действий с одним пунктом – Exit (смотри рис. 4). Его выбор приведет к появлению запроса о выходе, что и произойдет при нажатии на «ОК».
Рис. 4
Подробно о значении, которое может быть присвоено переменной appuifw.app.menu. Как видно из примера, для создания меню используется список кортежей. В нашем случае список состоял из одного кортежа, которое обеспечило создание одного пункта меню – “Exit”. Нажатие по этому пункту приводит к вызову функции exit. Если необходимо создать несколько пунктов, то указывайте кортежи через запятую. В общем, переменной может быть присвоено значение вида [(title1, callback1), (title2, callback2),…,(titleN, callbackN)]. Каждый кортеж состоит из одного элемента в виде строки, отвечающего за имя пункта, и второго элемента в виде имени функции, вызываемого сразу после выбора пункта.
Полученной информации достаточно для создания простейших программ – например, калькулятора на четыре арифметических действия: сложение, вычитание, умножение и деление. Данный пример называется Calculator и находится в архиве, идущем вместе со статьей. Описывать принцип его работы я не буду, так как в файле Calculator.py имеются комментарии (Рис. 5-7).
Рис. 5
Рис. 6
Пример также ярко доказывает, возможно, главное преимущество Python – при должном опыте можно написать программу с любым нужным функционалом, что поднимает удобство работы с Symbian смартфоном до не вообразимых высот. Например, тот же Calculator в умелых руках способен превратиться в мощный инженерный инструмент, подстроенный под нужды определенного пользователя. Причем за аналог в виде готового приложения *.sis пришлось бы отдать разработчику свои кровные деньги.
Чтобы достичь такого уровня программирования, читайте продолжение серии статей и подкрепляйте полученные знания собственными программами.
Жуки и другие насекомые...
Программирование — сложный процесс, и вполне естественно, что иногда программист допускает ошибку. Процесс поиска и устранения ошибок в англоязычной литературе принято обозначать термином debugging, мы же будем называть его отладкой.
Существуют три типа ошибок программирования:
1. синтаксические ошибки (syntax errors),
2. ошибки выполнения (runtime errors),
3. семантические ошибки (semantic errors).
Чтобы находить и исправлять ошибки быстрее, имеет смысл научиться их различать.
Синтаксические ошибки (syntax errors)
Любой интерпретатор сможет выполнить программу только в том случае, если программа синтаксически правильна. Когда интерпретатор находит инструкцию, которую не может понять, он прерывает работу и выводит сообщение об ошибке. Даже незначительная опечатка означает, что программа не выполнится:
>>> print print "Hello world"
File "<console>", line 1
print print "Hello world"
^
SyntaxError: invalid syntax
>>>
Нелепая ошибка.
На этом примере мы два раза в интерактивной консоли ввели оператор print. Ответ интерпретатора таков:
— File "<console>"
имя файла, в котором находится ошибка, ставится в кавычки. В данном случае значение console говорит, что код программы набран прямо в консоли;
— line 1
номер строки с ошибкой;
— print print "Hello world"
^
— SyntaxError: invalid syntax
Указывается тип ошибки. В данном случае — синтаксический.
Ошибки выполнения (runtime errors)
Второй тип ошибок обычно возникает во время выполнения программы (их принято называть исключительными ситуациями, или, коротко, исключениями, по-английски exceptions). Такие ошибки имеют другую причину. Если в программе возникает исключение, то это означает, что случилось непредвиденное: например, программе передали некорректное значение или программа попыталась разделить какое-то значение на ноль, что недопустимо с точки зрения математики. Если операционная система присылает запрос на немедленное завершение программы, то также возникает исключение. Но в простых программах это достаточно редкое явление, поэтому, возможно, с ним вы столкнетесь не сразу:
>>> 1/0
File "<console>", line 1, in ?
ZeroDivisionerror, integer division or modulo by zero
>>>
Сообщается об ошибке деления на ноль.
Делить на ноль нельзя!
Семантические ошибки (semantic errors)
Третий тип ошибок — семантические ошибки. Первым признаком наличия в вашей программе семантической ошибки является то, что она выполняется успешно, т.е. без исключительных ситуаций, но делает не то, что вы от нее ожидаете. Поиск таких ошибок — задача нетривиальная, т.к. приходится разбираться в том, что программа делает на самом деле.
Перехват диверсанта
К счастью, Python предоставляет инструкции, с помощью которых можно задать перехват нежелательных действий:
try:
<код, при выполнении которого могут появиться исключения>
except <тип исключения, которое необходимо перехватить>:
<код, выполняемый после перехвата исключения>
Расшифровка:
— подозрительный код вносится в ветвь try. Этот код и выполняется первым делом;
— ветвь except выполняется в том случае, если код ветви try привел к ошибкам, тому же делению на ноль, к примеру;
— если во время выполнения ветви try генерируется исключение (происходит ошибка), оставшаяся часть ветви пропускается.
— если исключение не соответствует указанному после except, то оно считается не перехваченным. Если для ветви except не указан тип ошибки, то перехватываются все исключения.
>>> def division(a,b):
... try:
... print a/b
... except:
... print "Error"
...
>>> division(6,2)
3
>>> division(2,0)
Error
>>>
Разумный контроль — ключ к успеху!
Если нужно перехватить несколько типов исключений, то указывается их кортеж: except (RuntimeError, TypeError, NameError). Какие конкретно бывают ошибки в Python, будет сказано чуть ниже.
После всех ветвей except можно указать необязательную ветвь else, которая будет выполняться в том случае, если во время выполнения ветви try исключений не происходит:
>>> def division(a,b):
... try:
... print a/b
... except ZeroDivisionerror:
... print "ZeroDivisionerror"
... except (TypeError,NameError):
... print "OtherError"
... else:
... print "No Error"
...
Лучше мы запутаем ошибку, чем она запутает нас!
Обычно лучше использовать ветвь else, чем добавлять код в ветвь try. Это позволит избежать обработки исключений, сгенерированных кодом, который вы и не собирались защищать.
Также инструкция try может иметь «страховочную» ветвь finally, которая выполняется при любых условиях:
>>> def division(a,b):
... try:
... print a/b
... finally:
... print "Goodbye!"
...
Ветвь finally выполняется независимо от того, возникла исключительная ситуация во время выполнения ветви try или нет. Инструкция try может иметь либо ветви except, либо только одну ветвь finally, но не оба варианта сразу.
Данная выше информация очень важна, и, судим по собственному опыту, большинство начинающих уделяют ей мало внимания, затрачивая большое количество времени на поиск ошибок. А ведь грамотное использование этой возможности позволит писать достаточно «умные» программы, которые не закрываются после глупых шагов пользователей (ввод строки вместо числа, например) и непредвиденных обстоятельств (отсутствует нужный файл, например), да к тому же могут проинформировать об ошибке в удобном виде.
Знай врага в лицо!
Как говорит программерская мудрость — старый «баг» лучше новых двух. Чтобы не допускать размножения ошибок, надо знать их в лицо:
ImportError
Ошибка при импорте модуля (скорее всего, неправильно указано его имя):
>>> import appuifwww
Traceback (most recent call last):
File "<console>", line 1, in ?
ImportError: No module named appuifwww
>>>
IndexError
Ошибка, которая генерируется, когда осуществляется попытка обратиться к списку (строке, кортежу) по индексу, превышающему его длину:
>>> list = [1, 2, 3]
>>> list [9]
Traceback (most recent call last):
File "<console>", line 1, in ?
IndexError: list index out of range
>>>
MemoryError
Ошибка из-за нехватки оперативной памяти (например, когда вы пытаетесь создать очень большой список функцией range):
>>> range (10000000)
Traceback (most recent call last):
File "<console>", line 1, in ?
MemoryError
>>>
NameError
Ошибка имени (используется несуществующая переменная):
>>> 1 a
Traceback (most recent call last):
File "<console>", line 1, in ?
NameError: name 'c' is not defined
>>>
SyntaxError
Синтаксическая ошибка (будьте внимательны!):
>>> 1 0
File "<console>", line 1
1 0
^
SyntaxError: invalid syntax
>>>
TypeError
Ошибка генерируется, когда осуществляется попытка применить операцию к объекту не того типа (например, складывать число и строку):
>>> 1 ‘2’
Traceback (most recent call last):
File "<console>", line 1, in ?
TypeError: unsupported operand types for : 'int' and 'str'
>>>
ZeroDivisionerror
Ошибка деления на ноль:
>>> 1 / 0
Traceback (most recent call last):
File "<console>", line 1, in ?
ZeroDivisionerror: integer division or modulo by zero
>>>
В следующей статье мы займемся изучением способов создания интерфейса для своей программы (причем на русском языке) и попутно разберем понятие объект в языке Python.
Python на Symbian S60: объекты, создание интерфейса (модуль appuifw) +пример Interface.py
Точка, точка, запятая...
Мы живем в мире объектов, каждый из которых имеет определенные свойства: цвет, размер, вкус, запах и другие. Эти предметы могут выполнять различные действия — например, авторучка предназначена для письма, а телефон, чтобы по нему звонить.
Аналогично устроен и мир языка Python, вот только объекты в нем называются классами. Характеризуются объекты действиями — методами и свойствами — атрибутами.
Создаются объекты (классы) в языке Python следующим образом:
class имя_объекта:
<инструкции>
Т.е. после ключевого слова class следует имя нового класса, а затем после двоеточия — код на языке Python. Код может содержать как простые инструкции (создание атрибутов), так и определение функций (создание методов):
>>> class new:
... attribute = ‘Hello’
... def method(self, name):
... print self.attribute, name
...
>>>
Таким образом, мы создали класс (объект) с именем new. Он имеет свойство attribute и действие method. Для того чтобы использовать класс, необходимо создать его экземпляр (делается это как вызов функции) и обозначить переменную, через которую сможем обращаться к атрибутам и методам этого класса. То есть сначала указывается имя объекта, потом ставится точка и, наконец, вводится имя атрибута или метода:
>>> my_class = new()
>>> my_class.attribute
‘Hello’
>>> my_class.method(‘World’)
Hello World
>>>
Атрибуты класса могу быть не только прочтены, но и изменены
>>> my_class.attribute = ‘Good-bye ’
>>> my_class.method(‘Albert’)
Good-bye Albert
>>>
Вам не показалось странным, что мы указали при создании функции method два аргумента (self,name), а при его вызове только один (‘World’)? Дело в том, что Python сам подставляет вместо self имя объекта. Т.е. my_class.method(‘World’) аналогичен method(my_class, ‘World’).
Как видно, первым аргументом метода является self. Он обязателен и используется, когда внутри функций необходимо обращаться к другим атрибутам и методам класса. Любая же переменная внутри функций, не начинающаяся с self, будет являться локальной. Если необходимо при создании объекта указать начальные параметры, то нужно определить функцию с именем __init__:
>>> class new2:
... def __init__(self, name):
... self.attribute = name
... self.method()
... def method(self)
... text = ‘Hello’
... print text, self.name
...
>>> my_class2 = new2(‘Albert’)
Hello Albert
>>>
К сведению, объекты могут и не иметь методов, а содержать только атрибуты — в этом случае они играют роль хранилищ. Причем атрибуты у объекта можно создавать уже и после его создания:
>>> my_class2.new_attribute = 1024
>>> print my_class2.new_attribute
1024
>>>
На этом про объекты пока все. Теперь вы можете создавать специализированные классы, выполняющие определенные функции. Почти так же работают и модули.
Модули и как их использовать
С точки зрения Python модуль это тоже объект. Он имеет атрибуты и методы, которые мы обычно используем в программе в виде переменных и функций. Кроме того, модуль также может содержать и другие объекты, которые, в свою очередь, имеют атрибуты и методы... и т.д.
Возьмем, к примеру, модуль appuifw. Для того чтобы узнать все его возможности, можно использовать функцию dir(). Набрав dir(appuifw), вы увидите список имен всех тех переменных и функций, которые доступны пользователю. У меня установлена новейшая, на момент написания, версия Python 1.4.0. (не забывайте постоянно обновляться!), и выполнение этой функции дало следующий результат:
>>> import appuifw
>>> dir(appuifw)
[‘Canvas’, ‘Form’, ‘Listbox’, ‘Text’, ‘Icon’, ‘Content_handler’, ‘app’, ‘multi_query’, ‘note, ‘popup_menu’, ‘query’, ‘selection_list’, ‘multi_selection_list’, ‘available_fonts’, ‘EEventKeyUp, ‘EEventKeyDown’, ‘EEventKey’, ‘FFormAutoFormEdit’, ‘FFormAutoLabelEdit’, ‘FFormDoubleSpaced’, ‘FFormEditModeOnly’, ‘FFormViewModeOnly’, ‘STYLE_BOLD’, ‘STYLE_ITALIC’, ‘STYLE_STRIKETHROUGH’, ‘STYLE_UNDERLINE’, ‘HIGHLIGHT_STANDARD’, ‘HIGHLIGHT_ROUNDED’, ‘HIGHLIGHT_SHADOW’, ‘EScreen’, ‘EApplicationWindow’, ‘EStatusPane’, ‘EMainPane’, ‘EControlPane’, ‘ESignalPane’, ‘EContextPane’, ‘ETitlePane’, ‘EBatteryPane’, ‘EUniversalIndicatorPane’, ‘ENaviPane’, ‘EFindPane’, ‘EWallpaperPane’, ‘EIndicatorPane’, ‘EAColumn’, ‘EBColumn’, ‘ECColumn’, ‘EDColumn’, ‘EStaconTop’, ‘EStaconBottom’, ‘EStatusPaneBottom’, ‘EControlPaneBottom’, ‘EControlPaneTop’, ‘EStatusPaneTop’]
>>>
Как видно, данный модуль представляет огромное количество средств для создания уникального интерфейса программы — ее «лица». Какие бы нужные функции программа не выполняла, необходимо обязательно продумать то, как это представить пользователю. А последний (думаю, по себе знаете) терпеть не может разбираться и угадывать то, что умеет программа, а чего нет. Если в программе тяжело разобраться, то она стирается и заменяется аналогом. Поэтому важно уделить время созданию интуитивного интерфейса, и в этом нам поможет модуль appuifw.
От слов перейдем к делу, а конкретно — к диалоговым функциям:
note(text[, type[, global] ]
Создает окно для вывода сообщения, которое держится около 3 секунд. Имеет обязательный аргумент text (строка Unicode) — само сообщение. Второй параметр необязательный и обозначает тип сообщения. По умолчанию равен ‘info’, но может иметь значения ‘error’ и ‘conf’. Третий аргумент, также необязательный, можно выставить на значение 1. В этом случае информационное окошко появится даже тогда, когда сама программа скрыта (свернута):
>>> appuifw.note(‘Hello!’)
>>> appuifw.note(‘Error!’, ‘error’)
>>> appuifw.note(‘OK’, ‘conf’)
>>>
popup_menu(list[, label])
Создает окно с выбором варианта из имеющего списка. Аргумент list должен быть списком строк Unicode, которые и будут являться описанием имеющихся вариантов. При выборе того или иного варианта, функция возвращает его номер. Необязательный аргумент label указывает подпись окошка:
>>> list = [
u’Open’,
u’Delete’,
u’Save’,
u’Load’]
>>> index = appuifw.popup_menu(list, u‘Menu:’)
>>> index
0
>>> list[index]
u’Open’
>>>
popup_menu(list[, label])
query(label, type [, initial_value]])
Создает окно для ввода данных. Аргумент label (строка Unicode) указывает подпись окна. Аргумент type указывает тип окна:
1) ‘text’ — ввод текста;
2) ‘code’ — ввод текста в виде звездочек (для паролей);
3) ‘number’ — ввод целого числа;
4) ‘float’ — ввод вещественного числа;
5) ‘date’ — ввод даты;
6) ‘time’ — ввод времени;
7) ‘query’ — вопрос («ОК» или «Отмена»).
Причем:
1) ‘text’и ‘code’ — возвращают текст;
2) ‘number’ и ‘float’ — целое и вещественное число соответственно;
3) ‘date’ и ‘time’ — значение в секундах в виде вещественного числа;
4) ‘query’ — 1 или None.
Необязательный аргумент initial_value определяет значение окна по умолчанию (игнорируется для ‘float’):
>>> appuifw.query(u’Text:’, ‘text’)
u’Hello!’
>>> appuifw.query(u’Code:’, ‘code’)
u’Parol’
>>> appuifw.query(u’Number:’, ‘number’)
2007
>>> appuifw.query(u’Float:’, ‘float’)
1.333333’
>>> appuifw.query(u’Date:’, ‘date’)
1183755600.0
>>> appuifw.query(u’Time:’, ‘time’)
75600.0
>>> appuifw.query(u’Good-bye?’, ‘query’)
1
>>>
type = ‘text’
type = ‘code’
type = ‘number’
type = ‘float’
type = ‘date’
type = ‘time’
type = ‘query’
multi_query(label1, label2)
Создает окно, состоящее из двух полей для ввода текста. При нажатии OK — возвращает кортеж из двух введенных строк. Функция вызывается с двумя аргументами: подписи первого и второго полей (строки Unicode):
>>> appuifw.multi_query(u’Text1:’, u’Text2:’)
(u’Hello’, u’World’)
>>>
multi_query(label1, label2)
selection_list(list [, search_field])
Создает окно со списком вариантов, позволяет выбрать один из них. Аргумент list должен быть списком строк Unicode, которые являются описанием имеющихся вариантов. При выборе того или иного варианта функция возвращает его номер. Если необязательный аргумент search_field равен единице, то под окошком появляется поле для поиска:
>>> list = [
u’Symbian’,
u’Window Mobile’,
u’Linux’,
u‘Palm’]
>>> index = appuifw.selection_list(list)
3
>>> list[index]
u’Palm’
>>> appuifw.selection_list(list, 1)
0
>>>
selection_list(list)
selection_list(list, 1)
multi_selection_list(list [, style=’checkbox’, search_field=0 ])
Создает окно для выбора нескольких вариантов из имеющего списка с помощью установления напротив них флажков. Выбор осуществляется нажатием на джойстик. Аргумент list должен быть списком строк Unicode, которые будут являться описанием имеющихся вариантов. При выборе одного или нескольких вариантов функция вернет их список. Необязательный аргумент style указывает стиль исполнения: по умолчанию он равен «checkbox» (флажки находятся слева), но может быть равен «checkmark» (флажки находятся справа). Если необязательный аргумент search_field равен единице, то под окошком появляется поле для поиска:
>>> list = [
u’Symbian’,
u’Window Mobile’,
u’Linux’,
u‘Palm’]
>>> appuifw.multi_selection_list(list)
(0, 1)
>>>
multi_selection_list(list)
multi_selection_list(list, search_field =1)
available_fonts()
Возвращает список шрифтов (их имена в Unicode), установленных на смартфоне:
>>> appuifw.available_fonts()
[u'Alpi12', u'Albi12', u'Alp13', u'Alpi13', u'Albi13', u'alp17', u'Alb17b', u'albi17b', u'alpi17', u'Aco13', u'Aco21', u'Acalc21', u'LatinBold12', u'LatinBold13', u'LatinBold17', u'LatinBold19', u'LatinPlain12', u'Acb14', u'Acb30', u'Acp5', u'Nokia Sans S60', u'Nokia Sans SemiBold S60', u'Nokia Sans TitleSmBd S60', u'Series 60 ZDigi']
>>>
app
Является объектом, который не нужно создавать, так как это уже произошло при загрузке модуля — просто используем его возможности. Объект имеет следующие атрибуты:
body
Отвечает за рабочую область приложения (его «тело»). Может быть присвоен один из трех объектов: Text, Canvas, Listbox. Что это за объекты, будет рассказано в следующих статьях.
menu
Этому атрибуту присваивается специального вида список для создания меню (вызывается при нажатии на левую софт-клавишу):
>>> def exit():
... if appuifw.query(u»You want exit?», «query»)==1:
... appuifw.app.set_exit()
...
>>> appuifw.app.menu = [(u»Exit»,exit)]
>>>
Теперь попробуйте нажать на левую софт-клавишу (появится меню для выбора нужной функции).
Общий вид списка: [(title1, callback1), (title2, callback2),...,(titleN, callbackN)]. Каждый кортеж состоит из одного элемента в виде строки, отвечающего за имя пункта, и второго элемента в виде имени функции, вызываемой сразу после выбора пункта. Вот пример с несколькими пунктами:
>>> def about():
... appuifw.note(u’My name Python!’)
...
>>> def exit():
... if appuifw.query(u»You want exit?», «query»)==1:
... appuifw.app.set_exit()
...
>>> menu = [
...(u’About’, about),
...(u’Exit’, exit)]
>>> appuifw.app.menu = menu
>>>
Обычное меню.
Если необходимо сделать вложенное меню в каком-нибудь пункте, то вместо имени функции указывается кортеж такого же вида (title1, callback1), (title2, callback2),...,(titleN, callbackN)):
>>> def up():
... appuifw.note(u‘Up’)
...
>>> def down():
... appuifw.note(u‘Down’)
...
>>> def left():
... appuifw.note(u‘Left’)
...
>>> def right():
... appuifw.note(u‘Right’)
...
>>> def about():
... appuifw.note(u’My name Python!’)
...
>>> def exit():
... if appuifw.query(u»You want exit?», «query»)==1:
... appuifw.app.set_exit()
...
>>> go = (
...(u’Up’, up),
...(u’Down’, down),
...(u’Left’, left),
...(u’Right’, right))
>>> menu = [
...(u’Go’, go),
...(u’About’, about),
...(u’Exit’, exit)]
>>> appuifw.app.menu = menu
>>>
Вложенное меню.
Такая организация списков (на разных строках) не даст запутаться стороннему программисту, да и себе тоже.
screen
Атрибут отвечает за размер видимой части экрана приложения. Может иметь три значения: ‘normal’ (по умолчанию), ‘large’ (средний), ‘full’ (на весь экран — обычно используется в играх):
>>> def normal():
... appuifw.app.screen = ‘normal’
...
>>> def large():
... appuifw.app.screen = ‘large’
...
>>> def full():
... appuifw.app.screen = ‘full’
...
>>> menu = [
...(u’Normal’, normal),
...(u’Large’, large),
...(u’Full’, full)]
>>> appuifw.app.menu = menu
screen = ‘large’
screen = ‘full’
screen = ‘normal’
title
Атрибут отвечает за подпись приложения в верхней части экрана. Часто программисты задают его изменение в зависимости от ситуации по ходу выполнения программы, а не только единовременно после запуска:
>>> print appuifw.app.title
u’Python’
>>> appuifw.app.title = u’Hello World!’
>>>
Подпись приложения.
orientation
Атрибут отвечает за ориентацию экрана. Может иметь следующее значения: ‘automatic’ (по умолчанию), ‘portrait’ (портретный режим) и ‘landscape’ (ландшафтный режим). Данный атрибут актуален только для смартфонов с Symbian 9.
>>> appuifw.app.orientation
‘avtomatic’
>>> appuifw.app.orientation = ‘portrait’
>>> appuifw.app.orientation = ‘landscape’
>>>
Атрибуты кончились, переходим к методам объекта app:
exit_key_handler()
Этот метод вызывается при нажатии на правую софт-клавишу (именно на нее обычно нажимают для выхода из программы или отмены действия):
>>> def exit():
... if appuifw.query(u»You want exit?», «query»)==1:
... appuifw.app.set_exit()
>>> appuifw.app.exit_key_handler = exit
>>>
Теперь попробуйте нажать на правую софт-клавишу. В общем, ему может быть присвоено имя любой функции.
focus()
Этот метод вызывается при изменении активности приложения: если приложение сворачивается, то эта функция вызывается с аргументом 0, если приложение становится активным — то с аргументом 1:
>>> def call(focus):
... if focus == 1:
... print ‘foreground’
... else:
... print ‘background’
...
>>> appuifw.app.focus = call
>>>
background
>>>
foreground
>>>
Для того чтобы получить то же самое, после набора кода сначала сверните Python, а потом перейдите к нему через Диспетчер задач.
full_name()
Метод возвращает полный путь к тому *.app-файлу (на Symbian 9 бывает и *.exe-файл), который запустил нашу *.py-программу (выполняющуюся в данный момент). Очень удобно использовать, когда необходимо получить путь к рабочей папке программы:
>>> appuifw.app.full_name()
u’c:\system\apps\Python\Python.app’
>>>
uid()
Метод возвращает UID того *.app/*.exe-файла, который запустил нашу *.py-программу (выполняющуюся на данный момент):
>>> appuifw.app.uid()
u’10201515’
>>>
set_exit()
Метод производит немедленный выход из программы (на Nokia 6120 с Symbian 9.2 это не сработало — возможно, и на других то же самое).
layout(id)
Метод возвращает информацию о размере (первый кортеж) и положение (второй кортеж) элементов интерфейса: экрана, различных панелей и т.д. Координаты отсчитываются с левого верхнего угла. Нужная информация выводится в зависимости от переменной