Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

About this user

Korakot Chaovavanich http://korakot.stumbleupon.com

« Newer Snippets
Older Snippets »
Showing 11-20 of 96 total

Preview available fonts

>>> from appuifw import *
>>> fonts = available_fonts()
>>> fonts.sort()
>>> t = Text()
>>> for f in fonts:
...   t.font = f
...   t.add(f + ' ')
...
>>> app.body = t

See screenshot.

Formatting time

>>> from e32db import format_time
>>> from time import *
>>> t = time()
>>>
>>> format_time(t)   # for Symbian SQL
u'06/03/2006 23:26:35'
>>> strftime('%d/%m/%Y %H:%M:%S')  # like above
'06/03/2006 23:26:39'
>>> ctime()
'Mon Mar 06 23:26:49 2006'
>>> strftime("%a, %d %b %Y %H:%M:%S +0000")  # email RFC
'Mon, 06 Mar 2006 23:26:59 +0000'

Here's the (shortened) table for strftime.
%a  weekday name.  
%A  weekday name (full).  
%b  month name.  
%B  month name (full).  
%c  date and time (locale)
%d  day of month [01,31].  
%H  hour [00,23].  
%I  hour [01,12].  
%j  day of year [001,366].  
%m  month [01,12].  
%M  minute [00,59].  
%p  AM or PM
%S  Second [00,61]
%U  week of year (Sunday)[00,53].
 w  weekday [0(Sunday),6].
 W  week of year (Monday)[00,53].
 x  date (locale).
%X  time (locale).
%y  year [00,99].
%Y  year [2000].
%Z  timezone name.  

Showing message on status bar

There's an empty space below app.title that we can
use as a status bar. So, I modify this recipe and
make it into a module. (need fgimage.pyd from here)
# status.py
from graphics import *
import fgimage
__all__ = ["status_on", "status_off"]

bar = Image.new((119,13))
bgcolor = screenshot().getpixel((0,0))[0]
fg = fgimage.FGImage()

def status_on(message=None):
    if message is not None:
        bar.clear(bgcolor)
        bar.text((0,11), unicode(message), 0xffffff)
    fg.set(57,30, bar._bitmapapi())

def status_off():
    fg.unset()

You can use it easily this way
>>> from status import *
>>> status_on('Hello world')  # show it
>>> status_off()              # hide it
>>>

See a screenshot.

Looking up phone model using firmware code

You can lookup the firmware code by
dial *#0000#

For pys60 you can use
>>> import sysinfo
>>> sysinfo.sw_version()
u'V 3.42.1 16-10-03 NHL-10 (c) NMP'
>>> firmware = _.split(' ')[3]
>>> firmware
u'NHL-10'
>>>

Looking at the table here, a mapping can be made.
>>> mapping = {
  'RM-51': '3230',
  'RM-38': '3250',
  'NHM-10': '3600',
  'NHM-10X': '3620',
  'NHL-8': '3650',
  'NHL-8X': '3660',
  'RM-25': '6260',
  'RM-29': '6260b',
  'NHL-10': '6600',
  'NHL-12': '6620',
  'NHL-12X': '6620',
  'RM-1': '6630',
  'RH-67': '6670',
  'RH-68': '6670b',
  'RM-36': '6680',
  'RM-57': '6681',
  'RM-58': '6682',
  'RH-51': '7610',
  'RH-52': '7610b',
  'NHL-2NA': '7650',
  'RM-49': 'E60-1',
  'RM-89': 'E61-1',
  'RM-10': 'E70-1',
  'RM-24': 'E70-?',
  'NEM-4': 'N-Gage',
  'RH-29': 'N-Gage QD (asia/europe)',
  'RH-47': 'N-Gage QD (americas)',
  'RM-84': 'N70-1',
  'RM-99': 'N70-5',
  'RM-67': 'N71-1',
  'RM-112': 'N71-5',
  'RM-91': 'N80-3',
  'RM-92': 'N80-1',
  'RM-42': 'N90-1',
  'RM-43': 'N91-1',
  'RM-158': 'N91-5' }
>>> mapping[firmware]
'6600'
>>>

Random rectangle demo

A good short demo for pys60.
# random rectangle
# modify from http://mtg.lcc.gatech.edu/class/rectangles.py

from appuifw import *
import e32
from random import randrange

running = 1
def quit():
	global running
	running = 0
app.exit_key_handler = quit

app.screen = 'large'
app.body = canvas = Canvas()
res_x, res_y = canvas.size

while running:
	x1 = randrange(res_x)
	x2 = randrange(x1, res_x)
	y1 = randrange(res_y)
	y2 = randrange(y1, res_y)
	color = randrange(0xffffff)
	canvas.rectangle((x1, y1, x2, y2), fill=color)
	e32.ao_yield()

Symbian phone list

# S60 3rd Edition (Symbian OS v9.1)
Nokia E60, E61, E70
Nokia 3250
Nokia N71, N80, N91, N92

# S60 2nd Edition FP3 (Symbian OS v8.1)
Nokia N70, N90

# S60 2nd Edition FP2 (Symbian OS v8.0a)
Nokia 6630, 6680, 6681, 6682
Lenovo P930

# S60 2nd Edition FP1 (Symbian OS v7.0s enhanced)
Nokia 3230, 6260, 6620, 6670, 7610
Panasonic X700, X800
Samsung SDH-D720

# S60 2nd Edition (Symbian OS v7.0s)
Nokia 6600

# S60 1st Edition (Symbian OS v6.1)
Nokia 3600, 3620, 3650, 3660, 7650
Nokia N-Gage, N-Gage QD
Sendo X
Siemens SX1

See official list.

SQL quotation for Symbian DBMS

import e32db, time

timestamp = time.time()
distance = 10.5
comment = "I'm fine, thanks!"

# for date/time, int/float, and string respectively

sql = "INSERT INTO events VALUES (#%s#, %d, '%s')" %\
  (e32db.format_time(timestamp),
   distance,
   comment.replace("'", "''") )

- date/time need to be quoted with # and formatted with e32db.format_time
- int/float need no quotation
- string need to be quoted with single quote and repeat the quote if it happen to be inside.
- binary can't be used. You may need to encode it (eg. base64)

One day, I wish to see an easy-to-use SQL abstraction layer for pys60.
An ORM(SQLObject or SQLAlchemy) is even better.

Using datetime in python 2.2 (e.g. pys60)

Python 2.2 doesn't have a decend date/time class.
There's a small compatible library from the Python Web Project.

I download the source and extract the datetime.py then
send it to my phone as a pys60 library.
Here's a simple test that works well.
(Taken from Effbot)
>>> import datetime
>>> now = datetime.datetime(2003, 8, 4, 12, 30, 45)
>>> print now
2003-08-04 12:30:45
>>> print repr(now)
datetime.datetime(2003,8,4,12,30,45)
>>> print type(now)
<type 'instance'>
>>> print now.year, now.month, now.day
2003 8 4
>>> print now.hour, now.minute, now.second
12 30 45

See its documentation here.
One limitation as a library is that you need to use
datetime.datetime(2004,1,1).now() # work for any version

instead of just
datetime.datetime.now() # python 2.3+


update
======
I add 'staticmethod' expression. Now it works fine.
    def now(self=None):
        "Return the current date and time as a datetime."
        now = t.localtime()
        return datetime(now[0],now[1],now[2],now[3],now[4],now[5])
    now = staticmethod(now)

Using &lt;font> (font tag) within pys60 Text widget

The Text widget allow rich text. However, it's quite
difficult to use. You need to set each attribute
(font, style, highlight, color) of the widget
before adding more text with differert style.

So, I make a function that make it a bit easier.
The font tag (<font></font>) is used (borrowed from HTML).
Attributes allowed are
- color ( #RRGGBB or 0xRRGGBB or color name)
- face ( both font and size eg. albi17b )
- style ( bold, italic, underline or strikethrough )
(styles can be combined using comma)
- highlight ( standard, rounded, shadow)
- hcolor ( highlight color )
from appuifw import *

def process_color(color):
    color_name = {
        'red': 0xff0000, 'green': 0x008000, 'blue':0x0000ff,       
        'black': 0,      'white':0xffffff,      'yellow': 0xffff00
        }
    if color.startswith('#'):   # HTML format #000000
        return int(color[1:], 16)
    if color.startswith('0x'):  # pys60 format 0x000000
        return int(color, 16)
    return color_name[color]

def set_ml(t, s):
    stack = []
    t.clear()
    t.font = 'normal'
    i = 0
    while i < len(s):
        if s.startswith('<', i):  # tag end or tag begin
            j = s.find('>', i) + 1
            if s[i:i+7] == '</font>' or s[i:i+3] == '</>':
                t.color, t.font, t.style, t.highlight_color = stack.pop()
            else:
                stack.append([t.color, t.font, t.style, t.highlight_color])
                to_style = 0
                for attr_val in s[i:j-1].split(' '):
                    if '=' in attr_val:
                        attr, val = attr_val.split('=')
                        if attr == 'color':
                            t.color = process_color(val)
                        elif attr == 'face':
                            t.font = unicode(val)
                        elif attr == 'hcolor':
                            t.highlight_color = process_color(val)
                        elif attr == 'style':   # style and highlight go together
                            to_style |= eval('|'.join(['STYLE_' + st.upper() for st in val.split(',')]))
                        elif attr == 'highlight':
                            to_style |= eval("HIGHLIGHT_" + val.upper())
                if to_style:
                    t.style = to_style
        else:    # normal text
            j = s.find('<', i)
            if j == -1: j = len(s)
            text = u'' + s[i:j].replace('&lt;', '<')
            t.add(text)
        i = j      # go next chunk


Now you can use it easily
>>> t = app.body   # use the default Text widget that start pys60
>>> set_ml(t, '<font color=red>Hello</font> <font style=bold>World</font>.')
>>>  # a stylish 'Hello World' is displayed

Notice:
- Quotation marks are not used to specify attribute values.
- A </> shorthand can be used for </font>
- <font> can be nested.

Plotting graph on pys60

Here's the first step towards porting matplotlib to pys60.
I try to replicate some easy examples in
matplotlib tutorial.

First, we need a float range function.
from __future__ import generators

def arange(start, stop=None, step=None):
    if stop is None:
        stop = float(start)
        start = 0.0
    if step is None:
        step = 1.0
    cur = float(start)
    while cur < stop:
        yield cur
        cur += step

Then, a function to draw the axes and ticks.
In the future, this should be called automatically from plot().
from appuifw import *
app.body = canvas = Canvas()
width, height = canvas.size

def axes(xyrange, position=[18, height-11, width-10, 10], formatter=lambda x:x):
    global left, bottom, right, top, min_x, min_y, scale_x, scale_y
    left, bottom, right, top = position
    min_x, max_x, step_x, min_y, max_y, step_y = xyrange
    scale_x = float(right-left)/(max_x-min_x)
    scale_y = float(bottom-top)/(max_y-min_y)
    canvas.clear()
    canvas.rectangle([(left,top), (right+1, bottom+1)], 0)
    for x in arange(min_x, max_x, step_x):
        canvas.text((14+scale_x*(x-min_x), height-1), unicode(formatter(x)))
        canvas.point((left+scale_x*(x-min_x), bottom-1), 0)
        canvas.point((left+scale_x*(x-min_x), top+1), 0)
    for y in arange(min_y, max_y, step_y):
        canvas.text((2, bottom+2-scale_y*(y-min_y)), unicode(formatter(y)))
        canvas.point((left+1, bottom-scale_y*(y-min_y)), 0)
        canvas.point((right-1, bottom-scale_y*(y-min_y)), 0)

And lastly, the plot function. Now it has only a few features.
More will be added depending on what is needed.
def plot(xs, ys=None):
    if ys==None:
        ys = xs
        xs = range(len(ys))
    last = left+(xs[0]-min_x)*scale_x, bottom-(ys[0]-min_y)*scale_y
    for i in range(1, len(ys)):
        p = left+(xs[i]-min_x)*scale_x, bottom-(ys[i]-min_y)*scale_y
        canvas.line([last, p], 0x00000ff)
        last = p
    canvas.point(last, 0x0000ff)

When we want to plot a graph, we called both axes() and plot()
# a straight line
>>> axes([0,3.1,.5, 1,4.1,.5])
>>> plot([1,2,3,4])

# a parabola y = x^2
>>> axes([1,4.1,1, 0,16.1,2], formatter=int)
>>> plot([1,2,3,4], [1,4,9,16])

See the sreenshot of the first.

« Newer Snippets
Older Snippets »
Showing 11-20 of 96 total