Programming for young learners with Python

Python is a free open source programming language. At an advanced level, it’s a powerful and flexible language, but it’s clear and straight forward syntax, and it’s forgiving nature, make it a great way to introduce people to programming
and computer science.

Younger learners can start by writing programs to draw shapes and
patterns in the PythonTurtle learning environment. They can also learn to write simplified functions to help Guido Van Robot to explore his abstract world. Both these programs provide learners with an interactive environment to learn basic concepts like sequencing, conditional branching, looping and procedural abstraction through problem solving with instant visual feedback.

PythonTurtle

PythonTurtle

When learners are ready, they can use the Python programming language to explore a free online course book like How to Think Like a Computer Scientist. Advanced learners can graduate to graphics and game programming with a free online course like Invent Your Own Computer Games with Python.

Python is such a flexible language that learners have the opportunity
to exlore procedural, functional and object oriented styles of programming that they can use later if go on to study languages like
C, C++, Java, and Haskell.

Posted in Uncategorized | Tagged , , | Leave a comment

The Edubuntu Live CD

Edubuntu

The Edubuntu live CD is suite of free and open source education and general software that you can run from the CD without having to install anything. It’s based on Ubuntu Linux. It gives you a great range of software to play with for learners of all ages.

If you like some of the stuff on the CD, these days most open source software has Windows or MacOS versions available from the project website for you to download and install. Or if you really dig it, and you’re adventurous, you can install the whole lot to your hard drive and run Linux as an alternative operating system.

Follow the links to find out more about Linux, more about open source software, a place in Australia to buy Linux live CDs in case you don’t feel like downloading and burning your own, other education focused live CDs.

Posted in Linux, open source software | Tagged , , , | Leave a comment

Simple system monitor powered by Python and Pygame

Simple system monitor powered by Python and Pygame

I’ve continued working on a simple system monitor application for the Ben Nanonote in Python and Pygame by rewriting the code in a more object-oriented style and adding a CPU and Memory monitor. Eventually I’d like to add disk space monitors, and to write a simple application launcher.

#!/usr/bin/python</code>

<code># A simple battery monitor application powered
# Python and Pygame.

#########################################################
# Press CONTROL-q to exit

from pygame import *
from copy import deepcopy
# initialize
init()

########################################################
# colours
white = 255,255,255
black = 0,0,0
red = 255,0,0
green = 0,255,0
yellow = 255,255,0
backcolour = black
solid = 0

########################################################
# background screen
def backgroundScreen(colour):
'''Setup background screen
In: colourTUPLE.
Return: screenOBJ'''
screen = display.set_mode((320,240))
backgrnd = colour
screen.fill(backgrnd)
display.flip()
return screen

# Warning colour
def getWarningColour(powerPercent):
'''Set a colour for the power block and percent text'''
if powerPercent >= 50:
warningColour = green
elif powerPercent >= 25:
warningColour = yellow
else:
warningColour = red
return warningColour

# get file
def getFile(path):
'''Returns a string'''
targetFile = open(path)
contents = targetFile.read()
targetFile.close()
return contents

# Check for keypress
# Exit on control-q
def exitKey():
for e in event.get():
if e.type == KEYDOWN \
and e.key == K_q \
and key.get_mods() & KMOD_CTRL:
return True

######################################################
class Point(object):
'''Point object'''

def __init__(self, x, y=0):
'''Create a point from x,y or (x,y). '''
if type(x) is tuple and y == 0:
self.x = x[0]
self.y = x[1]
elif type(x) is int and type(y) is int:
self.x = x
self.y = y
else:
message = "Point type error: %s, %s" % (x, y)
raise RuntimeError(message)

def __str__(self):
return "(%s, %s)" % (self.x, self.y)

def __add__(self, term):
'''Term can be a Point or a tuple.
Returns a Point.'''
result = Point(0, 0)
if type(term) is tuple and len(term) == 2:
result.x = self.x + term[0]
result.y = self.y + term[1]
return result
elif isinstance(term, Point):
result.x = self.x + term.x
result.y = self.y + term.y
return result
else:
message = "Point type error: %s" % (term)
raise RuntimeError(message)
def tuple(self):
return (self.x, self.y)

######################################
class Txt(object):

def __init__(self, message,
size = 16, fontName = None):

# self.message is used by Txt.write()
self.message = message
# font object
self.fontObj = font.Font(fontName, size)

def write(self, position, forecolour = white):
'''Render font object'''
if isinstance(position, Point):
position = position.tuple()
antialias = True
self.textObj = self.fontObj.render(self.message,
antialias,
forecolour,
backcolour)
# Create a rectangle
self.textRect = self.textObj.get_rect()
self.textRect.topleft = position
draw.rect(screen, backcolour, self.textRect, solid)
# Blit the text
screen.blit(self.textObj, self.textRect)
display.update(self.textRect)

#######################################################
class Header(object):

def __init__(self, text, origin):
self.text=Txt(text, 16)
self.origin = origin

def write(self):
self.text.write(self.origin)
#######################################################
class Monitor(object):

def __init__(self, name, origin):
self.origin = origin
# header text
self.header = Header(name, (origin + (0, 5)))

def draw(self):
self.header.write()

#######################################################
class batteryMonitor(object):
'''Header text, terminal, body'''
def __init__(self, origin):
'''origin is Point object '''

self.origin = origin
# header text
self.header = Header("Battery", (origin + (0, 5)))

# percent text
self.percentOrigin = self.origin + (55, 5)

# battery: body + terminal
batteryOrigin = self.origin + (100, 0)
batteryH = 22
batteryW = 12
self.lineWidth = 1

# battery terminal
terminalOrigin = batteryOrigin + (batteryW/4, 0)
terminalW = batteryW / 2
terminalH = int(round(batteryH * .1))
self.terminal = Rect(terminalOrigin.x,
terminalOrigin.y,
terminalW,
terminalH)

# battery body
bodyOrigin = batteryOrigin + (0, terminalH)
bodyW = batteryW
bodyH = batteryH - terminalH
self.body = Rect(bodyOrigin.x, bodyOrigin.y, bodyW, bodyH)

# list of power readings to average
self.powerReadings = []

def draw(self):
'''header, terminal, body'''

self.header.write()

# terminal
draw.rect(screen,
white,
self.terminal,
solid)

# body
draw.rect(screen,
white,
self.body,
self.lineWidth)

# update screen
display.flip()

def getPower(self):
'''Check powerlevel and return average of last 5 readings
reading is a percentage'''

# Check the battery power level
path = "/sys/class/power_supply/battery/capacity"
powerPercent = int(getFile(path))
# powerPercent = 75
# add to list of past readings
self.powerReadings.append(powerPercent)
# limit the list to 3 readings by deleting first item
if len(self.powerReadings) > 3:
self.powerReadings = self.powerReadings[1:]
# average the list of readings
average = float(sum(self.powerReadings)) / len(self.powerReadings)
# round the average to the nearest 5
powerPercent = int(round(average *2, -1) /2)
return powerPercent

def updateBlock(self, powerPercent):
'''Build power block and display with percentage'''

# Set a colour for the power block and percent text
warningColour = getWarningColour(powerPercent)
# Make a block to represent the power level
# Copy from body Rect
self.power = deepcopy(self.body)
# adjust the height of the power block to reflect the power level
self.power.h = int(round(self.power.h * powerPercent / 100))
# move the power block to the bottom of the battery
self.power.bottom = self.body.bottom - self.lineWidth
# blank the body outline
draw.rect(screen, backcolour, self.body, solid)
# draw solid power block
draw.rect(screen, warningColour, self.power, solid)
# redraw the body outline over the power block
draw.rect(screen, white, self.body, self.lineWidth)
display.update([self.body, self.power])

# Print the power percent
label = "%2s %%" % (powerPercent)
percent = Txt(label, 22)
percent.write(
self.percentOrigin,
forecolour = warningColour)

###############################################################
class CPUMonitor(object):
'''Header text, body rectangle'''

def __init__(self, origin):
'''origin is Point object '''
self.origin = origin

# header text
self.header = Header("CPU", (self.origin + (0, 5)))

# percent text
self.percentOrigin = self.origin + (55, 5)
self.percentBlank = Rect(self.percentOrigin.x, self.percentOrigin.y, 40, 20)

# cpu monitor body rectangle
bodyOrigin = self.origin + (100, 0)
bodyH = 20
bodyW = 12
self.body = Rect(bodyOrigin.x, bodyOrigin.y, bodyW, bodyH)
self.lineWidth = 1

def draw(self):
'''header, body rectangle'''

# header
self.header.write()

# body
draw.rect(screen,
white,
self.body,
self.lineWidth)
# update screen
display.flip()

def getLevel(self):
'''Check cpu level.
reading is a percentage'''

cpuFile = getFile("/proc/loadavg")
# extract first item and convert to percentage
listFromFile = cpuFile.split()
cpuPercent = int(float(listFromFile[0]) * 100)
return cpuPercent

def updateBlock(self, cpuPercent):
'''Build cpu block and display with percentage'''

# Set a colour for the power block and percent text
warningColour = green
# Make a block to represent the cpu level
# Copy from body Rect
self.block = deepcopy(self.body)
# adjust the height of the cpu block to reflect the cpu percent
self.block.h = int(round(self.block.h * cpuPercent / 100))
# move the cpu block to the bottom of the body
self.block.bottom = self.body.bottom - self.lineWidth
# blank the body outline
draw.rect(screen, backcolour, self.body, solid)
# draw solid cpu block
draw.rect(screen, warningColour, self.block, solid)
# redraw the body outline over the cpu block
draw.rect(screen, white, self.body, self.lineWidth)
display.update([self.body, self.block, self.percentBlank])

# Print the cpu percent
label = "%2s %%" % (cpuPercent)
percent = Txt(label, 22)
# blank out the old percent text
draw.rect(screen, backcolour, self.percentBlank, solid)
# write percentage
percent.write(
self.percentOrigin,
forecolour = warningColour)

###############################################################
class MemMonitor(object):
'''Header text, body rectangle'''

def __init__(self, origin):
'''origin is Point object '''
self.origin = origin

# header text
self.header = Header("Mem", (self.origin + (0, 5)))

# percent text
self.percentOrigin = self.origin + (55, 5)
self.percentBlank = Rect(self.percentOrigin.x, self.percentOrigin.y, 40, 20)

# total and free text
self.freeOrigin = self.origin + (100, 20)
self.freeBlank = Rect(self.freeOrigin.x, self.freeOrigin.y, 100, 20)

# monitor body rectangle
bodyOrigin = self.origin + (100, 0)
bodyH = 10
bodyW = 100
self.body = Rect(bodyOrigin.x, bodyOrigin.y, bodyW, bodyH)
self.lineWidth = 1

def draw(self):
'''header, body rectangle'''

# header
self.header.write()

# body
draw.rect(screen,
white,
self.body,
self.lineWidth)
# update screen
display.flip()

def getLevel(self):
'''Check mem level.
reading is a percentage'''

memFile = getFile("/proc/meminfo")
# Convert to list and extract total and free
listFromFile = memFile.split()
memTotal = int(listFromFile[1])
memFree = int(listFromFile[4])
memPercent = int(float(memFree) / memTotal * 100)
return memPercent

def updateBlock(self, memPercent):
'''Build mem block and display with percentage'''

# Set a colour for the power block and percent text
warningColour = getWarningColour(memPercent)
# Make a block to represent the mem level
# Copy from body Rect
self.block = deepcopy(self.body)
# adjust the length of the cpu block to reflect the mem percent
self.block.w = int(round(self.block.w * memPercent / 100))
# blank the body outline
draw.rect(screen, backcolour, self.body, solid)
# draw solid mem block
draw.rect(screen, warningColour, self.block, solid)
# redraw the body outline over the mem block
draw.rect(screen, white, self.body, self.lineWidth)
display.update([self.body, self.block])

# Print the mem percent
label = "%2s %%" % (memPercent)
percent = Txt(label, 22)
# blank out the old percent text
draw.rect(screen, backcolour, self.percentBlank, solid)
# write percentage
percent.write(
self.percentOrigin,
forecolour = warningColour)

###############################################################

# Hide the mouse pointer
mouse.set_visible(0)

# setup screen
screen = backgroundScreen(backcolour)

###############################################################
class TestMonitor(Monitor):

def __init__(self, name, position):
Monitor.__init__(self,name, position)
###############################################################

t = TestMonitor("header", Point(10,200) )
# t.draw()
###############################################################

# header, terminal, battery body
batteryMonitorOrigin = Point(10, 10)
battery = batteryMonitor( batteryMonitorOrigin )
battery.draw()

# header, cpu monitor body
cpuMonitorOrigin = Point(10, 50)
cpu = CPUMonitor( cpuMonitorOrigin )
cpu.draw()

# mem monitor
memMonitorOrigin = Point(10,100)
mem = MemMonitor( memMonitorOrigin )
mem.draw()

# The main loop
oldLevel = 100
oldPower = 0
oldMem = 0
done = False
while not done:

cpuPercent = cpu.getLevel()

if cpuPercent != oldLevel:
cpu.updateBlock(cpuPercent)
oldLevel = cpuPercent

powerPercent = battery.getPower()

if powerPercent != oldPower:
battery.updateBlock(powerPercent)
oldPower = powerPercent

memPercent = mem.getLevel()

if memPercent != oldMem:
mem.updateBlock(memPercent)
oldPower = memPercent

done = exitKey()
time.wait(250)

Posted in Ben Nanonote Pocket Computer | Tagged | 2 Comments

Imgv – image viewer

Sydney transit map viewed with Imgv.

Posted in Ben Nanonote Pocket Computer | Tagged , , | 1 Comment