SaltyCrane Blog — Notes on JavaScript and web development

python sleep

How to sleep for 5 seconds in python:

import time

time.sleep(5)

How to sleep for 0.5 seconds in python:

import time

time.sleep(0.5)

Documentation: time.sleep()

Django project #2: SQLite setup

In the first installment of the Sample Django Project, I installed Django and created a project. In this installment, I will set up the SQLite database. At first, I thought I had to figure out what kind of data to put in the database, but in actuality, I can create an empty database and fill it in later. That is what I am doing. Here are the steps.

  1. Install SQLite 3
    sofeng@tortoise:~$ sudo apt-get install sqlite3
  2. Edit settings.py
    cd to the mysite directory created last time.
    sofeng@tortoise:~$ cd ~/Web/mysite
    Edit settings.py and change the following 2 lines
    DATABASE_ENGINE = 'sqlite3'
    DATABASE_NAME = '/home/sofeng/Web/mysite/mydb'
  3. Create Django tables in the database
    sofeng@tortoise:~/Web/mysite$ python manage.py syncdb
    Creating table auth_message
    Creating table auth_group
    Creating table auth_user
    Creating table auth_permission
    Creating table django_content_type
    Creating table django_session
    Creating table django_site
    
    You just installed Django's auth system, which means you don't have any superusers defined.
    Would you like to create one now? (yes/no): yes
    Username (Leave blank to use 'sofeng'): 
    E-mail address: [email protected]
    Password: 
    Password (again): 
    Superuser created successfully.
    Installing index for auth.Message model
    Installing index for auth.Permission model
    Loading 'initial_data' fixtures...
    No fixtures found.
  4. Take a look at the databases created
    sofeng@tortoise:~/Web/mysite$ sqlite3 mydb
    SQLite version 3.4.2
    Enter ".help" for instructions
    sqlite> .schema
    You should see a bunch of CREATE TABLE statements. If you get the following error message, it probably means you used sqlite instead of sqlite3.
    Unable to open database "mydb": file is encrypted or is not a database

Well that was pretty easy. Next time, we'll create some models and actually write some python code.

Relational database introduction with Python and SQLite

I mentioned in a previous post that I have an Excel spreadsheet containing a bunch of information about the development C code I'm working on. It is a large table showing which variables are input and output from which functions. The variable names are in the first column and the function names are in the last several columns of the first row. I use "i" or "o" to denote if a variable is an input to or an output from a particular function. I also have a few columns for the variable type and description. A simplified example is shown in the table below.

ORIGINAL TABLE
namemoduletypedescExtSourceDoThisCalcThisCalcThatModifyStuffExtSink
fooModuleExtdoubleDescription of foooi i  
barModuleExtdoubleDescription of baroii   
knarkModule1intDescription of knark ioi   
wertModule1doubleDescription of wert o ii 
jibModule1doubleDescription of jib  o i 
lazModule2doubleDescription of laz  o oi
kewModule2doubleDescription of kew   ooi

As shown above, the table also includes the variable descriptions, type, and scope. In my real, unsimplified Excel table, I also include function-related information such as the function description, and the function prototype. This additional information makes the table very messy. Try to imagine where you would put the function description and function prototype information in the table above. I came up with a kludge solution, but it involved repeated information, and rows and columns with inconsistent meaning. I was realizing the limitations of a 2-dimensional table.

I had been interested in learning about relational databases, so this seemed like a good opportunity. Relational databases imply the SQL query language-- relational databases that use SQL are about the only kind around. They include: Oracle, Microsoft SQL Server, PostgreSQL, MySQL, and SQLite among others. I chose SQLite for my task because it is lightweight (no separate server), free, popular, and fast for small databases. (See http://www.sqlite.org/different.html for other distinctive features.) Also Python 2.5 now includes an interface module, sqlite3, as part of the standard distribution. See http://docs.python.org/lib/module-sqlite3.html for the documentation.

Relational model design

I could create a relational database using my original table in the Excel spreadsheet. However, this organization is not in the spirit of relational database design. The [relational] approach is to create many smaller tables and relationships between those tables. For my example, I created a variable table, a function table, and a variable_function table to indicate the relationship between the variable and function tables. Though it looks more complicated than the original single table form, inputting this into a relational database, such as SQLite, will allow for more advanced manipulation of the data. It is also much more [conducive] to maintenance and expansion. For example, now there is a natural place to put the additional function-related information which was so clumsy in the original single table. To do this, I add desc and prototype columns to the function table. If I needed to add more information to about the different modules, I could create a separate module table and include the module_id as a column in the variable table.

VARIABLE TABLE
idnamemoduletypedesc
1fooModuleExtdoubleDescription of foo
2barModuleExtdoubleDescription of bar
3knarkModule1intDescription of knark
4wertModule1doubleDescription of wert
5jibModule1doubleDescription of jib
6lazModule2doubleDescription of laz
7kewModule2doubleDescription of kew

FUNCTION TABLE
idname
1ExtSource
2DoThis
3CalcThis
4CalcThat
5ModifyStuff
6ExtSink

VARIABLE_FUNCTION TABLE
variable_idfunction_idtype
11output
12input
14input
21output
22input
23input
32input-output
33input
42output
44input
45input
53output
55input
63output
65output
66input
74output
75output
76input

SQLite Implementation (w/ Python)

To implement this database, all I needed was Python 2.5. If you have an older version of Python, you can install the pysqlite module. Here is the Python code to implement the database above.

import sqlite3

# data
VARIABLES = (
    (1, 'foo', 'ModuleExt', 'double', 'Description of foo'),
    (2, 'bar', 'ModuleExt', 'double', 'Description of bar'),
    (3, 'knark', 'Module1', 'int', 'Description of knark'),
    (4, 'wert', 'Module1', 'double', 'Description of wert'),
    (5, 'jib', 'Module1', 'double', 'Description of jib'),
    (6, 'laz', 'Module2', 'double', 'Description of laz'),
    (7, 'kew', 'Module2', 'double', 'Description of kew'),
)
FUNCTIONS = (
    (1, 'ExtSource'),
    (2, 'DoThis'),
    (3, 'CalcThis'),
    (4, 'CalcThat'),
    (5, 'ModifyStuff'),
    (6, 'ExtSink'),
)
VAR_FUNC = (
    (1, 1, 'output'),
    (1, 2, 'input'),
    (1, 4, 'input'),
    (2, 1, 'output'),
    (2, 2, 'input'),
    (2, 3, 'input'),
    (3, 2, 'input-output'),
    (3, 3, 'input'),
    (4, 2, 'output'),
    (4, 4, 'input'),
    (4, 5, 'input'),
    (5, 3, 'output'),
    (5, 5, 'input'),
    (6, 3, 'output'),
    (6, 5, 'output'),
    (6, 6, 'input'),
    (7, 4, 'output'),
    (7, 5, 'output'),
    (7, 6, 'input'),
)

# get connection and cursor objects
conn = sqlite3.connect('iodatabase')
c = conn.cursor()

# create tables
c.execute('''create table variable (
    id integer,
    name text,
    module text,
    type text,
    desc text
)''')
c.execute('''create table function (
    id integer,
    name text
)''')
c.execute('''create table var_func (
    variable_id integer,
    function_id integer,
    type text
)''')

# fill tables with data
for row in VARIABLES:
    c.execute('insert into variable values (?,?,?,?,?)', row)
for row in FUNCTIONS:
    c.execute('insert into function values (?,?)', row)
for row in VAR_FUNC:
    c.execute('insert into var_func values (?,?,?)', row)

Querying the Database

Now that I have created the database, I can get answers to interesting questions, such as What variables are output by CalcThis? Here is the Python/SQLite code to answer this question:

c.execute(''.join([
            'SELECT variable.name, variable.module, variable.type, variable.desc ',
            'FROM variable, var_func, function ',
            'WHERE variable.id=var_func.variable_id ', 
            'AND function.id=var_func.function_id ',
            'AND function.name="CalcThis" ',
            'AND var_func.type="output" ',
            ]))
FORMAT = '%-6s%-10s%-8s%-20s'
print FORMAT % ('name', 'module', 'type', 'desc')
print '-' * 44
for row in c:
    print FORMAT % row
Here is the output.
name    module    type    desc
----------------------------------------------
jib     Module1   double  Description of jib
laz     Module2   double  Description of laz
I can see this is consistent with my original table. The query works. For such a small example, the original method may seem easier, but as the number of entries grows, the benefit of the relational database grows as well. Here is another example which asks Which functions use the variable wert as an input?
c.execute(''.join([
            'SELECT function.name ',
            'FROM variable, var_func, function ',
            'WHERE variable.id=var_func.variable_id ', 
            'AND function.id=var_func.function_id ',
            'AND variable.name="wert" ',
            'AND var_func.type="input" ',
            ]))
print 'name'
print '------------'
for row in c:
    print '%s' % row
Output:
name
---------
CalcThat
ModifyStuff
I would like to do even more complicated things like determine the prerequisite input variables across all functions for a given output variable. However, I still need to read more about that, so that will have to wait.

Django project #1: Install

I plan to do a side project in Django just to get some web programming experience. I'm not sure exactly what the site will be yet. Maybe my very own blog software with extensive tagging capabilities and maybe revision control. I also have an idea for a site to specialize in comparison searching. E.g. "python vs. ruby", "mac vs. linux", "kde vs. gnome", etc. Or, if I find someone who needs a website, I might work someone else's project. As long as I get to choose the technology. Anyways, I plan to document my steps here. I've already installed Ubuntu. Here are my steps in creating my Django website.

Install django

$ sudo apt-get install python-django

Test install

To test the install, I typed import django in the python interpreter.

$ python
Python 2.5.1 (r251:54863, Oct  5 2007, 13:36:32) 
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> 
Alright, It worked.



Create a project

I tried to follow the Django tutorial and ran the django-admin.py command. However, I got the command not found error message.

$ django-admin.py startproject mysite
bash: django-admin.py: command not found
I googled for the error message and found this link which said to link the django-admin.py file to a location in your path.
$ sudo ln -s /usr/lib/python-django/bin/django-admin.py /usr/local/bin/django-admin.py
I tried the django-admin.py command again, and now got a Permission denied error.
$ django-admin.py startproject mysite
bash: /usr/local/bin/django-admin.py: Permission denied
Googling again, I found the SVN release version of the tutorial which gave instructions about the Permission denied error. (I was using the 0.96 version of the tutorial). So I changed the permissions of the django-admin.py file to be executable.
$ sudo chmod +x /usr/lib/python-django/bin/django-admin.py
I tried the command again.
$ django-admin.py startproject mysite
Alright, success! I got no errors.



Start the development web server

$ cd mysite
$ python manage.py runserver
Validating models...
0 errors found.

Django version 0.96, using settings 'mysite.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Alright, it worked! I know you are excited. I visited http://127.0.0.1:8000/ in my browser and got a nice page affirming me of my success.

It worked!
Congratulations on your first Django-powered page.

This seems like a good stopping point. The next step is setting up the database.

Ubuntu Gutsy Emacs Copy Paste

I have Ubuntu 7.10 Gutsy Gibson (Gnome) and installed the emacs22 package. Copy and paste did not work from Emacs to the Firefox search box and from the Firefox location box to Emacs. I did get it working after a little Google searching. But it made me think back to Tim Bray's comments in Back to the Mac regarding the importance of a simple thing like copy and paste.

Here is the fix, which worked like a charm. I got this from the Ubuntu forums. Put the following two lines in your .emacs file.

(setq x-select-enable-clipboard t)
(setq interprogram-paste-function 'x-cut-buffer-or-selection-value)

Useful Firefox keyboard shortcuts

Lesser known shortcuts:
CTRL+E or CTRL+K: focus search box
CTRL+L: focus location box
CTRL+J: toggle downloads window
CTRL+U: show page source
CTRL+B: toggle del.icio.us bookmarks in the sidebar
CTRL+H: toggle history in the sidebar
CTRL+D: add a del.icio.us bookmark

Basic shortcuts:
F11: toggle full screen
CTRL+T: open new tab
CTRL+W: close current tab
CTRL+F: find on page
CTRL+PGUP: previous tab
CTRL+PGDOWN: next tab
CTRL+P: open print dialog
ALT+LEFTARROW: back
ALT+RIGHTARROW: forward
ALT+HOME: home

First steps with Ubuntu Gutsy

I recently installed Ubuntu 7.10 Gutsy Gibson on my Dell E1405 laptop dual booting with Windows Vista. Here are my first steps at configuration. Note, I tried Kubuntu (KDE) for a while, but ended up going with the Gnome version because it seemed stabler, a little faster, is more popular (i.e. more support articles aimed at regular Ubuntu), and also the Compbiz Fusion / Beryl stuff looked cool. I'll probably add some KDE apps as I discover them in the future.
  1. Get internet working with Verizon wireless EVDO express card (Novatel V640)
    http://www.savvyadmin.com/2007/06/03/ubuntu-dell-5700-evdo/
    This actually works with no problems. And it seems to be faster under Ubuntu than under Vista.

  2. Select package manager repositories
    • From the Gnome desktop's System menu, Administration -> Synaptic Package Manager
    • Settings -> Repositories
    • in the Ubuntu Software tab, check:
      main, universe, and restricted
    • in the Updates tab, check:
      gutsy-security
      gutsy-updates
    • After closing the dialog, be sure to click the "Reload" button.

  3. Run Update Manager
    System -> Administration -> Update Manager
    • press the Check button
    • press the Install Updates button

  4. Configure Firefox
    • set home page to del.icio.us
    • remove bookmarks toolbar
    • save downloads to /home/sofeng/incoming
    • install del.icio.us Bookmarks Firefox Add-on
      https://addons.mozilla.org/en-US/firefox/addon/3615
    • install IE Tab Firefox Add-on (oh, not available for linux)
    • install flash plugin (free version)
      sudo apt-get install mozilla-plugin-gnash
    • youtube doesn't work
    • remove free flash plugin
      sudo apt-get autoremove mozilla-plugin-gnash
    • install flash plugin (non-free version)
      sudo apt-get install flashplugin-nonfree
      got an error message:
      sofeng@tortoise:~$ sudo apt-get install flashplugin-nonfree 
      Reading package lists... Done
      Building dependency tree       
      Reading state information... Done
      Package flashplugin-nonfree is not available, but is referred to by another package.
      This may mean that the package is missing, has been obsoleted, or
      is only available from another source
      E: Package flashplugin-nonfree has no installation candidate
      It appears as if I didn't add the multiverse repository. But I did. It turns out I didn't press the "Reload" button after adding the new repositories. hmmph. went back and did that and everything worked good.
  5. Install and configure emacs
    sofeng@tortoise:~$ sudo apt-get install emacs22
    copy in my .emacs file

  6. Install and configure my shell and terminal
    • copy in my .bashrc
    • copy in my .Xdefaults
    • copy in my .screenrc
    • install urxvt:
      sofeng@tortoise:~$ sudo apt-get install rxvt-unicode
    • To my suprise, I actually like gnome-terminal better than urxvt. The gnome-terminal font was better than urxvt and I couldn't figure out how to use that one with urxvt. While I was evaluating gnome-terminal, I found out it actually has areal transparent background!This is sweet. Google "ubuntu transparent background" to find out more. I will still use screen inside of gnome-terminal in lieu of gnome-terminal's tabs. There's no replacement for screen yet.

  7. Turn off PC speaker to get rid of annoying beeps
    sofeng@tortoise:~/$ sudo sh -c 'echo "blacklist pcspkr" >> /etc/modprobe.d/blacklist'
    from http://ubuntu-tutorials.com/2007/07/26/turning-off-the-system-hardware-beep-linux-tutorial/

  8. Do not dim display when on battery power
    From the Gnome System menu, Preferences -> Power Management
    On Battery Power tab:
    Dim display brightness by: 0%