Related Documentation:
Python is a dynamic programming language that started from conception in the 80’s. It boasts a clean readable syntax, support for several programming paradigms, high level of extensibility, and a huge standard library. The high extensibility of the language has allowed Python to spread into several areas of computing such as web development, scientific computing, and enterprise application development. Thanks to its readability, Python is an excellent language for beginning programmers, but it’s still powerful enough for just about any task. Thanks to the small learning curve, Python has gained a large community of developers. The Python community is different from other communities in that they see ”right” and ”wrong” ways to code solutions to certain problems, and how certain features are to be used.
One of the main motivations behind creating a scripting language layer for a software library, is to take advantage of all of the resources of that scripting language. Python boasts arguably the largest and most diverse collection of modules of any scripting language. Python is able to interface with many languages such as C, C++, and Java; thus it can provide a scripting layer to any software libraries written in a compatible language. The core of the major components for GENESIS3: the model container, heccer, chemesis 3, and experiment protocols, are written in C. An abstraction layer encapsulates the functional aspects of the C code, which makes the Python representation take advantage of an object oriented approach. Available python packages for G3 are:
Many other software tools have Python modules that allow you to interface with them via their API such as the aforementioned wxPython (based on wxWidgets written in C++), PyQT (based on Qt written in C++), PyYaml, SciPy, NumPy, and Matplotlib. Thanks to G3 having a presence in this scripting format, it’s possible to interface with any python module available.
Python and it’s modules are extremely portable. A Python interpreter can be embedded into other programs and has given interpretive capabilities to large software packages such as Blender, GIMP, and Abaqus. Library modules can also be distributed as Python ’eggs’, which are zipped library files that can be placed in the Python executables library paths; allowing you to import them and use them in your own scripts. An egg built for Python 2.6 can be imported and run on any matching version for the same operating system.
An online repository of Python eggs known as PyPi, the Python Package Index, allows users to create modules and upload them for others to download and install with a single command.
Unlike most languages Python does not use brackets or any sort of paired delimiter to indicate the start and end of a block of code. Python uses indentation, otherwise known as the ”off-side rule.” A definition such as a function declaration defines it’s scope as everything that is indented once following it and scope ends when it encounters a line that is at the same indentation level as the definition.
The following is a function simple definition:
def my_function(i): print "The number I have is %i" % i print "Hello!" |
The line of code that prints ”Hello!” is not part of the function definition since it is now out of scope.
Here is an example of a loop:
for i in range(0,100): print "%i" % i print "Done!" |
Again,the first print statement will print every value between 0 and 100, but the final line that prints out ”Done!” will not print since it is out of scope of the loop.
Functions, as shown before can be declared with the ’def’ declaration, a parameter list, and everything indented in its scope. Here’s an example:
def max(value1, value2): if value1 == value2: return "they’re equal" elif value1 > value2: return value1 elif value2 > value1: return value2 print "Max between 4 and 4 is ’%s’" % max(4, 4) print "Max between 10 and 2 is ’%s’" % max(10, 2) print "Max between 60 and 3000 is ’%s’" % max(60, 3000) |
The output of the script is:
Max between 4 and 4 is ’they’re equal’
Max between 10 and 2 is ’10’ Max between 60 and 3000 is ’3000’ |
Classes in python allow you to create objects that encapsule complex operations. To create a class it’s very simple:
class MyObject: # my constructor def __init__(self, value): self.my_value = value def get_value(self): return self.my_value my_obj = MyObject(100) print "The value of my object is %s" % my_obj.get_value() |
The output of the program is: ”The value of my object is 100”
Like most object oriented languages, Python allows you to inherit a class. Inheriting is very simple, taking the simple object from the previous example:
class MyObject: # constructor def __init__(self, value): self.my_value = value def get_value(self): return self.my_value class MyChildObject(MyObject): # constructor def __init__(self, value, value2): MyObject.__init__(self, value) self.value2 = value2 def get_value_2(self): return self.value2 my_obj = MyChildObject(20, 50) print "Value 1 is %s" % my_obj.get_value() print "Value 2 is %s" % my_obj.get_value_2() |
The output of the program is:
Value 1 is 20
Value 2 is 50 |
Strings in Python are objects, and have accompanying methods like the previous objects shown do.
Here’s some examples of string manipulation:
my_string = " This is my string! " print "The string is ’%s’" % my_string.rstrip() print "The string is ’%s’" % my_string.lstrip() print "The string is ’%s’" % my_string.replace(’my’, ’the’) string_parts = my_string.split() print "String parts are: ’%s’" % ’, ’.join(string_parts) |
The output from this script is:
The string is ’ This is my string!’
The string is ’This is my string! ’ The string is ’ This is the string! ’ String parts are: ’This, is, my, string!’ |
Strings can also be concatenated via the ’+’ operator or using a join like the previous example:
string1 = "This is "
string2 = "my string" string3 = string1 + string2 print string3 print ’’.join([string1, string2]) |
The output from this script is:
This is my string
This is my string |
Lists are arrays of objects, they are used to store consecutive sequences of data. GENESIS3, and many other pieces of scientific computing software output data lists for analysis in the form of a python list.
my_list = ["one", "two", "three"] print "There are %s items in this list" % len(my_list) for l in my_list: print "%s" % l my_list.append("four") print "\nThere are now %s items in this list" % len(my_list) for l in my_list: print "%s" % l print "\nThe third element is %s\n" % my_list[2] print "The elements and their indexes are" for i, l in enumerate(my_list): print "’%s’ is at position ’%i’" % (l,i) |
The output for the script is:
There are 3 items in this list
one two three There are now 4 items in this list one two three four The third element is three The elements and their indexes are ’one’ is at position ’0’ ’two’ is at position ’1’ ’three’ is at position ’2’ ’four’ is at position ’3’ |
A dictionary is a relational data structure that allows you to use keywords to hash to values. GENESIS3 uses some dict structures for input formats.
my_dict = { ’key1’ : 100, ’key2’ : 500, ’key3’ : 10} print "The keys are: " for k in my_dict.keys(): print "key ’%s’ holds value ’%s’" % (k, my_dict[k]) print "\n" my_dict[’key4’] = 600 for k in my_dict.keys(): print "key ’%s’ holds value ’%s’" % (k, my_dict[k]) print "\n" print "Removing the entry at ’key2’\n" my_dict.pop(’key2’) for k in my_dict.keys(): print "key ’%s’ holds value ’%s’" % (k, my_dict[k]) print "\n" if my_dict.has_key(’key3’): print "An entry with ’key3’ is present" |
GENESIS3 has a scheduler in Python called SSPy (simple scheduler in python), that is used to drive simulations and allow the user to interface with Python. Below is an example
from sspy import SSPy
scheduler = SSPy(verbose=True) my_model_container = None # # Create a model container service and load an ndf file # my_model_container = scheduler.CreateService(name="My Model Container", type="model_container", verbose=True) my_model_container.Load(’tests/cells/purk_test.ndf’) my_model_container.SetParameter(’/purk_test/segments/soma’, ’INJECT’, 2e-09) # # Must create solver. # my_heccer = scheduler.CreateSolver(’My solver’, ’heccer’, verbose=True) # Sets the segment of the model to run from my_heccer.SetModelName(’/purk_test’) # set the timestep for the entire scheduler (solvers, inputs and outputs) my_heccer.SetTimeStep(2e-05) # # Create Outputs # my_output = scheduler.CreateOutput(’My output object’, ’live_output’) my_output.AddOutput(’/purk_test/segments/soma’, ’Vm’) my_output.AddOutput(’/purk_test/segments/soma/ca_pool’, ’Ca’) scheduler.Run(steps=2500, finish=True) output_data = my_output.GetData() # you can put some sort of data manipulation here for the output_data print "Data at step 1, time ’%f’ is %s" % (output_data[1][0], ’,’.join(map(str, output_data[1][1:]))) print "Done!" |
At the end of this simulation, the ’my_output’ object holds a python list with all of the data from the simulation that can be obtained via its GetData() method and can be used to feed data into plotters, spreadsheets, and other analysis tools.