Python Logs
- 1 programming
- 1.1 debug in python
- 1.2 gtk/gnome
- 1.2.1 2008-01-14 gnome canvas documentation
- 1.2.2 2008-01-21 python-gtk/python-gnome documentation
- 1.2.3 2008-01-21 existing glade projects in gtk/gnome
- 1.2.4 2008-01-21 AppBar
- 1.2.5 2008-01-23 widget's properties and user custom data
- 1.2.6 2008-02-01 redirect the stdout/stderr output to a TextView widget
- 1.2.7 2008-11-07 type coercion in gtk.ListStore
- 1.3 2008-04-11 subprocess.Popen
- 1.4 2008-04-27 introspection
- 1.5 2008-04-28 useful small functions
- 1.6 2008-05-01 line separator difference between linux and windows/dos
- 1.7 2005-11-18 passing by reference
- 1.8 reload a module 2008-07-10
- 1.9 2009-10-3 numpy
- 1.10 2009-11-21 scipy
- 1.11 2009-2-17 glob: Unix/wildcards style pathname pattern expansion
- 1.12 2009-6-9 SystemError: Negative size passed to PyString_FromStringAndSize
- 1.13 2009-10-7 When do is vs == and is not vs != differ?
- 1.14 2009-10-10 _csv.Error: line contains NULL byte
- 2 package
- 2.1 2008-03-25 easy-install
- 2.2 2008-03-25 interesting cheese shop/pypi packages
- 2.3 2008-04-28 SQLAlchemy/elixir package
- 2.3.1 Documentation
- 2.3.2 example codes
- 2.3.3 208-05-23 access table field in sql.select()
- 2.3.4 2008-05-24 sqlalchemy's wrapper: collective.lead
- 2.3.5 2008-05-07 order_by
- 2.3.6 2008-05-30 memory management
- 2.3.7 2008-07-10 set table schema for postgres db
- 2.3.8 2008-07-10 relationship between tables
- 2.3.9 2008-07-17 how to autocommit in elixir 0.5
- 2.3.10 2008-08-07 how to do raw sql query in elixir
- 2.3.11 2008-08-12 how to access table name in elixir
- 2.3.12 2008-08-26 Working with Multiple Databases
- 2.3.13 2009-5-26 search by regular expression
- 2.4 2008-04-30 python web framework solutions
- 2.5 2008-05-12 machine learning python package
- 2.6 2008-08-13 enable autocommit in python mysql module
- 2.7 2008-12-31 pylons
- 2.7.1 2008-12-31 installation
- 2.7.2 2008-12-31 Minimal Steps to run a 0.9.6 project under 0.9.7
- 2.7.3 2009-1-30 install google-visualization-python
- 2.7.4 2009-4-1 plugins for firefox (debug purpose)
- 2.7.5 2009-3-4 quick paster commandlines
- 2.7.6 2009-1-29 set form default value
- 2.7.7 2009-4-3 jsonify encoding error
- 2.7.8 2009-5-27 unquote/decode URL
- 2.7.9 2009-7-22 route map
- 2.7.10 2009-6-23 character encoding in HTML
- 2.8 2009-3-31 pyjamas
- 2.9 2009-11-18 svm (interface to libsvm2)
1 programming
1.1 debug in python
1.1.1 2006-10-29 module pdb
- a quick tutorial: http://www.ferg.org/papers/debugging_in_python.html
- It's better to put the testing code in a file, rather than pasting it into the python console. Pasting disables the l(list) command. You'll have trouble to locate the line position of the codes.
- In order to skip big chunk of for-loop in a function, insert pdb.set_trace() right before what you want and in the python console, import the function and type pdb.run("function()"). After the pdb console shows up, type s to step into the function. The function will stop right before the trace.
1.1.2 2008-02-20 try except
sys.exc_info() returns a tuple of except type, except description and a traceback object.
import traceback
try:
print var
except:
sys.stderr.write('Except type: %s\n'%repr(sys.exc_info()[0]))
traceback.print_exc()
print sys.exc_info()
#raise sys.exc_info()[0]
sys.exit(2)
1.1.3 2008-02-28 garbage collection
To free up more memory, try following:
import gc gc.collect() #run a full collection gc.set_threshold(50,2,2) #Set the garbage collection thresholds (the collection frequency). Setting threshold0 to zero disables collection. del gc.garbage[:] #delete uncollectable objects
gc.set_threshold(50,2,2) incurs the danger of slowing down python due to frequent collection.
1.1.4 2008-03-31 useful functions in debug mode
locals() and globals() show the variables in the current environment.
1.2 gtk/gnome
programming using pygtk, gnome canvas, ...
1.2.1 2008-01-14 gnome canvas documentation
library reference manual It's for C language. But seems there's no documentation for python-gnomecanvas and the package is just a .so file.
- Book Chapters (outdated, but useful to understand the idea behind gnome canvas)
1.2.2 2008-01-21 python-gtk/python-gnome documentation
python-gtk(pygtk): the tutorial that comes with it. Its tutorial also appears on its website along with its reference.
python-gnome: http://library.gnome.org/devel/references. The C library references. It also includes references of other libraries related to Gnome. Can't find python-gnome's own documentation. It appears as .so/dynamic-libraries and comes with only examples.
1.2.3 2008-01-21 existing glade projects in gtk/gnome
- annot/bin/guianalyzer.glade
- annot/bin/graph/genepairgui.glade
- utility/grid_job_mgr/grid_job_mgr.glade
- variation/src/Genotyping/QCVisualizeII.glade
- variation/src/QCVisualize.py (not by glade, pygtk + matplotlib)
- proj200303/script/pygnome (not by glade, gtk/gnome ...)
1.2.4 2008-01-21 AppBar
- 3 choices:
gnome.ui.AppBar
the glade 'Gnome App Bar' widget
the AppBar embedded in the glade 'Gnome App' widget
Only the embedded AppBar works as the C library references show. gnome.ui.AppBar gives out GtkWarning: gtk_label_set_text: assertion 'GTK_IS_LABEL (label)' failed. The glade 'Gnome App Bar' widget doesn't have correct APIs.
2008-02-12. import gnome.ui has to be executed before using its push() method, self.app1_appbar1.push('Status Message.').
1.2.5 2008-01-23 widget's properties and user custom data
dir(widget.props) shows all properties' names. and widget.props.property_name gives out the value of that property.
widget.get_properties('property_name') or widget.get_property('property_name') is another way to get property value. The former gives a tuple (possible multiple property values for one property)
widget.set_properties('property_name', 'property_value') or widget.set_property('property_name', 'property_value') or widget.set(property_name='property_value') sets that property.
- user custom data
w.__dict__ is a dictionary to be used by user. w.__getattribute__('dict-key') fetches the value in that dictionary.
w.set_data(data_name, data_value) and w.get_data(data_name) is a another way.
1.2.6 2008-02-01 redirect the stdout/stderr output to a TextView widget
One way is to write a dummy file class which has all necessary APIs for it to be a file object but writes the output to a text buffer. source is http://www.daa.com.au/pipermail/pygtk/attachments/20031004/dbb34c38/Py_Shell.py. Implemented in pymodule.gnome
2nd way is to embed a terminal into your GUI. http://ubuntuforums.org/archive/index.php/t-366720.html. didn't implement this one.
1.2.6.1 2008-11-07 possibility of deadlocking the program
redirecting stdout/stderr to a textview widget sometimes deadlocks the whole program when a subprocess thread is putting lots of stuff into stdout/stderr.
1.2.7 2008-11-07 type coercion in gtk.ListStore
Upon initialization, types of all columns will be specified in gtk.ListStore. If a specific column's type is not str, feeding it with a None would raise an exception. Has to feed it with values of appropriate type. Like if it's int, feed it a 0.
Although it raises an exception, it can still handle the data inserted into the ListStore and display it. Just catch the exception to avoid program to break down.
1.3 2008-04-11 subprocess.Popen
It's supposed to replace all these:
os.system os.spawn* os.popen* popen2.* commands.*
An example:
cp_p = subprocess.Popen(['cp', array_filename, output_fname], stderr=subprocess.PIPE, stdout=subprocess.PIPE) cp_p_stdout_out = cp_p.stdout.read() cp_p_stderr_out = cp_p.stderr.read()
1.3.1 2008-11-07 avoid deadlock
- default for subprocess.Popen() is no_wait. If you intend to wait, as cp_p.wait(), it might deadlock the whole program.
- repetitive calling of subprocess.Popen() + cp_p.stderr.read() could deadlock the program easily, esp when stdout/stderr is redirected to a gtk TextView widget. For some mysterious reasons, cp_p.stderr.read() ahead of cp_p.stdout.read() increases the chance of deadlock. stdout_content, stderr_content = cp_p.communicate() is a much stable call than stderr.read() + stdout.read().
1.4 2008-04-27 introspection
Check what method/attribute a python object has:
import sqlalchemy dir(sqlalchemy) import inspect inspect.getmembers(sqlalchemy) #check whether sqlalchemy has attribute 'update' hasattr(sqlalchemy, 'update') #show all global variables globals() #show all local variables within current scope locals() #Without arguments, equivalent to locals(). With an argument, equivalent to object.__dict__. vars()
1.5 2008-04-28 useful small functions
1.5.1 @property
Put right above a function in a class. It declares this method to be accessed as an attribute.:
class a(object): @property def my_func_var(self): return 100 a_ins = a() print a_ins.my_func_var
2008-05-09 @property not available in python2.3. use my_func_var=property(my_func_var) to replace it.
1.6 2008-05-01 line separator difference between linux and windows/dos
A utility that converts MS-DOS text files to Unix text files, as the two systems have different ideas on what a line separator is.
1.6.1 a python script
If a python script is in dos format and you edit it in linux and add #!/usr/bin/python on the top to make it executable, when you run it directly, it'll report error : No such file or directory. Because it keeps the dos format although you modify it in linux. Run dos2unix solves it.
1.6.2 data file
If a data file is in dos format, python program will read the line separator as an extra character although it could recognize the end of line. Run dos2unix.
1.7 2005-11-18 passing by reference
Be careful with the list structure. They are merely numerous pointers which point to the same memory location.
Code snippet 1:
bucket_ls = [Set()]*no_of_buckets for i in range(total_no_of_cases): bucket_ls[i/bucket_size].add(case_indices[i]) #i/bucket_size
Code snippet 2:
bucket_ls = [] for i in range(no_of_buckets): #create empty sets bucket_ls.append(Set()) for i in range(total_no_of_cases): bucket_ls[i/bucket_size].add(case_indices[i]) #i/bucket_size return bucket_ls
Code snippet 1 will give you a list of buckets with same content as 'range(total_no_of_cases)'. Each time you add one item to one of the buckets, other buckets all get the same thing. Because they are merely numerous pointers which point to the same memory location.
Code snippet 2 is correct.
1.7.1 2008-05-29 python data structures that pass by reference
- list []
- dictionary {}
1.7.2 2008-05-29 class initialization for these data structures
Example 1:
>>> class a:
... my_ls = []
... def __init__(self, my_dict={}, my_other_dict=None):
... pass
...
>>> a_ins = a()
>>> b_ins = a()
>>> a_ins.my_ls.append('a')
>>> print b_ins.my_ls
['a']
Example 2:
>>> class a:
... my_ls = None
... def __init__(self, my_dict=None, my_other_dict=None):
... pass
...
>>> a_ins = a()
>>> b_ins = a()
>>> a_ins.my_ls = []
>>> a_ins.my_ls.append('a')
>>> print b_ins.my_ls
None
>>> a_ins.my_dict = {}
Basically initialization of those pass-by-reference data structure will cause different instances of the same class share the same data structure unless you re-evaluate the variable after instantiation.
1.8 reload a module 2008-07-10
After the source code of an already-imported module is changed, reimporting or delete+reimporting it won't update the code in the memory. But the reload(...), in which ... is module name, call tries loading from the current directory first, then from the rest of Python's path.
1.9 2009-10-3 numpy
1.9.1 2008-11-28 numpy.nan
WATCH: numpy.nan!=numpy.nan. Must use numpy.isnan() to judge whether a value is nan or not.
1.9.2 2009-10-3 upon conversion into numpy.array, empty list ([]) is casted into numpy.float64
clearly visible from:
>>> numpy.array([]) array([], dtype=float64)
It would spell trouble if you are trying to concatenate two lists together, one is empty and the other is integer list. It would cast the type of the combined array to float, which would cause trouble if it's used as an index list later on:
>>> numpy.hstack(([], [1,2,3])) array([ 1., 2., 3.])
1.10 2009-11-21 scipy
1.10.1 2009-11-21 percentile, quartile, median
get any percentile:
from scipy import stats minimum = numpy.min(intensity_ls) first_decile = stats.scoreatpercentile(intensity_ls, 10) lower_quartile = stats.scoreatpercentile(intensity_ls, 25) median = stats.scoreatpercentile(intensity_ls, 50) upper_quartile = stats.scoreatpercentile(intensity_ls, 75) last_decile = stats.scoreatpercentile(intensity_ls, 90)
1.11 2009-2-17 glob: Unix/wildcards style pathname pattern expansion
The glob module finds all the pathnames matching a specified pattern according to the rules used by the Unix shell. No tilde expansion is done, but * , ? , and character ranges expressed with [] will be correctly matched. http://docs.python.org/library/glob.html
import glob
for infile in glob.glob("[0-9]*.jpg"):
im = Image.open(infile)
1.12 2009-6-9 SystemError: Negative size passed to PyString_FromStringAndSize
happened once when i was doing cPickle.dumps(data, -1) in which data is a very large 2D numpy matrix. It used to be ok when data is a lot smaller.
The idea circulating on the web is the data size exceeded the largest integer possible on that machine (the largest 32 bit (signed) integer is 2 147 483 647), interpreted as a negative size by Python.
1.13 2009-10-7 When do is vs == and is not vs != differ?
Usually a is b and a==b are same. However, if a is of type numpy.array and the type of each element in a is of the same type as b (b is just one element), putting the latter (the equal sign) into if condition would run into trouble:
>>> a
array([[1, 2],
[3, 4]])
>>> a==0
array([[False, False],
[False, False]], dtype=bool)
>>> if a==0:
... print a
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> if a is 0:
... print a
...
>>>
1.14 2009-10-10 _csv.Error: line contains NULL byte
This means the file contains NULL byte, \0. The incident occurred when a python program was reading a csv file through the csv module and the file was disrupted mysteriously in a copy action (smaller than the original file and the original file doesn't have NULL byte).
In case some files contain NULL byte, link below offers a solution.
http://bytes.com/topic/python/answers/641517-_csv-error-string-nul-bytes
2 package
2.1 2008-03-25 easy-install
http://peak.telecommunity.com/DevCenter/FrontPage
easy-install is a new way to install python packages (a.k.a. eggs). it could read the package name/egg name, find it in current directory, or download it from cheese shop/pypi first.
Packages installed by easy-install seem to be unable to uninstall themselves automatically. Check the easy-install output log to see where the installed dir/files are, manually remove them and modify /usr/lib/python2.5/site-packages/easy-install.pth to delete removed package names.
ways to run:
easy_install SQLObject easy_install "SomePackage==2.0" easy_install "SomePackage>2.0" easy_install -f http://example.com/downloads ExamplePackage easy_install http://example.com/downloads/ExamplePackage-2.0-py2.4.egg easy_install my_downloads/ExamplePackage-2.0.tgz
2.2 2008-03-25 interesting cheese shop/pypi packages
workingenv.py http://pypi.python.org/pypi/workingenv.py/0.6.5
ZopeSkel provides a collection of skeletons for quickstarting Zope and Plone projects. http://pypi.python.org/pypi/ZopeSkel
zc.buildout http://pypi.python.org/pypi/zc.buildout System for managing development buildouts
collective.lead http://pypi.python.org/pypi/collective.lead SQLAlchemy/Zope2 transaction integration
2.3 2008-04-28 SQLAlchemy/elixir package
SQLAlchemy is the Python SQL toolkit and Object Relational Mapper that gives application developers the full power and flexibility of SQL.
elixir is a declarative layer for SQLAlchemy.
2.3.1 Documentation
http://www.sqlalchemy.org/docs/. Watch the version difference between the documentation and the SQLAlchemy library you are using.
http://www.rmunn.com/sqlalchemy-tutorial/tutorial.html
http://spyced.blogspot.com/2007/01/why-sqlalchemy-impresses-me.html
2.3.2 example codes
check repositary code test/python/test_sqlalchemy.py for examples etc.
If you wanna create a table-corresponding object and put it into database later, you either have an __init__() to have attributes initialized or assign attributes after the object is instantiated.:
>>> class a(object): ... def __init__(self, name=None): ... self.name = name ... >>> a_o = a(name='1st object') >>> print a_o.name 1st object >>> >>> class b(object): ... pass ... >>> (initialize table mapper ...) >>> b_o = b(name='1st ojbect') #won't work. b_o.name is None >>> print b_o.name None >>> b_o = b() >>> b_o.name = '1st object' >>> print b_o.name 1st object >>>
2.3.3 208-05-23 access table field in sql.select()
Two forms exist, either thru the original Table() object, or the python class object. However, the python class object doesn't work always. In test_sqlalchemy.py, both works. In variation repository, the python class object doesn't. Might be related where the Mapper() is called.
example:
#by Table() object a = Table(...) sql.select([a.c.id,a.c.name]) ... class A(object): ... Mapper(A, a, ...) #by python class object sql.select([A.c.id, A.c.name])
Wait to find out what causes this ...
2.3.4 2008-05-24 sqlalchemy's wrapper: collective.lead
in collective/lead/database.py, in _initialize_engine()
Bug 1: when new db engine is created, old session (if there's one) does not close or bind to the new engine. This causes the session still uses the old db setting (_url). add these code in it:
if getattr(self._threadlocal, 'session', None) is not None: #2008-05-24 added by yh. new engine binding
self._threadlocal.session.close()
self._threadlocal.session = Session(bind=engine)
Bug 2: self.tables[name] = table.tometadata(self._metadata). self._metadata hasn't been updated to the new metadata. so self.tables[name] = table.tometadata(metadata).
2.3.5 2008-05-07 order_by
Putting it as a function of the whole select, select([addresses]).order_by(addresses.c.id), according to http://www.sqlalchemy.org/docs/04/sqlexpression.html, gives error:
File "/usr/lib/python2.5/site-packages/sqlalchemy/engine/base.py", line 519, in execute
raise exceptions.InvalidRequestError("Unexecuteable object type: " + str(type(object)))
sqlalchemy.exceptions.InvalidRequestError: Unexecuteable object type: <type 'NoneType'>
order_by is a keyword argument of sqlalchemy.sql.select() by looking at sqlalchemy/sql.py:
select([addresses], order_by=[addresses.c.id])
2.3.6 2008-05-30 memory management
One problem with the sqlalchemy's session thing is that it'll hoard up lots of objects in memory (and memory usage is huge compared to plain sql) before a final commit.
session.clear() or session.close() after transaction commit doesn't help to release memory. Even deleting connection. maybe need to delete objects.
2008-07-10 this is no longer a problem in version 0.4. after session.flush() and session.clear(), memory is cleared up.
2.3.7 2008-07-10 set table schema for postgres db
specifying "schema=" in Table() solves it. some people suggests con=engine.connect(); con.execute("set search_path to ..."); metadata.bind=con. it doesn't work.:
table1 = Table(table_name, metadata, autoload=True, schema=getattr(self, 'schema', None))
In elixir, either specify using_table_options in Entity-derived class:
class Gene(Entity): ... using_table_options(schema='public')
OR use using_table_options_handler() to set it later:
from elixir.options import using_table_options_handler for entity in entities: using_table_options_handler(entity, schema=self.schema)
2.3.8 2008-07-10 relationship between tables
In establishing the map (SQlAlchemy) or defining the class (elixir), make sure the python keyword and the table column would be different (default). If you customize the column name same as the keyword, the python keyword takes precedence and overwrites the column name. In your python application, that same name has to refer to a python object (which represents a row in another table).:
class Gene2go(Entity):
tax_id = Field(Integer)
gene = ManyToOne('Gene', colname='gene_id', ondelete='CASCADE', onupdate='CASCADE')
...
2.3.9 2008-07-17 how to autocommit in elixir 0.5
omitting the whole session.begin()-session.commit() pair means autocommit because the default is autoflush=True, autocommit=False in create_session() of sqlalchemy/orm/__init__.py.
Rumour is in 0.6 it's changed. check http://elixir.ematia.de/trac/wiki/Migrate05to06:
session in elixir = sqlalchemy.orm.scoped_session(session_maker()).
assuming autoflush=True, autocommit=False (with SA 0.5 -- equivalent to transactional=True with SA 0.4), autoexpire=True.
2.3.10 2008-08-07 how to do raw sql query in elixir
The metadata data structure imported from elixir has an attribute bind, which is equivalent to sqlalchemy's connection.:
from elixir import metadata
...
metadata.bind = ... #connect to a database
rows = metadata.bind.execute("select * from table")
row = rows.fetchone()
for row in rows:
print row.id
2008-08-17 according to http://elixir.ematia.de/trac/wiki/FAQ#HowdoIexecuteSQLdirectly, this should work but did not.:
from elixir import *
for result in session.execute('select * from people'):
print result['name']
2.3.10.1 2009-01-03 how to access bind from a table class
either TableClass.table.bind or TableClass.table.metadata.bind works.
2.3.10.2 2009-01-03 methods of the returned object of a raw sql query
rows = metadata.bind.execute("select * from table") and dir(rows) give:
['_ResultProxy__ambiguous_processor', '_ResultProxy__echo', '_ResultProxy__keys', '_ResultProxy__props', '__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__iter__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', '_create_key_cache', '_fetchall_impl', '_fetchmany_impl', '_fetchone_impl', '_get_col', '_has_key', '_init_metadata', '_key_cache', '_process_row', '_rowcount', 'close', 'closed', 'connection', 'context', 'cursor', 'dialect', 'fetchall', 'fetchmany', 'fetchone', 'keys', 'last_inserted_ids', 'last_inserted_params', 'last_updated_params', 'lastrow_has_defaults', 'lastrowid', 'out_parameters', 'postfetch_cols', 'rowcount', 'scalar', 'supports_sane_multi_rowcount', 'supports_sane_rowcount']
- rows is not a list. no access as rows[0]. use rows.rowcount to access its length.
- get data by rows.fetch...(). it'll return a list or just one data entry depending on the method. each data entry is a class whose attributes can be accessed as either a list or class attribute. like row=rows.fetchone(); print row[0]; print row.id;.
2.3.11 2008-08-12 how to access table name in elixir
After defining a table class inheriting from Entity, say MyTable, you can access its table name via MyTable.table.name.
2.3.12 2008-08-26 Working with Multiple Databases
Elixir has a link showing how to do that, http://elixir.ematia.de/trac/wiki/Recipes/MultipleDatabases.
Program test/python/test_elixir.py showcases how to use the 2nd approach (multiple files, defining __metadata__ and __session__).
The trick is that setup_all() needs to be invoked only once and after all __metadata__ are set up.
2.3.13 2009-5-26 search by regular expression
in sqlalchemy, use column.op('regexp')(...):
table1.select(table1.c.column1.op('regexp')('pattern'))
a bit tricky to do it in elixir:
rows = Gene_symbol2id.query.filter_by(tax_id=tax_id).filter(Gene_symbol2id.table.c.gene_symbol.op('regexp')('^%s'%namelike))
2.4 2008-04-30 python web framework solutions
- CGI. a python module works with apache or other web server. web server doesn't need to install other modules.
- mod_python is an Apache module that embeds the Python interpreter within the server. With mod_python you can write web-based applications in Python that will run many times faster than traditional CGI
- WSGI defines a simple and universal interface between web servers and web applications or frameworks for the Python programming language.
- Comprehensive wiki about everything WSGI
- mod_wsgi The aim of mod_wsgi is to implement a simple to use Apache module which can host any Python application which supports the Python WSGI interface.
- WSGI metaframework python paste
- django
- pylons 2008-08-07
- TurboGears 2008-08-07
2.5 2008-05-12 machine learning python package
shogun-python
2.6 2008-08-13 enable autocommit in python mysql module
pretty hard to find it through http://mysql-python.sourceforge.net/ (i didn't find it).
try this:
mysql_conn = MySQLdb.connect(db=dbname,host=hostname, user = user, passwd = passwd) mysql_curs = mysql_conn.cursor() mysql_conn.autocommit(True)
check its doc in python console, help(mysql_conn.autocommit).
2.7 2008-12-31 pylons
2.7.1 2008-12-31 installation
the version coming with ubuntu is 0.9.6, missing some features mentioned in pylons book. so install 0.9.7 manually.
remove some python packages to avoid conflict:
sudo apt-get remove python-pylons paste-common python-beaker python-formencode python-mako python-nose python-paste python-pastedeploy python-pastescript python-pastewebkit python-routes python-simplejson python-webhelpers
install 0.9.7 throu easy_install, -a is to ensure --always-copy (-a) Copy all needed packages to install dir in case some packages are already registered in /usr/lib/python2.5/site-packages/easy-install.pth, which might be broken due to apt-get remove:
crocea@banyan:~$ sudo easy_install -a -f http://pylonshq.com/download/0.9.7 -U Pylons
all packages installed: Pylons, Tempita 0.3, WebTest 1.1, WebError 0.10, WebOb 0.9.4, Mako 0.2.4, nose 0.10.4, simplejson 2.0.6, FormEncode 1.2.1, PasteScript 1.7.3, PasteDeploy 1.3.2, Paste 1.7.2, Beaker 1.1.2, WebHelpers 0.6.4, Routes 1.10.1, Pygments 1.0. complete log is pylons_package_install.log/view.
2008-12-31 Elixir 0.6 doesn't work with the web project because in defining relationships (like OneToMany, ManyToOne, etc.) (quote):
Default "target entity resolving code" changed slightly. It now uses a global collection keyed on the entity name. This means that entities can refer to other entities in a different module simply with the target entity name instead of its full path. The full path is only required when there is an ambiguity (ie when there are two classes with the same name in two different modules).
apt-get remove python-elixir and sudo easy_install --always-unzip elixir==0.5.2
2009-11-17 Elixir 0.6 works now. The full path means "variation.src.Stock_250kDB.README" or "variation.src.StockDB.README" rather than "README". The path depends on how the module is imported. A universal way around it is "%s.README"%__name__ in which __name__ is the module name (= __main__ if it's running as a standalone program).
2.7.2 2008-12-31 Minimal Steps to run a 0.9.6 project under 0.9.7
http://wiki.pylonshq.com/display/pylonsdocs/Upgrading
Add the following lines to config/environment.py:
# Add these imports to the top from beaker.middleware import CacheMiddleware, SessionMiddleware from routes.middleware import RoutesMiddleware # Add these below the 'CUSTOM MIDDLEWARE HERE' line, or if you removed # that, add them immediately after the PylonsApp initialization app = RoutesMiddleware(app, config['routes.map']) app = SessionMiddleware(app, config) app = CacheMiddleware(app, config)
The default behavior of the 'c' object has changed in 0.9.7, to the 'strict_c' behavior which will throw an exception if an attribute is accessed of 'c' that doesn't exist. The pre-0.9.7 behavior can be restored by adding the following to config/environment.py:
# After config.init_app: config['pylons.strict_c'] = False
Action arguments are no longer attached to 'c' by default as well, to restore the old implicit behavior add the following line to config/environment.py:
# After config.init_app: config['pylons.c_attach_args'] = True
The Rails helpers from WebHelpers are no longer automatically imported in the webhelpers package. To use them 'lib/helpers.py' should be changed to import them:
from webhelpers.rails import *
Your Pylons 0.9.6 project should now run without issue in Pylons 0.9.7. Note that some deprecation warnings will likely be thrown reminding you to upgrade other parts.
2.7.3 2009-1-30 install google-visualization-python
AKA Google visualization Python API.
- download from http://code.google.com/p/google-visualization-python/
- untar ...
- python setup.py install
2.7.4 2009-4-1 plugins for firefox (debug purpose)
- Firebug http://getfirebug.com/. esp for javascript debugging
- LiveHTTPHeaders http://livehttpheaders.mozdev.org/
2.7.5 2009-3-4 quick paster commandlines
create a new project named "HelloWorld":
paster create --template=pylons HelloWorld paster create -t pylons HelloWorld
list all templates:
paster create --list-templates
start the server:
paster serve --reload development.ini
create a controller:
paster controller hello
interactive shell:
paster shell test.ini paster shell development.ini
2.7.6 2009-1-29 set form default value
If form helpers is used, no way to set the default of entries in the form. Only through the controller's defaults.:
defaults = {'call_method_id': id,
"remove_old_plots":"on"}
c.call_method_ls = self.getCallMethodLs()
c.call_method_ls.insert(0, [0, u'Please Choose ...'])
html = render('/display_results_form.html')
return htmlfill.render(html, defaults)
2.7.7 2009-4-3 jsonify encoding error
@jsonify on top of controller method would automatically convert your whatever python data structure into json data structure but it assumes encoding utf-8, which would fail when dealing with swedish letters (latin1 encoding). so uncomment it and do it manually:
#@jsonify #2009-4-3, the default encoding 'utf-8' doesn't work due to some swedish letters.
def autoComplete(self):
"""
2009-4-3
"""
namelike = request.params.get('namelike')
name_ls = self.findAccessionsNameLike(namelike)
name_ls.sort()
if len(name_ls)>100:
name_ls = name_ls[:100]
return simplejson.dumps(dict(result=name_ls), encoding='latin1')
2.7.8 2009-5-27 unquote/decode URL
URL are usually encoded/quoted in the browser window and between data passing. Replace special characters in string using the %xx escape. Letters, digits, and the characters '_.-' are never quoted.
So if a parameter from a URL request contains special characters, it needs to be unquoted beforehand, which is to replace %xx escapes by their single-character equivalent:
import urllib
geneName = urllib.unquote(request.params.get('geneName'))
2.7.9 2009-7-22 route map
map between route path and controller/action could override the controller-based maps. For example:
map.connect('/', controller='hello', action='index')
....
map.connect('/{controller}')
map.connect('/{controller}/')
map.connect('/{controller}/{action}')
map.connect('/{controller}/{action}/')
map.connect('/{controller}/{action}/{id}')
h.url_for(controller='hello'), h.url_for(controller='hello', action='index') and h.url_for(controller='hello', action='index', id=None) all map to the same path, '/', rather than '/hello' or '/hello/index'. Unless you change the id to 'home', anything different from the default None. Another way is to put direct path like /hello there to utilize the controller-based maps.
Under usual circumstances, h.url_for(controller='hello') and / are same under the route map. It could become different when / is redirected/rewritten to something else by apache.
2.7.10 2009-6-23 character encoding in HTML
according to http://en.wikipedia.org/wiki/Character_encodings_in_HTML, characters below were encoded.
- & → & (ampersand, U+0026)
- < → < (less-than sign, U+003C)
- > → > (greater-than sign, U+003E)
- " → " (quotation mark, U+0022)
- ' → ' (apostrophe, U+0027)
The encoding happens during the argument passing from controller to the template via c.. In the template, a simple javascript line would transform it back.:
var short_name = "${c.short_name}";
short_name = short_name.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
However, the encoding happens again when the variable is read from the html(template) into a GWT js variable. So in GWT java code, this is necessary:
phenotypeMethodShortName = phenotypeMethodShortName.replaceAll("<", "<").replaceAll(">", ">").replaceAll("&", "&");
// OR
phenotypeMethodShortName = URL.decodeComponent(phenotypeMethodShortName); // not verified
2.8 2009-3-31 pyjamas
http://pyjs.org/ Pyjamas is a port of Google Web Toolkit to Python.
2.8.1 installation
easy_install doesn't work because pyjamas would be installed in /usr/share/pyjamas, which is outside easy_install's directories. seems no way around it. both -d dir and -S dir failed.
download http://pypi.python.org/packages/source/P/Pyjamas/Pyjamas-0.5.tar.gz (probably same as from code.google). tag pyjamas_0_5 from svn repositary has installation problem. python setup.py install misses lots of ui files and others.
create ./bin/buildout:
sudo python bootstrap.py
build pyjsbuild pyjscompile:
./bin/buildout
install libraries (stuff installed into /usr/share/pyjamas/):
sudo python setup.py install
Note:
- import logging as log was inserted in the beginning of /usr/lib/python2.5/site-packages/setuptools/command/sdist.py. somehow, log.warn() in sdist.py is visited and log module is not found. probably a bug in setuptools.
2.8.2 TroubleShooting
2.8.2.1 2009-3-31 import error in FormPanel.py
pyjamas.uiObject doesn't exist. EventObject is in pyjamas.ui.EventObject. But FormPanel.py hasn't adjusted to it yet, probably because it's svn development version. so modify /usr/share/pyjamas/library/pyjamas/ui/FormPanel.py:
#from pyjamas.uiObject import EventObject from pyjamas.ui.EventObject import EventObject
2.8.2.2 2009-3-31 asyncPost() error
request.body or request.params in pylons seems to never get the asyncPost() from pyjamas/JSONService.py. So change it to asyncGet():
def __sendRequest(self, method, params, handler):
id = pygwt.getNextHashId()
msg = {"id":id, "method":method, "params":params}
msg_data = self.parser.encode(msg) #turn into json
request_info = JSONRequestInfo(id, method, handler)
#if not HTTPRequest().asyncPost(self.url, msg_data, JSONResponseTextHandler(request_info)):
#2009-3-31 asyncPost() doesn't work. pylons never receives the post data. use asyncGet() below instead.
if not HTTPRequest().asyncGet(self.url+'?json=%s'%msg_data, JSONResponseTextHandler(request_info)):
return -1
return id
2.8.2.3 2009-4-1 json encoding error in 0.5
The json structure sent to the server is the key:value dictionary in the current svn version. but it is key:[key,value] in 0.5.
The json structure sent back to the client is key:value in the current svn version. but it is key:key,value in 0.5.
so i modified /usr/share/pyjamas/library/pyjslib.py for class Dict:
def __setitem__(self, key, value):
JS("""
var sKey = this._keyToStr(key);
this.d[sKey]=value; //2009-4-1 used to be [key,value]. this change might break down others.
""")
def __getitem__(self, key):
JS("""
var sKey = this._keyToStr(key);
var value=this.d[sKey];
return value; //2009-4-1 used to be value[1]
""")
2.8.3 Pyjamas-Desktop http://pyjd.org/
Desktop version of Pyjamas.
2.9 2009-11-18 svm (interface to libsvm2)
In /usr/lib/python2.5/site-packages/svm.py:
svmc.svm_node_array_set(data,j,k, x[k])
was changed to:
svmc.svm_node_array_set(data,j,k, float(x[k])) # 2009-11-18 yh: cast x[k] (data variables used to predict) to float
When x is a double list, any native python numeric type it harbors is fine. However, when x is a numpy matrix, the numeric type becomes something like numpy.int8 or numpy.float32, which can't be passed through the underlying SWIG c-interface (svmc).