Рейтинг
+1.14
голосов:
1
avatar

Платформа Symbian  

Публикация мобильного приложения в OVI

В этой статье я расскажу о том, что нужно сделать с проектом для публикации в OVI. 

Предположим, что у вас есть готовое мобильное qt-приложение, которое вы хотите опубликовать. Можете воспользоваться этой



( Читать дальше )

Разработка простого QT приложения для Symbian S60

В этой статье я поделюсь своим опытом разработки простого QT приложения для Symbian S60, участвовавшего в конкурсе на лучшее Qt - приложение среди выпускников первого тура Qt тренингов России и занявшего первое место в Москве, опишу тонкие, на


( Читать дальше )

Мобильное ПО как бизнес

В этой статье я расскажу о том, как создавать и продавать shareware – программы для мобильных аппаратов на базе операционной системы Symbian. Данный материал отличается тем, что основан на моем личном опыте в построении с нуля малого бизнеса по разработке и продаже ПО для смартфонов. Мы изучим что нужно, чтобы стать не только квалифицированным, но и успешным разработчиком.

( Читать дальше )

Знакомство с С-классами

Знакомство с C-классами

Перевод оригинальной статьи "Introduction to C-classes" для сайта Symbian Developer Network.

Авторы: разработчики компании Penrillian. Перевод: Александр Смирнов.



( Читать дальше )

Python на Symbian S60: объект Text, строки

Python на Symbian S60: объект Text, строки


Автор: Газетдинов Альберт

Источник: «Онлайн-журнал Mobi»



Объект Text представляет текстовое поле для ввода текста. Над текстом можно совершать простейшие операции: удалять (клавиша «C») и копировать/вставлять (удерживание клавиши «карандаш»). Не хватает только возможности изменения языка ввода (используется английский). Программист может усовершенствовать поле: сделать меню Функции, привязать к нажатиям на клавиши определенные события. Интерактивная консоль самого Python  – модифицированный вариант объекта Text, в ней наличествует меню, по нажатию на джойстик выполняется введенная команда.

Скачать пример TextBox.py



( Читать дальше )

Python на Symbian S60: словари и объект Form, вкладки

Python на Symbian S60: словари и объект Form, вкладки


Автор: Газетдинов Альберт

Источник: «Онлайн-журнал Mobi»

Объект Form – это диалоговое окно, элементы которого можно редактировать по своему усмотрению. Используется форма для вывода информации (свойств файла, например) и настройки программы. Каждый элемент формы состоит из названия и поля с данными (число, текст и т.д.).

Скачать пример FormBox.py

Создание объекта

Form создается как обычный объект, при этом ему передаются аргументы, которые отвечают за его содержимое и вид:

>>> import appuifw

>>> form = appuifw.Form(fields [,flags])

>>>

Аргумент fields должен представлять список кортежей, каждый из которых отвечает за один элемент формы – [(label, type[, value ]),…]. Где:

1) label – название элемента (строка);

2) type – тип поля элемента (строка, варианты будет даны чуть ниже);

3) value – значение элемента по умолчанию (не обязателен).

Существуют следующие типы полей элементов формы:

1) «text» – текст;

2) «number» – целое число;

3) «float» – вещественное число;

4) «date» – дата;

5) «time» – время;

6) «combo» – список.

Аргумент flags (он необязательный) настраивает вид элементов формы и может принимать следующие значения:

FFormViewModeOnly

Устанавливает, что поля элементов формы доступны только для просмотра (их редактирование не допускается).

FFormEditModeOnly

Устанавливает, что поля элементов формы доступны и для редактирования.

FFormAutoLabelEdit

Разрешает возможность редактирования не только полей элементов, но и их  названий.

FFormAutoFormEdit

Разрешает динамически изменять содержимое формы (т.е. удалять и добавлять элементы прямо по ходу работы).

FFormDoubleSpaced

Указывает представить элементы в двухстрочном  виде: на первой строке расположено имя, на втором – поле.

Работа нескольких флагов одновременно организуется с помощью логической операции « | ».

После создания Form есть доступ к следующим атрибутам:

menu

Меню формы. Атрибуту необходимо присвоить список, состоящий из кортежей. Каждый кортеж отвечает за один пункт меню: [(title, callback),..]. Где: title – имя пункта, callback – имя функции, вызываемой сразу после нажатия на пункт. Меню должно быть только одноуровневым (т.е. никаких вложений). Кроме того, в случае когда установлен флаг FFormEditModeOnly (редактирования полей) появится пункт меню «Изменить».

save_hook

Этому атрибуту присваивается имя функции, которой передается единственный аргумент – содержимое формы. Задача save_hook – проверить верность введенных данных и вернуть логическое значение: True, если новое содержимое принимается как дозволенное, False – данные неприемлемы.

Также Form имеет несколько методов (функций то бишь):

execute()

Активирует форму, после чего она становится видимой и доступной для работы.

insert(index, field)

Вставляет новый элемент field после элемента с индексом index.

pop()

Возвращает значение последнего элемента и  сразу же удаляет.

length()

Возвращает количество элементов формы.

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

>>> list = [

(u’text’, ‘text’, u’\u0422\u0435\u043a\u0441\u0442’),

(u’number’, ‘number’, 1024),

(u’float’, ‘float’),

(u’date’, ‘date’, 1183755600.0),

(u’time’, ‘time’, 21600.0),

(u’combo’, ‘combo’, ([u’Symbian’, u’Windows Mobile’, u’Linux’], 2))]

>>>

Заметьте:

1) в текстовом поле использованы русские символы (Юникод);

2) элемент типа ‘float’ не может иметь значение по умолчанию;

3) при использовании типов ‘date’ и ‘time’ значения указываются в секундах;

4) в ‘combo’ использован кортеж, состоящий из списка строк (каждый из которых представляет собой один вариант выбора) и номера варианта, выделенное по умолчанию: ([label, ...], index)

Пока никаких флагов не устанавливаем, поэтому сразу создадим форму и запустим (Рис. 1):

>>> import appuifw

>>> form = appuifw.Form(list)

>>> form.execute()

>>>

Рис. 1. Форма активирована.

 

Получили список одноуровневых элементов (имя, двоеточие и поле), но которые нельзя изменить. Этот вариант подходит в основном для вывода информации (например, свойства чего-либо). Для осуществления ввода данных необходимо установить флаг FFormEditModeOnly (Рис. 2).

>>> form = appuifw.Form(list, appuifw.FFormEditModeOnly)

>>> form.execute()

>>>

 

Python на Symbian S60
Рис. 2. Элементы формы поддаются изменению.

Если нужно больше места для имени и поля, можно использовать флаг FFormDoubleSpaced (Рис. 3–4)

>>> form = appuifw.Form(list, appuifw.FFormEditModeOnly | appuifw.FFormDoubleSpaced)

>>> form.execute()

>>>

Python на Symbian S60
Python на Symbian S60
Рис. 3. Стало больше места. Рис. 4. Стало больше места.

После выхода из формы данные становятся доступны для просмотра – объект Form превращается в список полей:

>>> form[2]

1.33333

>>> form[5]

u’Symbian’

>>>

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

set_tabs(tab_texts[ ,callback=None])

Создаем вкладки, название которых содержится в списке tab_texts. Аргументу callback присваивается имя функции, вызываемой после каждого перехода по вкладкам. При этом передается аргумент в виде номера активированной вкладки. Переход по вкладкам происходит с использованием клавиш «Влево» и «Вправо».

>>> import appuifw

>>> def change(index):

…          if index == 0:

…              appuifw.app.body = appuifw.Text(u’Hello World!’)

…          elif index == 1:

…              appuifw.app.body = appuifw.ListBox([u’One’, u’Two’])

>>> list_tabs = [u’Text’, u’List’]

>>> appuifw.app.set_tabs(list_tabs, change)

>>> appuifw.app.activate_tab(0)

>>>

Python на Symbian S60
Python на Symbian S60
Рис 5. Первая вкладка. Рис. 6. Вторая вкладка.

 

activate_tab(index)

Активирует вкладку под номером index.

На этом пока все, продолжу я статью рассказом о новом типе данных – словарь.

Создание и изменение словаря

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

Создается словарь путем перечисления пары ключ : значение через запятую, все это нужно заключить в фигурные скобки. Обращение к значению элемента производится только по ключу:

>>> dict = {‘S’ : ‘Symbian’, ‘WM’ : ’Windows Mobile’}

>>> dict[‘S’]

‘Symbian’

>>>

Примечание – если в словарь записывается несколько значений с одинаковым ключом, то сохраняется только последний:

>>> dict = {‘S’ : ‘Symbian S60’, ‘WM’ : ’Windows Mobile’, ‘S’ : ‘Symbian UIQ’}

>>> dict[‘S’]

‘Symbian UIQ’

>>>

У словаря можно получить длину функцией len(), удаляется запись с помощью оператора del, кроме того, словарь поддается изменению:

>>> dict = {‘S’ : ‘Symbian’, ‘WM’ : ’Windows Mobile’, ‘L’ : ‘Linux}

>>> len(dict)

3

>>> del dict[‘L’]

>>> dict

{‘S’ : ‘Symbian’, ‘WM’ : ’Windows Mobile’}

>>> len(dict)

2

>>> dict[‘S’] = ‘Symbian S60’

>>> dict[‘P’] = ‘Palm’

>>> len(dict)

3

>>> dict

{‘S’ : ‘Symbian S60’, ‘WM’ : ’Windows Mobile’, ‘P’ : ‘Palm’}

>>>

Как вы могли обратить внимание, если при попытке изменить словарь мы обращаемся по несуществующему ключу (dict[‘P’] = ‘Palm’), то создается новая запись (‘P’ : ‘Palm’), т.е. это является одним из способов добавления новых элементов в словарь.

Python на Symbian S60
Рис. 7. Создаем словарь и изменяем его.

Методы словарей

clear()

Удаляет все записи из словаря:

>>> dict = {1 : ’One’, 2 : ’Two’, 3 : ’Three’}

>>> dict.clear()

>>> dict

{}

>>>

copy()

Возвращает копию словаря:

>>> dict1 = {1 : ’One’, 2 : ’Two’, 3 : ’Three’}

>>> dict2 = dict1.copy()

>>> dict2

{1:’One’, 2:’Two’, 3: Three’}

>>>

has_key(k)

Возвращает 1, если словарь содержит запись с ключом k:

>>> dict = {1 : ’One’, 2 : ’Two’, 3 : ’Three’}

>>> dict.has_key(3)

1

>>> dict.has_key(4)

0

>>>

items()

Возвращает список записей в виде (key, value):

>>> dict = {1 : ’One’, 2 : ’Two’, 3 : ’Three’}

>>> dict.items()

[(1, ’One’), (2, ’Two’), (3, ’Three)]

>>>

keys()

Возвращает список всех ключей:

>>> dict = {1 : ’One’, 2 : ’Two’, 3 : ’Three’}

>>> dict.keys()

[1, 2, 3]

>>>

values()

Возвращает список всех значений:

>>> dict = {1 : ’One’, 2 : ’Two’, 3 : ’Three’}

>>> dict.keys()

[’One’, ’Two’, ’Three’]

>>>

update(m)

Добавляет в словарь все записи словаря m:

>>> dict1 = {1 : ’One’, 2 : ’Two’, 3 : ’Three’}

>>> dict2 = {4 : ’Four’, 5 : ’Five’}

>>> dict1.update(dict2)

>>> dict1

{1 : ’One’, 2 : ’Two’, 3 : ’Three’, 4 : ‘Four’, 5 : ‘Five’}

>>>

get(k [,v])

Возвращает значение с ключом k, но только если он есть, иначе возвращает значение v (по умолчанию None):

>>> dict = [1 : ’One’, 2 : ’Two’, 3 : ’Three’]

>>> dict.get(3, ‘Error’)

’Three’

>>> dict.get(4, ‘Error’)

‘Error’

>>>

setdefault(k [,v])

Возвращает значение с ключом k, если такого ключа нет, то метод возвращает  значение v (по умолчанию None), при этом одновременно добавив в словарь новую запись k : v:

>>> dict = [1 : ’One’, 2 : ’Two’, 3 : ’Three’]

>>> dict.setdefault(4, ‘Four’)

‘Four’

>>> dict

{1 : ’One’, 2 : ’Two’, 3 : ’Three’, 4: ‘Four’}

>>>

Для закрепления теории приведу пример FormBox.py, где в интерактивном режиме можно изменить содержимое формы, причем все данные хранятся в словаре.

FormBox.py

Скачать пример FormBox.py

Структура программы на этот раз необычная. В начале мы, как всегда, подключаем модули. Однако в конце переработано все.

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

dict = {u'Безымянный': u'Пусто'}

form = appuifw.Form([(u'Безымянный', 'text', u'Пусто')], appuifw.FFormAutoLabelEdit | appuifw.FFormDoubleSpaced)

Во-вторых, мы указываем форме вызывать функцию save_dict при каждом изменении и создаем меню (заметьте, пункт «Изменить» уже имеется по умолчанию):

form.save_hook = save_dict

form.menu = [

(u'Добавить', insert),

(u'Удалить', pop),

(u'Очистить', clear),

(u'Ключи keys),

(u'Значения', values),

(u'Проверка, has_key),

(u'Найти', get)]

Python на Symbian S60
Рис. 8. Меню функции FormBos.py.

В-третьих, изменили код проверки источника запуска программы. Теперь, при запуске примера из интерактивной консоли, изменяем подпись и нейтрализуем функцию выхода из программы (делаем ее «пустышкой» на основе lambda). В самом конце она будет вызваться, но если программа запущена из консоли, то ничего не произойдет. А вот если программа запущена из другого *.app приложения, то функция для выхода сработает на совесть (что нам и надо, так как иначе сама программа не закроется).

if appuifw.app.full_name().lower().find(u"python")!=-1:

appuifw.app.title=u'FormBox'

appuifw.app.set_exit=lambda:0

Также добавлен бесконечный цикл, который при выходе из формы запрашивает выход уже из программы. В случае положительного ответа команда break прервет выполнение цикла и сработает функция выхода, иначе вновь запустится форма (причем данные формы никуда не пропадут и все вернется обратно в целости и сохранности).

while 1:

form.execute()

if appuifw.query(u'Выйти из программы?', 'query'):

break

А теперь рассмотрим остальные функции в теле программы.

def save_dict(list):

global dict

dict={}

for index in list:

dict[index[0]]=index[2]

return True

Функция обновляет содержимое словаря в соответствии с новым содержимым формы:

1) делаем словарь пустым;

2) перебираем циклом все элементы полученного списка (напомню, аргументу функции передается содержимое формы в виде списка кортежей);

3) для каждого элемента формы создаем запись в словаре (ключом становится имя  элемента – [0], значением – его поле [2]);

4) обязательно возвращаем True, чтобы форма приняла новое содержимое, иначе в случае возврата False все изменения отменятся;

def insert():

global dict

try:

key, volume = appuifw.multi_query(u'Название элемента:', u'Содержимое элемента:')

except:

pass

else:

dict[key]=volume

form.insert(len(dict)-1, (key, 'text', volume))

Функция для вставки нового элемента в форму:

1) получаем от пользователя название имени и содержимое поля будущего элемента формы;

2) если ввод был отменен, произойдет ошибка (при отмене возвращается None, а это не кортеж, и он не распаковывается – вот это и приведет к ошибке) и функция завершится;

3) иначе создаем в словаре новую запись;

4) вставляем в конец формы новый элемент.

Python на Symbian S60
Python на Symbian S60
Рис. 9. Вставляем новые элементы. Рис. 10. Пара штук успешно добавилась.

 

def pop():

global dict

if len(dict)==1:

appuifw.note(u'Форма должна содержать хотя бы один элемент.', 'error')

return False

else:

element=form.pop()

del dict[element[0]]

return True

Функция для удаления последнего элемента формы:

1) если длина словаря равна единице, то информируем пользователя об ошибке (так как в форме должен быть минимум один элемент) и возвращаем False (зачем это, скажу ниже);

2) иначе получаем последний элемент формы и одновременно удаляем его;

3) удаляем из словаря значение по ключу (первый элемент кортежа) и возвращаем True.

def clear():

while pop():

pass

Функция для удаления всех элементов формы (хотя один по-любому останется). Представляет из себя бесконечный цикл для удаления элементов с конца и выполняется до тех пор, пока  функция pop() не вернет False (т.е. больше элементов удалять уже нельзя). Именно для этого случая мы в вышеописанной функции и использовали return False/True, ведь для самого pop() они не нужны, а так убили двух зайцев и получили простейшую функцию.

def keys():

global dict

appuifw.query(u', '.join(dict.keys()), 'query')

Функция для вывода всех ключей из словаря. Преобразует список ключей в строку, при этом элементы списка соединяются между собой запятыми с помощью метода строки.

def values():

global dict

appuifw.query(u', '.join(dict.values()), 'query')

Функция для вывода всех значений в словаре (аналогичен вышеописанной функции).

def has_key():

global dict

key=appuifw.query(u'Введите имя элемента.', 'text', u'Безымянный')

if key:

if dict.has_key(key):

appuifw.note(u'Элемент с таким ключом существует.')

else:

appuifw.note(u'Нет элемента с таким ключом.', 'error')

Функция проверяет наличие в словаре элемента с заданным ключом:

1) получаем ключ от пользователя;

2) если ключ введен, то проверяем наличие ключа в словаре, и если такой существует, то информируем пользователя об этом;

3) если нет, то выводим соответствующее сообщение об ошибке.

На заметку – if key выполняется как if key!=None, т.е. на русском это звучит как «Если пользователь что-то ввел…»

Python на Symbian S60
Рис. 11. Ищем значение по его ключу (проще говоря, имени).

def get():

global dict

key=appuifw.query(u'Введите имя элемента.', 'text', u'Безымянный)

if key:

appuifw.note(dict.get(key, u'Нет такого элемента.'))

Функция выводит значение элемента по его ключу:

1) запрашиваем ключ;

2) если он введен, демонстрируем найденное значение. Причем функция работает так, что если значения с таким ключом нет в словаре, то возвращается значение по умолчанию, если же такой ключ есть, то возвращается существующее значение.

Объект Form пригодится любому программисту. Можно просто осуществлять с помощью него настройку приложения, а можно вообще сделать форму главным элементом интерфейса вашей программы, т.е. как сделано в примере. Главное – грамотно использовать все методы объекта и удовлетворение пользователя будет гарантировано.

Скачать пример FormBox.py

Python на Symbian S60: математические функции и работа со временем

Python на Symbian S60: математические функции и работа со временем

Автор: Газетдинов Альберт

Источник: «Онлайн-журнал Mobi»

Модуль math

Скачать пример PyMath.py

 

Модуль math предоставляет доступ к стандартным математическим функциям:

cos(x)

Возвращает косинус числа x.

sin(x)

Возвращает синус числа x.

tan(x)

Возвращает тангенс числа x.

acos(x)

Возвращает арккосинус числа x.

asin(x)

Возвращает арксинус числа x.

atan(x)

Возвращает арктангенс числа x.

atan2(x, y)

Эквивалентно atan(x/y). Аргумент y может быть равен нулю – в этом случае возвращается pi/2.

cosh(x)

Возвращает гиперболический косинус числа x.

sinh(x)

Возвращает гиперболический синус числа x.

tanh(x)

Возвращает гиперболический тангенс числа x.

log(x)

Возвращает натуральный логарифм числа x.

log10(x)

Возвращает десятичный логарифм числа x.

sqrt(x)

Возвращает квадратный корень из числа x.

pow(x, y)

Возвращает x в степени y и эквивалентно x**y.

Рис. 1. Функции из модуля math.

modf(x)

Возвращает кортеж из пары вещественных чисел – дробной и целой части x.

ceil(x)

Возвращает наименьшее вещественное число с нулевой дробной частью - большее, чем число x.

floor(x)

Возвращает наибольшее вещественное число с нулевой дробной частью - меньшее, чем число x.

fabs(x)

Возвращает абсолютное значение числа x.

fmod(x, y)

Возвращает остаток от деления x на y и эквивалентно x%y.

exp(x)

Возвращает e**x.

frexp(x)

Возвращает пару чисел в виде кортежа (m, e), где m – мантисса (вещественное число), а e – экспоненциальная часть (целое число). Для чисел m и e всегда выполняется условие x=m*2**e. Если аргумент x равен нулю, возвращает (0.0, 0). В противном случае всегда выполняется 0.5<=abs<1.

ldexp(m, e)

Функция обратная frexp() и возвращает m*(2**e).

hypot(x, y)

Возвращает длину гипотенузы прямоугольника со сторонами длиной x и y и эквивалентно sqrt(x*x+y*y).

Модуль также определяет две константы:

pi – число пи.

e – число e.

Модуль random

Этот модуль определяет множество функции, которая генерирует  псевдослучайные числа с различными распространенными распределениями. Однако я представлю только те, которые чаще всего применяются на практике и характеризуются равномерным распределением случайных чисел:

random()

Возвращает случайное вещественное число r, находящееся в диапазоне 0.0?r<1.0.

uniform(a, b)

Возвращает случайное вещественное число r, находящееся в диапазоне a?r<b.

randrage(start, stop, step)

Возвращает случайное целое число r, находящееся в диапазоне range (start, stop, step).

choice(seq)

Возвращает случайный элемент из непустой последовательности seq (список или кортеж).

Python на Symbian S60: математические функции и случайные числа
Рис. 2. Случайный элемент из списка.

Модуль time

Данный модуль предоставляет различные функции для работы со временем. Перед тем как начать описание, отмечу, что точкой отчета является 1970 год и любое время представлено в количестве секунд, прошедшей с этой даты.

altzone

Переменная хранит сдвиг часового пояса в секундах с учетом перехода на летнее время. Если часовой пояс находится восточнее Гринвича, то он принимает отрицательное значение:

>>> import time

>>> time.altzone

-14400

>>>

timezone

Хранит сдвиг часового пояса в секундах без учета перехода на летнее время.

>>> time.altzone

-10800

>>>

clock()

Функция возвращает текущее процессорное время от начала включения смартфона. Может быть использовано для замера производительности.

sleep(secs)

Останавливает выполнение программы на secs секунд.

time()

Возвращает время с начала эпохи по Гринвичу.

>>> time.time()

1186563710.0

>>>

ctime()

Возвращает местное время с начала эпохи.

>>> time.time()

1186574510.0

>>>

gmtime(secs)

Преобразует время secs (выражено в секундах) в кортеж, представляющее время по Гринвичу. Этот кортеж состоит из 9 целых чисел:

1) год (1970-2038);

2) месяц (1-12);

3) день (1-31);

4) час (0-23);

5) минута (0-59);

6) секунда (0-61);

7) день недели (0-6, 0 – это понедельник);

8) число дней от начала года (0-366);

9) флаг коррекции летнего времени (0, 1, -1).

>>> time.localtime(1186563710.0)

(2007, 8, 8, 6, 1, 50, 2, 220, -1)

>>>

localtime(secs)

Преобразует время secs (выражено в секундах) в кортеж, представляющий местное время.

>>> time.localtime(1186563710.0)

(2007, 8, 8, 9, 1, 50, 2, 220, -1)

>>>

mktime(time_tuple)

Преобразует кортеж time_tuple во время в секундах.

>>> time.localtime((2007, 8, 8, 6, 1, 50, 2, 220, -1))

1186563710.0

>>>

asctime(time_tuple)

Преобразует кортеж time_tuple в строку.

>>> time.asctime((2007, 8, 8, 6, 1, 50, 2, 220, -1))

‘Tue Aug 08 06:01:50 2007’

>>>

strftime(format, time_tuple)

Преобразует кортеж time_tuple в соответствии с форматом format в строку. Format представляет из себя строку, содержащую следующие управляющие символы:

1) %a – сокращенное название дня недели;

2) %A – полное название дня недели;

3) %b – сокращенно название месяца;

4) %B – полное название месяца;

5) %c – дата и время;

6) %d – десятичное представление даты (’01’– ’31’);

7) %H – десятичное представление часа (’00’–’23’);

8) %I – десятичное представление часа (’01’–’12’);

9) %j – десятичное представление года (’001’–’366’);

10) %m – десятичное представление месяца (’01’–’12’);

11) %M – десятичное представление минут (’01’–’59’);

12) %p – обозначение ‘AM’ (до полудня) или ‘PM’ (после полудня);

13) %S – десятичное представление секунд (’00’–’61’);

14) %U – десятичное представление порядкового номера недели (‘00’–’53’);

15) %w – десятичное представление дня недели (’0’–’6’);

16) %W – десятичное представление порядкового номера недели (’00’–’53’);

17) %x – дата;

18) %X – время;

19) %y – представление года без указания века (’00’–’99’);

20) %Y – полное десятичное представление года;

21) %Z – название часового пояса;

22) %% – символ ‘%’.

>>> time.strftime(‘%a %b %d %H:%M:%S %Y’, (2007, 8, 8, 6, 1, 50, 2, 220, -1))

‘Tue Aug 08 06:01:50 2007’

>>>

Python на Symbian S60: математические функции и случайные числа
Рис. 3. Московское время.

 

strptime(string, format)

Разбирает строку string в соответствии с форматом format (смотри выше) и возвращает кортеж.

>>> time.strptime(‘Tue Aug 08 06:01:50 2007’, ‘%a %b %d %H:%M:%S %Y’)

(2007, 8, 8, 6, 1, 50, 2, 220, -1)

>>>

Вместе со статьей идет пример PyMath.py, который дает возможность осуществить все возможные математические действия над числами, получить случайные числа, показать время в различной форме. Теперь подробнее.

PyMath.py

Скачать пример PyMath.py

В начале программы, как всегда, подключаем необходимые модули:

import e32,appuifw,math,random,operator,time

Новый модуль operator включает арифметические функции, аналогичные  обычным операторам. Т.е. операцию сложения – «1+2» – можно написать как operator.add(1, 2). Зачем это нужно? Читайте дальше.

Описание меню:

appuifw.app.menu = [

(u'Арифметика', (

(u'сложить', lambda:two(operator.add)),

(u'вычесть', lambda:two(operator.sub)),

(u'умножить', lambda:two(operator.mul)),

(u'поделить', lambda:two(operator.div)),

(u'подкорень', lambda:one(math.sqrt)),

(u'возвести в', lambda:two(math.pow)))),

(u'Тригоном-ие', (

(u'синус', lambda:one(math.cos)),

(u'косинус', lambda:one(math.sin)),

(u'тангенс', lambda:one(math.tan))),

(u'Обр-ые тригоном-ие', (

(u'арксинус', lambda:one(math.acos)),

(u'арккосинус', lambda:one(math.asin)),

(u'арктангенс', lambda:one(math.atan)))),

(u'Гиперболические', (

(u'гип-ий синус', lambda:one(math.cosh)),

(u'гип-ий косинус', lambda:one(math.sinh)),

(u'гип-ий тангенс', lambda:one(math.tanh)))),

(u'Логарифмические', (

(u'натуральный логарифм', lambda:one(math.log)),

(u'десятичный логарифм', lambda:one(math.log10)))),

(u'Время', (

(u'с начала вкл-ия', lambda:out(time.strftime('%H:%M:%S',time.gmtime( time.clock())))),

(u'часовой пояс', lambda:out(time.altzone/3600)),

(u'дата', lambda:out(time.strftime('%A %d %Y',time.localtime()))))),

(u'Случ-ое число', lambda:two(random.uniform)),

(u'Выйти', exit)]

Python на Symbian S60: математические функции и случайные числа
Рис. 4. Немаленькое меню получилось у программы.

Меню получилось невероятно функциональным за счет использования lambda и стандартизации вызова различных функций, подробнее – ниже.

Участок кода для определения источника запуска программы стандартен, поэтому рассмотрю остальные функции программы.

def out(argument):

appuifw.query(u'Ответ:', 'text', unicode(argument)).

Python на Symbian S60: математические функции и случайные числа
Рис. 5. Быстро и удобно выводим любую информацию.

Функция для вывода информации пользователю:

def one(function):

argument=appuifw.query(u'Введите аргумент функции:', 'float')

if argument:

try:

result=function(argument)

except:

appuifw.note(u'Плохой аргумент.', 'error')

else:

out(result)

Функция для обработки одноаргументных функций (с помощью lambda передается имя функции, имеющей один аргумент):

1) запрос у пользователя аргумента функции;

2) если аргумент введен, то вычисляем результат функции;

3) если произошла ошибка, информируем пользователя об этом;

4) иначе выводим результат на экран.

Таким образом, вместо определения 12 функций для сложения, вычитания, умножения, деления, получения квадратного корня, логарифмов и тригонометрических функций, прямо из меню вызываем one() с именем нужной нам функции. Колоссальная оптимизация!

Python на Symbian S60: математические функции и случайные числа
Рис. 6. Вводим аргумент.

def two(function):

try:

argument1, argument2=appuifw.multi_query(u'Первый аргумент:', u'Второй аргумент:')

except:

pass

else:

try:

result=function(float(argument1), float(argument2))

except:

appuifw.note(u'Плохие аргументы.', 'error')

else:

out(result)

Аналог one(), только для двухаргументных функций:

1) получаем от пользователя аргументы функций;

2) если они не введены, то пропускаем все;

3) иначе – вычисляем результат вычисления функции с двумя аргументами;

4) если произошла ошибка – информируем пользователя;

5) иначе выводим результат.

С помощью two() сократили огромное количество кода! Раздувание меню оправдано, когда на другой чаше весов находится необходимость написать несколько десятков однотипных функций. Вероятно, вы так и сделали бы, но lambda идет на помощь!

Вдруг кому-то непонятны lambda функции для работы с модулем time, поэтому я расшифрую одну из них в многострочный код.

Дано:

out(time.strftime('%H:%M:%S',time.gmtime( time.clock()))).

Подробно:

1) time.clock – получаем время по Гринвичу в секундах;

2) time.gmtime – преобразуем время в секундах в кортеж чисел с информацией о времени;

3) time.strftime – преобразуем кортеж чисел в строку в соответствии с шаблоном;

4) out – выводим строку.

Остальные lambda функции работают по аналогии.

Python на Symbian S60: математические функции и случайные числа
Рис. 7. Вводим несколько аргументов.

Таким образом, был показан прекрасный пример оптимизации. Использование lambda в меню дает возможность написать одну функцию вместо нескольких похожих. Конечно, это не единственная сфера применения – используйте lambda там, где это необходимо. Возможно, из-за нее придется перегруживать строки кодом (как в нижней части меню примера), тогда будет легче расшифровать код и вынести его в отдельную функцию. Какой подход вы выберите, напрямую зависит от вашего опыта и профессионализма. И не забывайте - все хорошо в меру!

Скачать пример PyMath.py

Python на Symbian S60: работа с файлами (модуль os и path)

Python на Symbian S60: работа с файлами (модуль os и path)


 

Автор: Газетдинов Альберт

Источник: «Онлайн-журнал Mobi»

Модуль os

Скачай пример FileMan.py

Модуль os позволяет работать с файлами и папками. Сразу отмечу, русские названия файлов и папок возвращаются и принимаются всеми функциями этого модуля в кодировке UTF-8, поэтому необходимо использовать функции для перекодирования строк – методы decode и encode.

listdir(path)

Возвращает список имен файлов и папок в папке с именем path.

mkdir(path)

Создает папку с именем path.

makedirs(path)

Работает аналогично функции mkdir(), но автоматически создает все необходимые промежуточные папки.

remove(path)

Удаляет файл с именем path.

rmdir(path)

Удаляет каталог с именем path.

removedirs(path)

Работает аналогично функции rkdir(), но автоматически удаляет все родительские пустые папки.

rename(src, dst)

Переименовывает файл или папку с именем src в dst.

Модуль path

Модуль path встроен в модуль os и позволяет работать с путями к файлам и папкам.

split(path)

Возвращает кортеж из пары строк – (head, tail). Где: tail – последний компонент пути (имя папки или файла), head  – остальная часть пути:

>>> os.path.split(‘c:\\system\\apps\\Python\\Python.app’)

(‘c:\\system\\apps\\Python\\’, ‘Python.app’)

>>>

splitdrive(path)

Возвращает кортеж из пары строк – (drive, tail). Где: drive – имя диска, head  – остальная часть пути:

>>> os.path.splitdrive(‘c:\\system\\apps\\Python\\Python.app’)

(‘c:\\’, ‘system\\apps\\Python\\Python.app’)

>>>

splitext(path)

Возвращает кортеж из пары строк – (root, ext). Где: ext – расширение файла, head  – остальная часть пути:

>>> os.path.splitext(‘c:\\system\\apps\\Python\\Python.app’)

(‘c:\\system\\apps\\Python\\Python’, ‘.app’)

>>>

dirname(path)

Возвращает имя каталога пути path. Это первый элемент пары split(path):

>>> os.path.dirname(‘c:\\system\\apps\\Python\\Python.app’)

‘c:\\system\\apps\\Python’

 >>>

basename(path)

Возвращает основное имя пути path. Это второй элемент пары split(path):

>>> os.path.basename(‘c:\\system\\apps\\Python\\Python.app’)

‘Python.app’

 >>>

join(path1, path2, …)

Объединяет пути path:

>>> os.path.join(‘c:\\’, ‘system\\apps\\Python\\’, ‘Python.app’)

‘c:\\system\\apps\\Python\\Python.app’

>>>

exists(path)

Возвращает 1, если файл или каталог с именем path существует.

isfile(path)

Возвращает 1, если path указывает на файл.

isdir(path)

Возвращает 1, если path указывает на папку.

getatime(path)

Возвращает время последнего доступа к файлу или папке с именем path.

getmtime(path)

Возвращает время последнего внесения изменения в файл или папку с именем path.

getsize(path)

Возвращает размер файла или папки с именем path.

Работа с файлами

Python обладает встроенными возможностями для открытия файлов, чтения их содержимого или записи в них различных данных.

open(filename, mode)

Возвращает объект-файл с именем filename. Характер работы определяет аргумент mode (по умолчанию ‘r’):

1) ‘r’ – файл открывается для чтения данных;

2) ‘w’ – для записи данных;

3) ‘a’ – для дописывания данных.

Данный объект имеет следующие методы:

read(size)

Считывает из файла данные размером size и возвращает в виде строки. Если аргумент опущен, то считывается все содержимое файла.

readline()

Считывает из файла одну строку, включая символ перехода на новую строку («\n»).

readlines()

Считывает из файла все строки и возвращает их в виде списка.

write(string)

Записывает строку string в файл.

writelines(lines)

Записывает строки из списка lines в файл. Символ перехода на новую строку между ними не добавляется.

tell()

Возвращает текущее положение в файле в байтах от начала файла.

seek(offset, whence)

Изменяет положение на offset. Характер определения положения зависит от аргумента whence (по умолчанию 0):

1) 0 – новое положение отсчитывается от начала файла;

2) 1 – от конца файла;

3) 2 – от текущего положения в файле;

truncate(size)

Усекает файл до размера size.

close()

Закрытие файла. Запомните! Любое открытие файла должно сопровождаться последующим закрытием с помощью этого метода.

На этом все. Ниже будет дано описание программы FileMan.py, которая предоставляет основные возможности любого файл-менеджера: навигация по дискам и папкам, удаление и открытие файлов.

FileMan.py

Скачай пример FileMan.py

Программа начинается с подключения нужных модулей:

import os,e32,appuifw,key_codes

И создания нужных переменных:

list=e32.drive_list()

path=[]

В list будет храниться тот список имен файлов и папок, который передается объекту Listbox для отображения. path хранит список строк, который показывает путь к тому месту в файловой системе, где мы находимся. Т.е. если мы будем находиться в папке ‘c:\\system\\apps\\’, выглядеть path будет следующим образом: [‘c:’, ‘system’, ‘apps’]

Заканчивается программа строками для создания объекта Listbox (при этом ему передается начальный список имен дисков и указывается, чтобы при нажатии на джойстик вызывалась функция select). Также привязывается к нажатию на «C» вызов функции delete:

appuifw.app.body=listbox=appuifw.Listbox(list, select)

listbox.bind(key_codes.EKeyBackspace, delete)

Рис. 1. Начальное окно программы FileMan.py – список дисков.

Также создим меню с единственной функцией для выхода из программы и опишем код для определения источника запуска программы (все стандартно).

Опишу функции основной части программы:

def create():

global list,path

if len(path)==0:

list=e32.drive_list()

else:

full_path='\\'.join(path)

dirs,files=[],[]

for name in os.listdir(full_path):

if os.path.isdir(full_path+'\\'+name):

dirs.append(name.decode('utf-8'))

else:

files.append(name.decode('utf-8'))

dirs.sort()

files.sort()

list=[u'<<<']+dirs+files

listbox.set_list(list)

Функция для создания списка имен папок и файлов в новой папке (в ту, которую мы зашли) и его отображении на объекте Listbox:

1) подключаем глобальные переменные;

2) если путь к файлу по длине равен нулю, то отображаем список дисков;

3) иначе мы получаем путь к новой папке с помощью метода строк для объединения элементов списка;

4) создаем два пустых списка для хранения имен файлов и папок соответственно;

5) создаем цикл для перебора имен всех файлов и папок, находящихся в новой папке;

6) если путь указывает к папке, то добавляем его имя в список для папок, по пути перекодируя его.

7) иначе это путь к файлу, поэтому его имя добавляется в другой список.

8) сортируем оба списка по алфавиту;

9) создаем список для вывода, как сумма элемента обозначающего кнопку назад («<<<») и списков имен папок и файлов;

10) устанавливаем новое содержание объекта Listbox.

def select():

global list,path

index=listbox.current()

dir=list[index].encode('utf-8')

if dir!='<<<' or len(path)==0:

full_path='\\'.join(path)

if os.path.isdir(full_path+'\\'+dir):

path.append(dir)

create()

else:

try:

appuifw.Content_handler().open(full_path+'\\'+dir)

except:

appuifw.note(u'Невозможно открыть файл.','error')

else:

path.pop()

create()

Функция вызывается при нажатии джойстика по выделенному элементу, и в зависимости от того его типа (папка или файл) мы осуществляем соответствующие действия (смотрим содержимое папки или открываем файл):

1) получаем номер той строки, которую мы выделили;

2) получаем имя папки (или файла) из списка по его номеру (не забываем перекодировать, так как список содержит строки в Unicode, а нам надо в UTF-8);

3) если выделена кнопка назад («<<<») или path у нас пустой (когда видим на экране список дисков), то получаем путь в виде строки;

4) проверяем, ведет ли этот новый путь (старый путь плюс новое имя) к папке, и если да, то добавляем в путь новое имя и обновляем список объекта Listbox;

5) иначе этот путь ведет к файлу, и мы открываем его;

6) если произошла ошибка при открытии (тип файла не поддерживается системой), то уведомляем пользователя об этом;

7) иначе (т.е. произошло нажатие на кнопку назад) удаляем имя папки, в которой мы находимся (что равносильно «прыжку» назад);

8) и обновляем список объекта Listbox.

Python на Symbian S60: модуль os
Рис. 2. Смотрим содержимое папки.

def delete():

global path

file='\\'.join(path)+'\\'+list[listbox.current()].encode('utf-8')

if os.path.isfile(file):

if appuifw.query(u'Удалить файл?', 'query'):

try:

os.remove(file)

except:

appuifw.note(u'Невозможно удалить файл.','error')

else:

appuifw.note(u'Файл удален.')

create()

Функция для удаления выделенного файла:

1) получаем номер выделенной строки, получаем его имя из списка имен по номеру, перекодируем и складываем с путем к той папке, где мы находимся, – получаем полный путь к файлу (или папке);

2) если этот путь ведет к файлу (здесь папки и отсекаются), то получаем у пользователя подтверждение для удаления;

3) удаляем файл;

4) если произошла ошибка, информируем пользователя об этом;

5) иначе уведомляем об успешном удалении.

6) обновляем список объекта Listbox.

Python на Symbian S60: модуль os
Рис. 3. Решаем – удалить файл или нет?

Скачай пример FileMan.py

Предполагаю, что если вы читаете эту статью, то предыдущие вы знаете хорошо. Поэтому домашнее задание: добавить функции для переименования файлов и папок для удаления пустых папок; реализовать чтение текстовых файлов (*.txt) и вывод их на объект Text; с помощью объекта Form попробуйте организовать настройки программы. Дерзайте!

Python на Symbian S60: журнал и сообщения

Python на Symbian S60: журнал и сообщения

 

Модуль logs

 

Данный модуль предоставляет доступ к журналу смартфона, где аккумулируется все информация о принятых или отправленных SMS, совершенных звонках и т.д. Модуль включает следующие функции:

 

raw_log_data()

Возвращает все содержимое журнала в виде списка словарей, каждый элемент которого несет определенную информацию о событии:

  • number – номер (строка Unicode);
  • name – имя (строка Unicode);
  • description – тип (например, Short message – короткое сообщение, Voice call – голосовой вызов);
  • direction’- направление (например, Incoming – входящий, Outgoing – исходящий);
  • status – статус (например Sent – отправлено);
  • subject – содержимое;
  • id – уникальный номер;
  • contact’;
  • duration’;
  • duration type’;
  • flags’;
  • link’;
  • data’;
  • time’время события.

 

log_data(type, [start_log=0, num_of_logs=_all_logs, mode=’in’])

Возвращает список событий аналогично logs.raw_log_data(), но в количестве num_of_logs, начиная с позиции start_log, и только определенного типа type:

  • call – вызовы;
  • sms – сообщения;
  • data – передача информации;
  • fax – факс;
  • email – электронные письма;
  • scheduler – событие по расписанию.

Можно указать режим mode:

  • ’in’ входящие;
  • ’out’ исходящие;
  • ’fetched’;
  • ’missed’;
  • ’in_alt’;
  • ’out_alt.

 

log_data_by_time(type, start_time, end_time, [mode=’in’])

Возвращает список событий аналогично logs.raw_log_data(), но во временном  периоде с start_time по end_time, типа type и с режимом mode. Время указывается в секундах.

 

calls([start_log=0, num_of_logs=_all_logs, mode=’in’])

Возвращает список вызовов в количестве num_of_logs, начиная с позиции start_log, и с режимом mode.

 

faxes([start_log=0, num_of_logs=_all_logs, mode=’in’])

Возвращает список факсов в количестве num_of_logs, начиная с позиции start_log, и с режимом mode.

 

emails([start_log=0, num_of_logs=_all_logs, mode=’in’])

Возвращает список электронных писем в количестве num_of_logs, начиная с позиции start_log, и с режимом mode.

 

sms([start_log=0, num_of_logs=_all_logs, mode=’in’])

Возвращает список сообщений в количестве num_of_logs, начиная с позиции start_log, и с режимом mode.

 

scheduler_logs([start_log=0, num_of_logs=_all_logs, mode=’in’])

Возвращает список выполненных событий по расписанию в количестве num_of_logs, начиная с позиции start_log, и с режимом mode.

 

data_logs([start_log=0, num_of_logs=_all_logs, mode=’in’])

Возвращает список событий по передаче данных в количестве num_of_logs, начиная с позиции start_log, и с режимом mode.

 

 

 

Модуль inbox

 

Модуль, позволяющий работать с сохраненными в телефоне SMS, предоставляет доступ к объекту Inbox. При его создании  необходимо передать аргумент folder_type, который может принимать одно из значений:

  • inbox.EInbox – работа с папкой Входящие;
  • inbox.EOutbox – работа с папкой Исходящие;
  • inbox.ESent – работа с папкой Переданные;
  • inbox.EDraft работа с папкой Черновики.

 

После создания объекта можно вызывать следующие его методы:

 

sms_messages()

Возвращает список номеров SMS сообщений, находящихся в папке.

 

content(sms_id)

Возвращает текст SMS сообщения по номеру sms_id.

 

time(sms_id)

Возвращает время создания SMS сообщения по номеру sms_id.

 

address(sms_id)

Возвращает адресата SMS сообщения по номеру sms_id.

 

delete(sms_id)

Удаляет SMS сообщение по номеру sms_id. Если удалить входящее SMS сразу после его прихода, то звукового оповещения не произойдет.

Пример

>>> import inbox

>>> i=inbox.Inbox()

>>> m=i.sms_messages()

>>> i.content(m[0])

u’foobar’

>>> i.time(m[0])

1130267365.03125

>>> i.address(m[0])

u’John Doe’

>>> i.delete(m[0])

>>>

 

unread(sms_id)

Возвращает статус SMS сообщение по номеру sms_id (0 – если сообщение прочтено, 1 – если не прочтено).

 

set_unread(sms_id, status)

Устанавливает статус SMS сообщение с номером sms_id как status (0 – прочтено, 1 – не прочтено).

 

bind(callable)

Привязывает вызов функции с именем callable к появлению нового сообщения в папке, при этом функции передается уникальный номер сообщения sms_id.

 

Локализация приложения под S60. Добавление хелпа. Динамическая локализация приложения и хелпа.

Локализация приложения под S60.

Добавление хелпа. Динамическая локализация приложения и хелпа.

Автор: Дмитрий Тарасов

Источник: dtarasov.ru

Введение

В рамках этой статьи я предлагаю рассмотреть реализацию функционала, который хоть и не является критичным с точки зрения функциональности ПО, но является при этом неотъемлемым аттрибутом любого коммерческого ПО. Если конкретно, то мы рассмотрим процесс локализации приложения и создания локализуемого хелпа. И то, и другое являются необходимыми требованиями Nokia к приложениям, которые рассматриваются на предмет помещения в каталог программ Download!. Поэтому если вы заинтересованы в разработке коммерчески успешного ПО (ну не одни трояны же писать, правда?), то от решения этих задач никуда не деться.

 



( Читать дальше )