Laboratory‎ > ‎

### Python

CS 495-20 Script languages taken in Spring 2006 at Northwestern University. Inclusive scripts mostly involves Python. Source codes can be also downloaded from the links at the bottom of the page.

## Statistics sampling

This python code(netdisease.py) requires matplotlib 0.98, and numpy(svn co http://svn.scipy.org/svn/numpy/trunk numpy)

```#!/usr/bin/env python
"""
Simulating Spread of Disease in Networks

"""
__author__ = """Seunghoon Kim (ski819)"""
__date__ = "\$Date: 2006-04-10 (Mon, 10 Apr 2006) \$"
__revision__ = "Homework 1"
#    Copyright (C) 2006 by
#    Seunghoon Kim <seunghoon@northwestern.edu>
#
#	 Note: Higher numbered nodes are more likely to die after their first cycle as infected,
#			while more likely to recover from infected state.

from networkx import *
import random

def netdisease(n,k,s,p,i):

Infected=[]
G=Graph()
d=0.2			# sustain rate for infected
r=0.05			# recovery rate for infected, the remainder survives without recovery
for m in range(n):
if ((m%100) == 0):
Infected.append(int(m))
for l in range(k):
t=m+int(l*n*s/k)				# rewire proability calculated
if t>n:
t = t-n
for j in range(i):
for c in range(len(Infected)):
if c < r*len(Infected):
Infected.pop()
for c in range(len(Infected)):
Infected.pop()
for a in range(n):
if a in Dead:
B=G.degree(a)
for b in range(B):
newinfect = G[a][b]
if b < p*B:
if newinfect not in Infected:
if newinfect not in Dead:
Infected.append(int(newinfect))
for c in range(len(Dead)):
if c > d*len(Dead):				# clear dead list according to the death rate

S= G.number_of_nodes() * 100 / n
print '--------------------------------------------------'
print 'Disease spread Simulation by Seunghoon Kim(ski819)'
print 'Percentage of Survivors = ', S,'%'
print 'Recovery and sustain rate can be configured by'
print 'manually changing the value in netdisease.py'
print '--------------------------------------------------'

return G.number_of_nodes()```

## Image processing

This python code(montager.pycreates mosaic of input images as part of montage process. (Requires ImageMagick)
```#!/usr/bin/env python
"""
Processing Images

"""
__author__ = """Seunghoon Kim (ski819)"""
__date__ = "\$Date: 2006-04-17 (Mon, 17 Apr 2006) \$"
__revision__ = "Homework 2"
#    Copyright (C) 2006 by
#    Seunghoon Kim <seunghoon@northwestern.edu>
#
#	 Usage: ./montage.py (dirname) (number of pictures to montage)
#

import os, sys, re, string

if __name__ == '__main__':
dirname, numpics = sys.argv, int(sys.argv)
lspath = ["ls -R"] + [dirname] + ["> list"]
os.system(string.join(lspath))
list = open("list", 'r')
fnames = ls.split()
#	print fnames

print dirname
#	os.chdir(dirname)
#	print os.system("pwd")

montageset = []

picsatt = 0
picindex = 0
while picsatt < numpics:
completepath = [fnames[picindex]]
completepath = addpath + completepath
temppath = string.join(completepath,'')
completepath = ["identify"] + [temppath] + ["> id"]
#completepath = string.join(addpath, fnames[i])
#print completepath
ident = 1									# for testing purpose
ident = os.system(string.join(completepath))  # returns jpeg,png,gif
#print "ident returns", ident
iden = open("id", 'r')
id = ide.split()
if len(id):
#print id
if id in ['JPEG','PNG','GIF']:
montageset.append(temppath)
picsatt += 1
print "Collecting picture #", picsatt, "out of", numpics
picindex += 1

montageadd = ["montage"] + montageset + ["montage.png"]
#print montageset
print "creating montage.png.......please wait"
os.system(montagecmd)
print "Done!!!"```

## Regular expression

Regular expressions are a powerful and standardized way of searching, replacing, and parsing text with complex patterns of characters.
• dupwords.py - finds duplicate words in the input string
```#!/usr/bin/env python
"""
Regular Expression I

"""
__author__ = """Seunghoon Kim (ski819)"""
__date__ = "\$Date: 2006-04-17 (Mon, 17 Apr 2006) \$"
__revision__ = "Homework 2"
#    Copyright (C) 2006 by
#    Seunghoon Kim <seunghoon@northwestern.edu>
#

import sys
import re
import glob

for pat in sys.argv[1:]:
for file in glob.glob(pat):
for para in open(file).read().split('\n\n'):
dups = re.findall(r'(?m)(^.*(\b\w+\b)\s*\b\2\b.*\$)', para)
if dups:
for dup in dups:
print 'Duplicate word "%s" found in sequence: ' % dup, dup

```
• urlizer.py - finds URL format in the string, and inserts HTML codes in the respective places
```#!/usr/bin/env python
"""
Regular Expression II

"""
__author__ = """Seunghoon Kim (ski819)"""
__date__ = "\$Date: 2006-04-17 (Mon, 17 Apr 2006) \$"
__revision__ = "Homework 2"
#    Copyright (C) 2006 by
#    Seunghoon Kim <seunghoon@northwestern.edu>
#

import re, fileinput

pattern = re.compile(r'''(?x)( # verbose identify URLs within text
(http|ftp|gopher|mailto|telnet|file|wais) # make sure we find a resource type
:* # ...needs to be followed by colon-slash-slash
[^ \n\r]+ # some stuff then space, newline, tab is URL
(\w+\.?){2,} # at least two domain groups, e.g. (gnosis.)(cx)
(?=[\s\.,]) # assert: followed by whitespace/period/comma
) # end of match group
''')

#for line in fileinput.input():
if __name__ == '__main__':
for line in fileinput.input():
print re.compile(pattern, re.M).sub("<a href=\"\g<0>\">\g<0></a>", line.rstrip())```

## Extending Python

makefile
```#
#  Simple Makefile
#  For compiling C extension modules for
#  python.
#

###################################################
#
# Basic Swig Procedure :~)
#
# // First make the wrapper from the interface file
# swig -python utility.i
# // Then compile both the utility_wrap.c and the utility.c code.
# gcc -c utility.c utility_wrap.c -I/usr/include/python2.2
# // Then link :~)
# ld -shared utility.o utility_wrap.o -o _utility.so
#
##################################################

includes = -I/usr/include/python2.4 -I/usr/lib/python2.4
interface = *.i
source = *.c
objects = *.o
library = _example.so
junk = *.so *.o *_wrap.c *_wrap.doc
linkopts = -shared -o
ccopts = -c

\${library} : \${objects} #pointer
ld \${linkopts} \${library} \${objects}

\${objects} : interface \${source}
gcc \${ccopts} \${source} \${includes}

interface : \${interface}
swig -python \${interface}

clean :
-rm \${junk}

```
setup.py
```#!/usr/bin/env python
"""
Extension Setup File

"""
__author__ = """Seunghoon Kim (ski819)"""
__date__ = "\$Date: 2006-04-17 (Mon, 17 Apr 2006) \$"
__revision__ = "Homework 3"
#    A Script written by
#    Seunghoon Kim <seunghoon@northwestern.edu>
#

from distutils.core import setup, Extension

module = Extension('rankorder', sources = ['rankorder.c'])

setup (name = 'rank_order',
version = '1.0',
description = 'CS495-20 MP3',
ext_modules = [module])```
rankbag.py
```#	Return a dictionary where
#	key = rank, ranked by number of occurrences
#	val = number of numbers at that rank
#	There may be more elegant ways to do this but
#	this is the most straightforward I could come up with.

import types

class RankBag(list):
def __init__(self, list):
self = list
print self

def rank(self):
# Calculate the number of occurrences of a given number
occurrences = {}
for i in range(len(self)):
occurrences[(self[i])] = occurrences.setdefault((self[i]), 0 ) + 1
# Construct a decreasingly sorted sequence of
# cnt, num pairs, first pair has rank 1
self = [(cnt, num) for num, cnt in occurrences.items()]
print self
self.sort()
print self
self.reverse()
print self
return self

#	rank_counts = {}
#	current_rank = 1
#	current_cnt = pairs
#	print current_cnt

# Build the final dictionary, looking for transitions in
# the counts for a number
#	for cnt, num in pairs:
#		print cnt, current_cnt
#		if cnt <> current_cnt:
#			current_rank = current_rank + 1
#			current_cnt = cnt
#		rank_counts[current_rank] = rank_counts.setdefault(current_rank, 0) + 1

#	print rank_counts
#	return rank_counts```
rankorder.c
```// CS495-20 Homework 3
# include <stdio.h>
# include <stdlib.h>
# include <string.h>

//static PyObject* rank_order(PyObject *self, PyObject *args)
int rank_order(int argc, char **argv)
{

char* nums = argv;
int occurrences;
int i, j, num;
for (i=0; i<10; i++)
occurrences[i] = 0;
for (num=0; num<10; num++)
{
for (i=0; i<strlen(nums); i++)
{
if (nums[i] == num)
occurrences[num]++;
}
}

int pairs;
int tempswap;
for (i=0; i<10; i++)
{
for(j=i; j<10; j++)
{
if (pairs[i] < pairs[j])
{
tempswap = pairs[j];
pairs[j] = pairs[i];
pairs[i] = tempswap;
}
}
}

int currcnt = 0;
int countvalue = pairs;
for(i=0; i<10; i++)
{
if (countvalue != pairs[i])
{
currcnt++;
countvalue = pairs[i];
}
}
int rank_counts[currcnt];

countvalue = pairs;
for(i=0; i<currcnt; i++)
rank_counts[i] = 0;
currcnt = 0;
for(i=0; i<10; i++)
{
if (countvalue != pairs[i])
{
rank_counts[currcnt]++;
currcnt++;
countvalue = pairs[i];
}
}

printf("{");
for(i=0; i<currcnt; i++)
printf("%d: %d,", i, rank_counts);
printf("}");
return 1;
}
```
rankorder.lua (LUA version)
```function rank_order(nums)

--	Return a dictionary where
--	key = rank, ranked by number of occurrences
--	val = number of numbers at that rank
--	There may be more elegant ways to do this but
--	this is the most straightforward I could come up with.

--	Calculate the number of occurrences of a given number
occurrences = {}
for num,nums do
occurrences[num] = occurrences.setdefault(num, 0) + 1
end

--	Construct a decreasingly sorted sequence of
--	cnt, num pairs, first pair has rank 1
pairs = [(cnt, num) for num, cnt in occurrences,items()]
pairs.sort()
pairs.reverse()

rank_counts = {}
current_rank = 1
current_cnt = pairs

--	Build the final dictionary, looking for transitions in
--	the counts for a number
for cnt, num in pairs:
if cnt ~= currenct_cnt:
current_cnt = current_rank + 1
current_cnt = cnt
rank_counts[current_rank] = rank_counts.setdefault(current_rank, 0 ) + 1

return rank_counts
end```

## Application Controller

This lesson is for Python scripts' use in controlling other applications using simple commands. Purpose of this lesson is to show how to pass in commands to control iTunes, and add in additional functionalities such as calculating average track length and a needle-drop which plays each track for few seconds. Appscript is a high-level, user-friendly Apple event bridge that allows you to control scriptable Mac OS X applications from Python, Ruby and Objective-C. Appscript makes these languages serious alternatives to Apple's own AppleScript language for automating your Mac. In order to operate the following python script, appscript needs to be installed (command: python setup.py build, python setup.py install)

nettunes.py
```#!/usr/bin/env python
"""
Building a Remote iTunes Service

"""
__author__ = """Seunghoon Kim (ski819)"""
__date__ = "\$Date: 2006-05-17 (Wed, 18 May 2006) \$"
__revision__ = "Homework 4"
#    Copyright (C) 2006 by
#    Seunghoon Kim <seunghoon@northwestern.edu>
#
#	 Executing python nettunes.py will trigger both functions.
#	 In order to modify arguments for the two functions, modify the last 3 lines of this code.
#	 Default values are host="wolverine", port=8080, seconds=20

import mytunes
import time

def average_track_length(remote_host, port):
itunes = mytunes.MyTunes()
itunes.start()
try:
tracks = itunes.track_length()
count = len(tracks)
total = sum(tracks)
result = total/count
return result
except:
print "Error retrieving tracks"

def needle_drop(remote_host, port, seconds):
itunes = mytunes.MyTunes()
try:
tracks = itunes.track_length()
count = len(tracks)
itunes.play_track(0)
for i in range(count):
time.sleep(seconds)
itunes.next_track()
print "Playing next track"
except:
print "Error executing needle_drop"

print "Average track length:", average_track_length("wolverine", 8080)
print "Executing needle drop, will sample for 20 seconds"
needle_drop("wolverine", 8080, 20)```

mytunes.py this script calls reference to the following, in which iTunes functionalities are defined and ready for use
```from appscript import *
import __builtin__

class MyTunes:
def __init__(self):
""" no arguments -> MyTunes handle
creates a new MyTunes bridge object
Save this value in a variable for future use, e.g.
itunes = mytunes.MyTunes()
"""
self.__app = app('iTunes')

def start(self):
""" no arguments -> None
starts iTunes playing"""
try:
self.__app.play()
except:
pass

def pause(self):
"""no arguments -> None
pauses the currently  playing track
"""
try:
self.__app.pause()
except:
pass

def stop(self):
"""no arguments -> None
stops the currently playing track
"""
try:
self.__app.stop()
except:
pass

def next_track(self):
""" no arguments -> None,
moves to the next track in the current playlist """
try:
self.__app.next_track()
except:
pass

def previous_track(self):
""" no arguments -> None
moves to the previous track in the current playlist """
try:
self.__app.previous_track()
except:
pass

def set_volume(self, value):
"""integer between 0 and 100 -> None
Sets the volume
"""
try:
self.__app.sound_volume.set(value)
except:
print "Error setting volume. Skipping"
pass

def get_volume(self):
"""no arguments -> integer
Returns the current value of the volume setting
"""
try:
return self.__app.sound_volume.get()
except:
return -1

def play_playlist(self, pl_name):
"""playlist_name -> None
Starts playing the named playlist """
try:
pl = self.__app.playlists[pl_name]
self.__app.play(pl)
except:
print "No such playlist %s" % pl_name

def play_track(self, track_idx):
"""track_name or number -> None
Starts playing the indicated track, within the current playlist.
"""
try:
tracks = self.__app.current_playlist.tracks.get()
if track_idx >= len(tracks):
print "Index out of bounds [0:%s)" % len(tracks)
return
track = tracks[track_idx]
self.__app.play(track)
except:
print "No such track %s" % track_name

def track_length(self):
"""no arguments -> list of track_names,
Returns a list of strings for the currently playing playlist.
"""
try:
tracks = self.__app.current_playlist.tracks.duration.get()
return tracks
except:
print "Error retrieving tracks"

def current_tracks(self):
"""no arguments -> list of track_names,
Returns a list of strings for the currently playing playlist.
"""
try:
tracks = self.__app.current_playlist.tracks.name.get()
return tracks
except:
print "Error retrieving tracks"

def current_track(self):
"""no arguments -> dictionary
Returns a dictionary of information
regarding the current track
"""

track_fields = ['album', 'artist', 'bit_rate', 'bpm', 'comment',
'compilation', 'composer', 'database_ID',
'duration', 'enabled', 'EQ', 'finish', 'genre',
'grouping', 'kind', 'modification_date',
'played_count', 'played_date',
'rating', 'sample_rate', 'size', 'start',
'time', 'track_count', 'track_number'
'name', 'location', 'container']

try:
result = {}
track = self.__app.current_track.get()
for field_name in track_fields:
try:
if hasattr(track, field_name):
result[field_name] = getattr(track, field_name).get()
except:
pass
return result
except:
print "Error getting track info."
return result

def track_info(self, track_name):
"""track_name -> dictionary
Returns dictionary of information regarding
the named track if it exists, otherwise an empty dictionary
"""

try:
track = self.__app.library_playlists.get().tracks[track_name].get()
track_fields = ['album', 'artist', 'bit_rate', 'bpm', 'comment',
'compilation', 'composer', 'database_ID',
'duration', 'enabled', 'EQ', 'finish', 'genre',
'grouping', 'kind', 'modification_date',
'played_count', 'played_date',
'rating', 'sample_rate', 'size', 'start',
'time', 'track_count', 'track_number'
'name', 'location', 'container']

result = {}
for field_name in track_fields:
try:
if hasattr(track, field_name):
result[field_name] = getattr(track, field_name).get()
except:
pass
return result
except Exception, e:
print "Error getting track info"
return {}

def all_playlist_names(self):
"""No arguments -> list of strings
Returns a list of the names of all of the playlist
names in the iTunes database."""

try:
return self.__app.sources['Library'].user_playlists.name.get()
except:
return []

def all_track_names(self):
"""No arguments -> list of strings,
Returns a list of the names of all of the track
names in the iTunes database."""

try:
names = []
for pl_name in self.all_playlist_names():
tracks = self.__app.playlists[pl_name].tracks.get()
if not tracks: continue
names.extend(self.__app.playlists[pl_name].tracks.name.get())
return names
except Exception, e:
print "Error", e
return []

def get_playlist(self, idx):
"""playlist_name or playlist_number -> list of strings
Returns a list of all the names in the named playlist, if the playlist exists.
"""

try:
pl = self.__app.user_playlists[idx].get()
results = []
for track in pl.tracks.get():
results.append(track.name.get())
return results
except:
return []

def __playlist_object(self, idx):
try:
playlists = self.__app.user_playlists.get()
pl = None
if isinstance(idx, str):
pl = self.app.user_playlists[idx]
elif isinstance(idx, int):
if ((0 <= idx) and (idx < len(playlists))):
pl = playlists[idx]
return pl
except:
return

def help():
for attr_name in dir(MyTunes):
if attr_name != "_":
__builtin__.help(getattr(MyTunes, attr_name))
```

## Embedding Python

This code implements a simple turtle graphics style engine that’s used to render the result of Lindenmayer systems(L-system), a transformation process on strings.

Lsystem.cpp
```#include "lsystem.h"
#include <Python.h>

LSystem::LSystem(const string& start_string)
: start(start_string), cur_string(start_string)
{
}

void LSystem::reset() {
cur_string = start;
}

string LSystem::iterate(int iterations) {
string next_string;

PyObject *pModule, *pFunc, *pValue;							// python extension parts
Py_Initialize();
pModule = PyImport_ImportModule("LSYSTEM_FILE");
pFunc = PyObject_GetAttrString(pModule, "generate");
pValue = PyObject_CallObject(pFunc, NULL);
cur_string = PyString_AsString(pValue);
return cur_string;
Py_Finalize();

}```

lsystem_file.py
```#!/usr/bin/env python
"""
L-systems file for RGS

"""
__author__ = """Seunghoon Kim (ski819)"""
__date__ = "\$Date: 2006-06-11 (Sun, 11 Jun 2006) \$"
__revision__ = "Homework 5"
#    A Script written by
#    Seunghoon Kim <seunghoon@northwestern.edu>
#

import sys,re

start = "F"
iterations = 3
rules = {"F": "F+F--F+F"}

def generate():
pattern = start
for i in range(iterations):
pattern = re.sub(start, rules[start], pattern)
#		print pattern
return pattern	```

## Batterylife Simulation

Part of CS495-20 Python programming project, as well as a battery life simulator used for my Power Deregulation paper. The following set of code was used to calculate how long a particular type of battery would last under various processor setups tested. The input data, power dissipation metrics (static/dynamic) were taken from M5 processor simulation results, while various battery-related literature provided battery capacity and dissipation trends for different types of batteries. Project Proposalare also available.

bl-compute.py Battery life cycle simulation for embedded systems
```#!/usr/bin/env python
"""
Battery Life Simulation for each benchmarks
for use in Power Deregulation research
"""
__author__ = """Seunghoon Kim (ski819)"""
__date__ = "\$Date: 2006-06-09 (Fri, 8 Jun 2006) \$"
__revision__ = "Rev.2 Part of CS495-20 Project"
#    Written by
#    Seunghoon Kim <seunghoon@northwestern.edu>
#	 Northwestern University
#
#	 Usage: ./bl-compute.py
#

import powvolt
import battery

print "-------------------Battery Simulation--------------------\n"
benchmark = ['MPGdec', 'MPGenc', 'SpeechRec', 'ADPCMdec', 'ADPCMenc', 'epic', 'unepic', 'g721dec', 'g721enc']

for i in range(9):
time_step = 1.0
time = 0.0
bat = battery.Li_MnO2_Battery()

while bat.cap > 0.0:
time += time_step
power = powvolt.power_voltage(benchmark[i], bat.voltage())
bat.deplete_capacity(power * time_step)
print "Estimated battery lifetime for", benchmark[i], ":", time, "seconds"
print "\n---------------------------------------------------------"```
battery.py Battery capacity information and discharging behaviour
```default_capacity = 600.0 * 1E-3 * 60.0 * 60.0 * 4 # Ws

class Battery(object):
def __init__(self, capacity_Ws = default_capacity):
self.cap_init = capacity_Ws
self.cap = self.cap_init

def deplete_capacity(self, drain_Ws):
self.cap = max(self.cap - drain_Ws, 0.0)

def voltage(self):
val = self.cap / self.cap_init
if val <= 0:
return 0.0
else:
for i in range(len(self.table)):
if val <= self.table[i] and val >= self.table[i+1]:
alpha = (val - self.table[i+1]) / (self.table[i] - self.table[i+1])
return self.table[i] * alpha + self.table[i+1] * (1.0 - alpha)

class Li_MnO2_Battery(Battery):
name = 'Li/MnO_2'
table = [
(1.0, 3.25),
(0.95, 3.1),
(0.875, 3.0),
(0.84, 2.98),
(0.75, 2.95),
(0.50, 2.9),
(0.28, 2.9),
(0.25, 2.875),
(0.2, 2.8),
(0.0, 2.3)
]

class NiMH_Battery(Battery):
name = 'NiMH'
table = [
(1.0, 2 * 1.38),
(0.9, 2 * 1.31),
(0.8, 2 * 1.29),
(0.6, 2 * 1.28),
(0.4, 2 * 1.28),
(0.2, 2 * 1.26),
(0.1, 2 * 1.25),
(0.05, 2 * 1.16),
(0.0, 2 * 0.92)
]

types = [
Li_MnO2_Battery,
NiMH_Battery,
]

```

powvolt.py Power consumption for each application in relation to number of active processors
```#!/usr/bin/env python
"""
Battery Life Simulation for each benchmarks
for use in Power Deregulation research
"""
__author__ = """Seunghoon Kim (ski819)"""
__date__ = "\$Date: 2006-06-09 (Fri, 8 Jun 2006) \$"
__revision__ = "Rev.2 Part of CS495-20 Project"
#    Written by
#    Seunghoon Kim <seunghoon@northwestern.edu>
#	 Northwestern University
#
#	 To be used with bl-compute.py
#

_bench_proc = { \
'MPGdec': [(3.3, 1), (3.112, 2), (2.83, 3), (2.736, 4)], \
'MPGenc': [(3.3, 1), (3.112, 2), (2.736, 3)], \
'SpeechRec': [(3.3, 1), (3.112, 2), (2.736, 3)], \
'ADPCMdec': [(3.3, 1), (3.112, 2), (2.83, 3)], \
'ADPCMenc': [(3.3, 1), (3.112, 2), (2.736, 3)], \
'epic': [(3.3, 1), (3.112, 2), (2.924, 3)], \
'unepic': [(3.3, 1), (3.112, 2), (2.736, 3)], \
'g721dec': [(3.3, 1), (3.112, 2), (2.83, 3)], \
'g721enc': [(3.3, 1), (3.112, 2), (2.736, 3)] \
}

_power_cons = [(3.3, 3.3899), (3.206, 2.9031), (3.112, 2.4551), (3.018, 2.04677),
(2.924, 1.67705), (2.83, 1.3415), (2.736, 1.0408)]

def benchmark_proc(bench, voltage):
v_to_proc_cnt = _bench_proc[bench]
for v, numcpus in v_to_proc_cnt:
if v < voltage:
return numcpus
return 1

def single_proc_p(voltage):
v_to_power_cnt = _power_cons
for v, power in v_to_power_cnt:
if v > voltage:
return power

def power_voltage(bench, voltage):
numcpus = benchmark_proc(bench, voltage)		# Find out number of CPUs used at specific voltage level
#	single_proc_p(voltage)
return (float(numcpus) * single_proc_p(voltage))```

powercalc.py Initially used to calculate the total power consumption at particular processor setup and time period. Submitted as CS495-20 project, and later converged into bl-compute.py for specific use for publication
```#!/usr/bin/env python
"""
Power Data Extraction and Calculation Script for M5 Statistics

"""
__author__ = """Seunghoon Kim (ski819)"""
__date__ = "\$Date: 2006-06-08 (Thurs, 8 Jun 2006) \$"
__revision__ = "Rev.2 Part of CS495-20 Project"
#    Copyright (C) 2006 by
#    Seunghoon Kim <seunghoon@northwestern.edu>
#
#	 Usage: ./powercalc.py (filename) (# of processors[max:4]) (Vdd[in V])
#

import re, sys, math

#for line in fileinput.input():
if __name__ == '__main__':
fname, numcpus, voltage = sys.argv, int(sys.argv), float(sys.argv)
frequency = (300 * (voltage-2.736) / 0.564) + 200
print frequency
if numcpus > 4:
numcpus = 4
test = open(fname, 'r')
str = string.split()
#print numcpus
#print str

dynparamstart = ["system.cpu0.POWER.DYNAMIC:bpred_block_average",
"system.cpu1.POWER.DYNAMIC:bpred_block_average",
"system.cpu2.POWER.DYNAMIC:bpred_block_average",
"system.cpu3.POWER.DYNAMIC:bpred_block_average"]
dynparamend = ["system.cpu0.POWER.DYNAMIC:lsq_block_average",
"system.cpu1.POWER.DYNAMIC:lsq_block_average",
"system.cpu2.POWER.DYNAMIC:lsq_block_average",
"system.cpu3.POWER.DYNAMIC:lsq_block_average"]
staparamstart = ["system.cpu0.POWER.STATIC:bpred_block_average",
"system.cpu1.POWER.STATIC:bpred_block_average",
"system.cpu2.POWER.STATIC:bpred_block_average",
"system.cpu3.POWER.STATIC:bpred_block_average"]
staparamend = ["system.cpu0.POWER.STATIC:lsq_block_average",
"system.cpu1.POWER.STATIC:lsq_block_average",
"system.cpu2.POWER.STATIC:lsq_block_average",
"system.cpu3.POWER.STATIC:lsq_block_average"]
dynpower = [0.0,0.0,0.0,0.0]
stapower = [0.0,0.0,0.0,0.0]		# Initialize an array in length of 4
dyntotal = 0.0
statotal = 0.0

for i in range(numcpus):
# first value to fetch is the one that comes after this pattern
dynindex = str.index(dynparamstart[i]) + 1
dynend = str.index(dynparamend[i]) + 1
while dynindex < dynend:
dynpower[i] += float(str[dynindex])
dynindex =  dynindex + 4
print "Dynamic Power for Processor", i, " sums upto: ", dynpower[i]
dyntotal += dynpower[i]

# Similarly for static power
staindex = str.index(staparamstart[i]) + 1
staend = str.index(staparamend[i]) + 1
while staindex < staend:
stapower[i] += float(str[staindex])
staindex += 4
print "Static Power for Processor", i, " sums upto: ", stapower[i]
statotal += stapower[i]

print "Total Dynamic Power: ", dyntotal
print "Scaled according to", voltage, "V and", frequency, "MHz:", (dyntotal*voltage*voltage*frequency/3.3/3.3/500)
print "Total Static Power: ", statotal
print "Scaled according to", voltage, "V:", (statotal*math.exp(3.3-voltage))
totalpower = (dyntotal*voltage*voltage*frequency/3.3/3.3/500) + (statotal*math.exp(3.3-voltage))
print "Overall Power Dissipation for", numcpus, "processors running at", voltage, "volts and", \
frequency, "MHz:", totalpower, "W"```

Reference: Dive into Python; A good walkthrough guidelines; used as primary reference source for academic purposes

## wxPython

for GUI programming using python; a blending of the wxWidgets C++ class library with the Python programming language

## Language Comparison: to C++

The main advantage for using scripting languages that were experienced while completing this programming assignment was Python’s ﬂexibility. For implementing this type of module, Python was a better choice for being able to fully integrate outside modules, not deﬁned data types, and simpler debugging process.

First, importing outside sources can be done with one line of command, whereas in C++, more restricted class and data type rules apply when outside header ﬁles are used. When using python, importing simply just involves ﬁguring out what kinds of additional commands should be used; however, C++, in turn for being able to have more ﬂexible types of operations, requires careful observation of source code sighted. That leads to another advantage for python, having non-deﬁned data types. For C++ to have custom data types, it involves complex tree or multiple layer styled data structure that inhibits quick programming. In python, there is no need to deﬁne variables in advance, so even when mistakes are made, it can be quickly ﬁxed. The favorite part about programming for this class is that being able to debug as I write the program. Being able to test each line of code as I plan out what to do or use puts me in so much calm state. C++ programming process is usually repetition of write a long lines of codes, test and ﬁx the errors as I go, but for this assignment, whatever I type on .py ﬁle, I could test and check whether the expression is valid, which resulted more stable programming task and efﬁcient time spending. As this was yet the ﬁrst step for actually implementing a module using Python, I expect that the upcoming programming assignments will look more straight forward.

## Language Comparison: to Lua

### Basic Language Features

The primary purpose of Lua was for its usage in extension; therefore, it was made compact to fit on many different host platforms. Lua contains a single native data structure that maps out typical data structures including arrays, sets, lists and hash tables. All of these features are pretty much contained in Python. Its typical syntax can be briefly explained by the code below:

```io.write("F ")
for c=c0,c0+10-1 do
f=(9/5)*c+32
io.write(string.format("%3.0f ",f))
end
io.write("\n\n")```

Unlike Python, Lua only supports dynamic typing . The language itself is simple, so that variables do not possess any other definition besides the value they hold. Lua treats functions as first class variables, explained by the example below:

```local oldprint = print		-- store current print function as old print
print = function(s)		-- redefine print function
if s == "foo" then
oldprint("bar")
else
oldprint(s)
end
end```

### Scripting

In terms of text processing capabilities, Lua has string manipulation library that is similar to Python’s regular expression library, though its character pattern class does not seem as comprehensive as Python’s. Command invocation and file system manipulation are very similar to Python, their io, file, os, debug facilites .

```local A
while 1 do
if l==nil then break end
local _,_,a,b=string.find(l,'"?([_%w]+)"?%s*(.*)\$')
if a~=A then A=a io.write("\n",a,":") end
io.write(" ",b)
end```

### Gluing

Some of the namespaces and objects can be created using Lua’s native data structure; however, Lua lacks one of the essential gluing capability introspection. IPC mechanisms and Coroutine support were added since version 4.1. Network support can be added on by installing a C extension.

### Extending

Extensible semantics is a key feature of Lua; therefore, its extensibility is boundless with variety of foreign function codes. Its semantics can also be extended by using built-in functions in metatables, enabling its capability to compose an object-oriented program.

### Bibliography

ċ
Hoonio,
Feb 24, 2013, 4:30 PM
ċ
Makefile
(1k)
Hoonio,
Feb 24, 2013, 4:30 PM
ċ
Hoonio,
Feb 24, 2013, 4:30 PM
ċ
Hoonio,
Feb 24, 2013, 4:30 PM
ċ
Hoonio,
Feb 24, 2013, 4:30 PM
ċ
Hoonio,
Feb 24, 2013, 4:30 PM
ċ
Hoonio,
Feb 24, 2013, 4:30 PM
ċ
Hoonio,
Feb 24, 2013, 4:30 PM
ċ
Hoonio,
Feb 24, 2013, 4:31 PM
ċ
Hoonio,
Feb 24, 2013, 4:31 PM
ċ
Hoonio,
Feb 24, 2013, 4:31 PM
ċ
Hoonio,
Feb 24, 2013, 4:31 PM
ċ
Hoonio,
Feb 24, 2013, 4:31 PM
ċ
Hoonio,
Feb 24, 2013, 4:31 PM
ċ
rankorder.lua
(1k)
Hoonio,
Feb 24, 2013, 4:31 PM
ċ
Hoonio,
Feb 24, 2013, 4:31 PM
ċ
Hoonio,
Feb 24, 2013, 4:31 PM
ċ
Hoonio,
Feb 24, 2013, 4:31 PM