Symbian OS
Python / PyS60
1 Andreas Jakl, 2009 v1.2 – 01 March 2009
PyS60 – Examples
● ShakerRacer
www.youtube.com/watch?v=EMjAYdF13cU
2 Andreas Jakl, 2009
PyS60 – Examples
● PyWuzzler (Benjamin Gmeiner, Yen-Chia Lin)
3 Andreas Jakl, 2009
Controlling Super Mario
PyS60 – Examples by movements (jumping,
walking, ...)
● NiiMe
Playing drums
Controlling flight / racing
games with tilting
http://www.niime.com/
4 Andreas Jakl, 2009
PyS60 – Examples
Time-lapse Photography
http://blog.foozia.com/blog/2007/jan/21/python-s60-time-lapse-photography-using-nokia-n80/
aspyplayer
Last.fm-Player for PyS60
http://code.google.com/p/aspyplayer/
pyPoziomica
Use your phone as a level tool
http://www.symbian-freak.com/news/007/12/pypoziomica_freeware_level_tool.htm
PyED
Edit Python source code on the phone
http://sourceforge.net/projects/pyed/
5 Andreas Jakl, 2009
What is it all about?
Python
6 Andreas Jakl, 2009
Python
● Older than you might think:
1989 – 1991 by Guido van Rossum (National Research
Institute for Mathematics and Computer Science,
Netherlands)
Named after Monty Python’s Flying Circus
● Today:
Microcontrollers
Mobile Phones
Web servers
7 Andreas Jakl, 2009
Scalable
● Modular architecture
● Easy code reuse
● Huge Python standard library
● Extension with own C/C++ modules
Shell scripts
Huge projects
8 Andreas Jakl, 2009
Mature
Helpful
Object
Interpreted error
oriented, Very high
& byte- messages,
memory level
compiled exception
manager
handling
9 Andreas Jakl, 2009
Fast
● Rapid Application Prototyping
● Easy to learn – can you read this code?
import inbox, audio
box = inbox.Inbox()
msg_id = box.sms_messages()[0]
msg_txt = u"Message: " + box.content(msg_id)
audio.say(msg_txt)
● What would this be like in C++ or Java ME? ...
10 Andreas Jakl, 2009
Symbian OS + Runtimes
Java ME Python .net Basic Perl
Widgets
Apache / Silverlight
(Web Flash Lite Ruby
PHP / MySQL (soon)
Runtime)
S60
(C++)
Symbian OS
11 Andreas Jakl, 2009
UI Platforms: S60
● Unified UI platform based on S60
Official UI platform of
Symbian Foundation
Former name: Series 60
Nokia N97 ● Touchscreen support with S60 5th
Edition
12 Andreas Jakl, 2009
UI Platforms: S60
www.s60.com
Business High-End Multimedia Mass Market
Nokia N96
Nokia E66 Samsung Omnia HD
Nokia 6121 Classic
Nokia 5800
XPressMusic
Nokia E71
Nokia N85
SE Idou
Nokia 5500 Sport
Nokia E90 Samsung INNOV8
13 Andreas Jakl, 2009 Nokia 6210 Navigator
PyS60
● Python port to S60
● Allows easy access to: Web
Ease of development
Flash
Python
Accelerometer Managed
code
Camera Java
Text-to-speech P.I.P.S.
Location
Symbian
Web services Native code C++
Messaging Functionality and performance
Bluetooth
UI
14 Andreas Jakl, 2009
Setup – Phone PyS60 1.4.x: based on
Python 2.3
PyS60 1.9.2+: based on
Python 2.5.1, supports
● Install the latest Nokia PC Suite: new sensor framework
of S60 3rd Ed., FP2+
http://europe.nokia.com/A4144903
● Download and install PyS60:
1.4.x: http://sourceforge.net/projects/pys60/
1.9.x+: https://garage.maemo.org/projects/pys60/
● Phone:
Phone software: PythonForS60_1_x_x_3rdEd.SIS
Phone script shell: PythonScriptShell_1_x_x_3rdEd.SIS
15 Andreas Jakl, 2009
Setup – PC
● Extract SDK plug-in to the S60 SDK:
PythonForS60_1_x_x_SDK_3rdEd.zip
16 Andreas Jakl, 2009
IDEs
● IDLE – comes with Python SDK
C:\Program
Files\Python\Lib\idlelib\idle.bat
● PythonWin + Win32 Extensions
http://sourceforge.net/projects/pywi
n32/
● PyDev Eclipse/Carbide.c++ Plug-in
http://pydev.sf.net/
● SPE
http://pythonide.stani.be/
17 Andreas Jakl, 2009
Hello World
● Create a file hello.py:
hello.py
print “Hello World”
● Connect your phone to the PC (“PC Suite” connection
mode)
● Transfer the script to E:\Python\ (memory card) using
the Nokia PC suite file manager
● Run the script:
18 Andreas Jakl, 2009
Hello World – Emulator
● Copy hello.py to:
\winscw\c\python\hello.py
● Start the emulator from:
\release\winscw\udeb\epoc.
exe
19 Andreas Jakl, 2009
PyDev + Emulator
● Either create the project / workspace directly in the
python-dir of the emulator
● Or link the project files to source files in the dir:
20 Andreas Jakl, 2009
Starting with the UI
PyS60 – User Interface
21 Andreas Jakl, 2009
Module
● Collection of related functions and data grouped
together
● Has to be imported at the beginning:
import appuifw
● Addressing a function of the module:
appuifw.query(label, name)
● Import multiple modules in a single statement:
import appuifw, e32
22 Andreas Jakl, 2009
import appuifw
Query appuifw.query(u"Type a word:", "text", u"Hello")
appuifw.query(u"Type a number:", "number", 7)
appuifw.query(u"Type a date:", "date")
appuifw.query(u"Type a time:", "time")
appuifw.query(u"Type a password:", "code")
appuifw.query(u"Do you like PyS60?", "query")
Syntax: appuifw.query(label, type[, initial value])
number /
text float date time code query
23 Andreas Jakl, 2009
import appuifw
Note Dialog appuifw.note(u"Hello")
appuifw.note(u"File not found", "error")
appuifw.note(u"Upload finished", "conf")
Syntax: appuifw.note(text[, type[, global] ] )
info /
default error conf
24 Andreas Jakl, 2009
Variables
● Variables not declared ahead of time
● Implicit typing
● Automated memory management
Reference counting, garbage collection
● Variable names can be “recycled”
● del statement allows explicit de-allocation
25 Andreas Jakl, 2009
Variables – Example
age = 5
name = u"Andreas" # u in front of the string: unicode
name += age # Doesn't work, the type isn’t converted automatically
name += str(age) # name == Andreas5
name = age # name now points to the same object as age; name == 5
foo = "xyz" foo “xyz”
bar = foo # bar points to the same object as foo
bar
foo = 123 # a new object is created for foo, bar still points to "xyz“
foo “xyz”
bar 123
26 Andreas Jakl, 2009
Multi-Query Dialog
● Syntax: appuifw.multi_query(label1, label2)
import appuifw
pwd = u"secret"
info = appuifw.multi_query(u"Username:", u"Password:")
if info: // returns a tuple with the info
login_id, login_pwd = info
if login_pwd == pwd:
appuifw.note(u"Login successful", "conf")
else:
appuifw.note(u"Wrong password", "error")
else: // returns None – special type
appuifw.note(u"Cancelled")
27 Andreas Jakl, 2009
if-statement
● Works like in other languages
● Blocks are defined by indentation – avoids dangling else
● if expression1:
expr1_true_suite
elif expression2:
expr2_true_suite
else:
none_of_the_above_suite
28 Andreas Jakl, 2009
Lists, Tuples and Dictionaries
● Generic “arrays” for arbitrary number of arbitrary
objects
● Ordered and accessed via index offsets
● List – created using [ ]
myList = [1, 2, 3, 4] # [1, 2, 3, 4]
print myList[0] #1
# Subsets: sequence[starting_index:ending_index]
print myList[1:3] # [2, 3]
print myList[2:] # [3, 4]
print myList[:3] # [1, 2, 3]
myList[1] = 5 # [1, 5, 3, 4]
myList[2] = ["bla", (-2.3+4j)] # [1, 5, ["bla", (-2.3+4j)], 4]
print myList[2][1] # -2.3+4j
print 4 in myList # True
29 Andreas Jakl, 2009
Lists, Tuples and Dictionaries
● Tuple – created using ( )
Immutable – can therefore be used as dictionary keys
Also useful when you don’t want a function to be able to
change your data
myTuple1 = ('python', 's60', 27)
print myTuple1[0] # python
myTuple[1] = 'no' # tuples are immutable – exception!
myTuple2 = ('symbian', 'uiq')
myTuple3 = myTuple1 + myTuple2
print myTuple3 # ('python', 's60', 27, 'symbian', 'uiq')
30 Andreas Jakl, 2009
Lists, Tuples and Dictionaries
● Dictionary – created using { }
Mapping type – like associative arrays or hashes in Perl
Key-value pairs
– Keys: almost any Python type, usually numbers or stings
– Values: arbitrary Python object
myDict = {'planet': 'earth'}
myDict['port'] = 80
print myDict # {'planet': 'earth', 'port': 80}
print myDict.keys() # ['planet', 'port']
print myDict['planet'] # earth
for key in myDict:
print "key=%s, value=%s" % (key, myDict[key])
# key=planet, value=earth
# key=port, value=80
31 Andreas Jakl, 2009
Popup Menu
● Syntax: appuifw.popup_menu(list[, label ])
import appuifw
items = [u"The Journey", u"RealReplay", u"ShakerRacer"]
index = appuifw.popup_menu(items, u"Buy:")
if index == 0:
appuifw.note(u"Great choice")
elif index == 1:
appuifw.note(u"Cool")
elif index == 2:
appuifw.note(u"I like that")
elif index == None:
appuifw.note(u"Purchase cancelled")
32 Andreas Jakl, 2009
Selection List Search field appears
after pressing a letter key
● Syntax: appuifw.selection_list(choices[, search_field=0])
import appuifw
names = [u"Michael", u"Devon", u"Bonnie", u"April", u"RC3"]
index = appuifw.selection_list(names, 1)
if index == 2:
print "I love you!"
else:
print "You're great!"
33 Andreas Jakl, 2009
Multi-Selection List
● Syntax: appuifw.multi_selection_list(
choices[, style=„checkbox‟, search_field=0])
import appuifw
names = [u"Michael", u"Devon", u"Bonnie", u"April", u"RC3"]
selections = appuifw.multi_selection_list(names, 'checkbox', 1)
print selections
Style: checkmark
Select multiple items with the pen key
Not really important
34 Andreas Jakl, 2009
for loop
● for iter_var in iterable:
suite_to_repeat
● With each loop, iter_var set to current element of
iterable
Similar to foreach in other languages
35 Andreas Jakl, 2009
for Loop – Examples
# Iterating over a string current letter: T
for eachLetter in "Text": current letter: e
print "current letter:", eachLetter current letter: x
current letter: t
# Iterating by sequence item
Charles
nameList = ["Mike", "Sarah", "Charles"]
for eachName in sorted(nameList): Mike
print eachName Sarah
# Iterating by sequence index Mike
for nameIndex in range(len(nameList)):
Sarah
print nameList[nameIndex]
Charles
# Iterate over a range
value: 0
for eachVal in range(3):
print "value: ", eachVal value: 1
value: 2
# Extended syntax:
# range(start, end, step = 1)
for eachVal in range(2, 10, 3):
value: 2
print "value: ", eachVal value: 5
value: 8
36 Andreas Jakl, 2009
while loop
● while expression:
suite_to_repeat
● Nice addition: else is executed if loop was not
abandoned by break
def showMaxFactor(num):
count = num / 2
while count > 1:
if num % count == 0:
print "Largest factor of %d is %d" % (num, count)
break
count -= 1
else:
print num, "is prime"
for eachNum in range(10, 21):
showMaxFactor(eachNum)
37 Andreas Jakl, 2009
Example – System Info SMS
import appuifw, messaging, sysinfo
# You could use a dictionary as well, but here this is more straightforward later on
infoNames = [u"Profile", u"Battery", u"Signal DBM"]
infoCalls = ["sysinfo.active_profile()", "sysinfo.battery()", "sysinfo.signal_dbm()"]
# Let the user choose the information he wants to send
choices = appuifw.multi_selection_list(infoNames, "checkbox", 0)
infoSms = ""
for idx in choices:
# Execute the statement(s) stored in the infoCalls-list through the eval-statement,
# convert the result to a string and append it to the sms text
infoSms += infoNames[idx] + ": " + str(eval(infoCalls[idx])) + "; "
# Query the telephone number
smsNum = appuifw.query(u"Number:", "text", u"+15550135")
if smsNum:
# Send the SMS if the user didn’t cancel
messaging.sms_send(smsNum, infoSms)
appuifw.note(u"Info sent", "conf")
38 Andreas Jakl, 2009
Procedural and Object Oriented Development
Python – Function and Classes
39 Andreas Jakl, 2009
Functions – Basics
● def function_name(arguments):
[“function_documentation_string”]
function_body_suite
● Supports: def foo():
"foo() -- does't do anything special."
Default arguments print "in foo"
Variable length arguments # Execute the function
foo()
Multiple return values # Print the help text of the function
print foo.__doc__
Inner functions # foo() -- does't do anything special.
...
40 Andreas Jakl, 2009
Functions – Default Arguments
● Default arguments:
def func(posargs, defarg1=dval1, defarg2=dval2, ...):
def calcTax(amount, rate=0.0275):
return amount + (amount * rate)
print calcTax(100) # 102.75
print calcTax(100, 0.05) # 105.0
41 Andreas Jakl, 2009
Functions – Variable Length Arguments
● Variable length arguments (unknown number):
Non-keyword variable arguments (tuple):
def func([formal_args,] *vargs_tuple):
Argument with * will hold all remaining arguments once all
formal parameters have been exhausted
Keyword variable arguments (dictionary):
def func([formal_args,][*vargst,] **vargsd):
def tupleVarArgs(arg1, arg2='defaultB', *theRest): tupleVarArgs('abc')
print "formal arg 1: ", arg1 # formal arg 1: abc
print "formal arg 2: ", arg2 # formal arg 2: defaultB
for eachXtraArg in theRest:
print 'another arg: ', eachXtraArg tupleVarArgs('abc', 123, 'xyz', 123.456)
# formal arg 1: abc
# formal arg 2: 123
# another arg: xyz
# another arg: 123.456
42 Andreas Jakl, 2009
global_str = "foo"
Variable Scope
local scope
def foo():
local_str = "bar"
return global_str + local_str
● Global scope
print foo()
Declared outside a function
Lifespan lasts as long as script is running
● Local scope
Live temporarily as long as function they are defined in is
active
● Searching for identifiers
First local, then global
Possible to override global variables by creating a local one
43 Andreas Jakl, 2009
Variable Scope
● Writing to global variables in functions:
Creates a new local variable
(pushes global variable out of scope)
global statement specifically references a named global
variable
def foo(): def foo():
local scope
local scope
bar = 200 global bar
print "in foo(), bar is", bar bar = 200
print "in foo(), bar is", bar
bar = 100
print "in __main__, bar is", bar bar = 100
foo() print "in __main__, bar is", bar
print "in __main__, bar still is", bar foo()
in __main__, bar is 100 print "in __main__, bar is now", bar
in foo(), bar is 200 in __main__, bar is 100
in __main__, bar still is 100 in foo(), bar is 200
in __main__, bar is now 200
44 Andreas Jakl, 2009
Classes
● class MyObject(bases):
“Documentation text”
class_suite
● New style classes should be derived from any other
class or from object
● Simplest use: container object for instance attributes
Not defined in class definition class MyData(object):
pass # code is required syntactically,
Only valid for this instance # but no operation is desired
mathObj = MyData()
mathObj.x = 4
mathObj.y = 5
45 Andreas Jakl, 2009 print mathObj.x * mathObj.y # 20
Classes – Subclasses, Methods
class LibraryEntry(object):
● __init__ def __init__(self, id, title):
self.id = id
self.title = title
similar to constructor
def updateId(self, newId):
● self-parameter self.id = newId
Passes reference to class LibraryBook(LibraryEntry):
def __init__(self, id, title, author):
current instance LibraryEntry.__init__(self, id, title)
self.author = author
Not needed for static
or class methods def updateAuthor(self, newAuthor):
self.author = newAuthor
Python wants to be libBook = LibraryBook(1, "PyS60", "Andreas Jakl")
explicitly clear libBook.updateId(2)
libBook.updateAuthor("Nokia")
46 Andreas Jakl, 2009
Classes – Attributes
● Instance attributes are set “on-the-fly” by using them
Constructor is the first place to set instance attributes
Use default arguments for default instance setup
● Class variables / static data have to be defined
class Letter(object): class C(object):
def __init__(self, text, author="Andreas Jakl", category=“love"): foo = 100 # Static data
self.text = text
self.author = author print C.foo # 100
self.category = category
C.foo = C.foo + 1
def printLetter(self): print C.foo # 101
print self.text, self.author, self.category
['__class__', '__delattr__', '__dict__', '__doc__',
loveLetter = Letter("I love you") '__getattribute__', '__hash__', '__init__',
print dir(loveLetter) # Print all methods & attributes of this class '__module__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__',
47 Andreas Jakl, 2009 '__str__', '__weakref__', 'author', 'category',
'printLetter', 'text']
How to organize your application
PyS60 – Application Structure
48 Andreas Jakl, 2009
Application Structure
Title appuifw.app.title
Navigation pane appuifw.app.set_tabs()
Body appuifw.app.body
Dialog appuifw.
- appuifw.query()
- appuifw.note()
- ...
Menu Exit appuifw.app.
appuifw.app.menu exit_key_handler
49 Andreas Jakl, 2009
UI App – Example
import appuifw, e32
def quit():
print "Exit key pressed"
app_lock.signal()
appuifw.app.exit_key_handler = quit
appuifw.app.title = u"UI App"
print "App is now running"
app_lock = e32.Ao_lock()
app_lock.wait()
print "Application exits"
50 Andreas Jakl, 2009
Callback Function
● No difference to normal functions
● Associating function with event: binding
Use function name without () to get the function object
Compare to function pointers in C
def quit():
pass # function is empty (instead of {} in C++ / Java)
appuifw.app.exit_key_handler = quit
51 Andreas Jakl, 2009
Wait for the User
● Previously: app. exited after executing all lines
● Event based UI-app: wait for user input
...
app_lock = e32.Ao_lock() # Create an instance of an Ao_lock object
app_lock.wait()
Refer to the Symbian OS
course for more
information about
Waiting for Active Objects
quit() call-back handler
events
app_lock.signal()
52 Andreas Jakl, 2009
Application Body
appuifw.app.screen = “normal" appuifw.app.screen = “large" appuifw.app.screen = "full"
53 Andreas Jakl, 2009
Application Body
● You can assign several objects to the body
Canvas: provides drawable screen area + support for
handling raw key events
Form: complex forms with various input fields
Listbox: shows a list of items (single- or double-line-item)
Text: free-form text input
54 Andreas Jakl, 2009
Application Menu
● Defined using tuples: import appuifw, e32
def play():
Text print "Play file"
def volume_up():
Call-back function print "Volume up"
def volume_down():
– Specify another print "Volume down"
tuple instead to def quit():
print "Exit key pressed"
define a submenu app_lock.signal()
appuifw.app.exit_key_handler = quit
appuifw.app.title = u"mp3 Player"
appuifw.app.menu = [(u"Play", play),
(u"Volume", ( (u"Up", volume_up), (u"Down", volume_down) ) )]
submenu
print "App is now running"
app_lock = e32.Ao_lock()
app_lock.wait()
Example based on [1]
55 Andreas Jakl, 2009
String Manipulation
txt = "I like Python"
url = " http://www.mopius.com "
print txt[2:6] url = url.strip()
print txt.find("like") if url.startswith("http://"):
if txt.find("love") == -1: print url, "is a valid URL"
print "What's wrong with you?"
txt.replace("like", "love") webServiceInput = " 1, 2, 3, 4"
print webServiceInput.replace(" ", "")
print txt.upper()
print "Length", len(txt) txt = "one;two;three"
print txt.split(";")
txt2 = "" http://www.mopius.com is a valid URL
if txt2: 1,2,3,4
print "txt2 contains characters" ['one', 'two', 'three']
else:
print "txt2 doesn't contain characters"
like
2
What's wrong with you?
I LIKE PYTHON
Length 13
txt2 doesn't contain characters
56 Andreas Jakl, 2009
String Formatting
● String slicing like for lists: [start:end]
● Assemble string based on other variables:
print "Host: %s\tPort: %d" % ("Earth", 80)
print "DD.MM.YYYY = %02d.%02d.%d" % (12, 3, 82)
list = [3, 2, 1, "go"] # A list has to be converted to a tuple first
print "Counting: %d, %d, %d, %s" % tuple(list)
Symbol Conversion Host: EarthPort: 80
%s String conversion via str() prior DD.MM.YYYY = 12.03.82
to formatting Counting: 3, 2, 1, go
%d Signed decimal integer
%f Floating point real number
... ...
57 Andreas Jakl, 2009
Example – Inbox Search
import inbox, appuifw
# Create an instance of the Inbox object
box = inbox.Inbox()
# Query search phrase
query = appuifw.query(u"Search for:", "text").lower()
hits = []
ids = []
# sms_messages() returns message IDs for all messages in the SMS inbox
for sms_id in box.sms_messages():
# Retrieve the full message text and convert it to lowercase
msg_text = box.content(sms_id).lower()
if msg_text.find(query) != -1:
# If the text was found, store a preview
hits.append(msg_text[:25])
ids.append(sms_id)
# Display all results in a list
index = appuifw.selection_list(hits, 1)
if index >= 0:
# Show the full text of the selected message
appuifw.note(box.content(ids[index]))
58 Andreas Jakl, 2009
Event Loop
● e32.Ao_lock waits for events, but stops execution
● Game:
App. has to be active all the time
But still needs respond to events (keys, ...)
Initialize event call-backs Sleep (+ execute waiting active objects):
while : e32.ao_sleep(interval)
Update game state Yield (just execute ready active objects with
Redraw screen higher priority)
Pause / yield e32.ao_yield()
59 Andreas Jakl, 2009
The Python way of
Exception Handling
60 Andreas Jakl, 2009
Exceptions
● Example:
Exception “NameError” raised by the interpreter:
>>> print foo
Traceback (most recent call last):
File “", line 1, in
print foo
NameError: name 'foo' is not defined
61 Andreas Jakl, 2009
Exceptions
● try:
try_suite # watch for exceptions here
except Exception[, reason]:
except_suite # exception-handling code
● Different objects derived from Exception
● Exception arguments / reasons:
May be passed along
Not just a string, but contains more information
62 Andreas Jakl, 2009
Exceptions – Information
try:
f = file(u"c:\\python\\test.txt", "w+")
print >> f, "Welcome to Python"
f.seek(0)
print "File contents:", f.read()
f.close()
except IOError, reason: [Errno 2] No such file or
print reason directory: u'c:\\python\\test.txt'
print reason.filename c:\python\test.txt
print reason.errno 2
print reason.strerror No such file or directory
63 Andreas Jakl, 2009
Multiple Exceptions
● Catching multiple exceptions:
Multiple except-statements
Multiple exceptions in one except statement
Catch the base class Exception
(no good coding style – you might be silently dropping
errors)
64 Andreas Jakl, 2009
Code Examples
● Code snippets for:
Camera
Text to Speech
Sound recording / playing
Bluetooth
Networking http://www.mobilenin.com/pys60/menu.htm
Graphics, UI Additional modules:
3D (Open GL ES) http://cyke64.googlepages.com/
Camera
Sensor
...
65 Andreas Jakl, 2009
Bonus – Acceleration Sensor (3rd Ed (FP1))
import appuifw,e32,sensor
def get_sensor_data(status):
"Callback function for regular accelerometer status"
print "x: %d, y: %d, z: %d" % (status['data_1'], status['data_2'], status['data_3'])
def exit_key_handler():
# Disconnect from the sensor and exit
acc_sensor.disconnect()
app_lock.signal()
appuifw.app.exit_key_handler = exit_key_handler
# Retrieve the acceleration sensor
sensor_type = sensor.sensors()['AccSensor']
# Create an acceleration sensor object
acc_sensor = sensor.Sensor(sensor_type['id'],sensor_type['category'])
# Connect to the sensor
acc_sensor.connect(get_sensor_data)
# Wait for sensor data and the exit event
app_lock = e32.Ao_lock()
app_lock.wait()
66 Andreas Jakl, 2009
Bonus – Acceleration Sensor (3rd Ed FP2+)
from sensor import *
import e32, time, appuifw
class DemoApp():
def __init__(self):
self.accelerometer = AccelerometerXYZAxisData(data_filter=LowPassFilter())
self.accelerometer.set_callback(data_callback=self.my_callback)
self.counter = 0
def my_callback(self):
# For stream sensor data the callback is hit 35 times per sec (On 5800).
# The device cannot handle resource hungry operations like print in the callback function
# for such high frequencies. A workaround is to sample the data as demonstrated below.
if self.counter % 5 == 0:
print "X:%s, Y:%s, Z:%s" % (self.accelerometer.x,
self.accelerometer.y, self.accelerometer.z)
self.counter = self.counter + 1
def run(self):
self.accelerometer.start_listening()
def exit_key_handler():
# Disconnect from the sensor and exit
global d
d.accelerometer.stop_listening()
print "Exiting Accelorometer"
app_lock.signal()
if __name__ == '__main__':
appuifw.app.exit_key_handler = exit_key_handler
d = DemoApp()
d.run()
app_lock = e32.Ao_lock()
67 Andreas Jakl, 2009
app_lock.wait()
Literature – Recommended
Mobile Python
Jürgen Scheible, Ville Tuulos
Complete overview of Python development for PyS60, many
small code samples.
Status: Symbian OS 9, PyS60 1.4, 2007
Free code samples:
http://www.mobilenin.com/pys60/menu.htm
Core Python Programming (Second Edition)
Wesley J. Chun
Python for developers who already know other languages.
Comprehensive short overview, in later chapters a detailed
overview of the individual components.
Status: 2007
68 Andreas Jakl, 2009
That’s it!
Thanks for your attention
69 Andreas Jakl, 2009