Thursday, May 29, 2008

Back to Python

I haven't used Python in a while. I'm logging my re-familiarization on the REPL and Doc Strings.

REPL

I write my code in emacs and run it on the REPL instead of just doing ./my_code.py. I use execfile to load my code:
$ ls -l my_code.py 
-rwx------ 1 user user 3305 May 29 10:17 my_code.py
$ python 
Python 2.4.3 (#1, Dec 11 2006, 11:38:52) 
[GCC 4.1.1 20061130 (Red Hat 4.1.1-43)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> execfile("my_code.py")
>>> call_a_function_defined_in_my_code()
>>>
In emacs M-x py-shell will get you a local Python REPL and you can C-x o in a split screen between the REPL and your code (for mouse free development). I like to use tramp to edit remote files. To accommodate this style with the py-shell I just ssh from ansi-term and start the REPL as above.

Doc Strings

I tend to include a lot of comments when I define functions. My typical function looks like this:
# -------------------------------------------------------
def my_function():
    """
    Function:                my_function

    Description:             1-3 line description of 
                             the function... with an 
                             extra line here... 

    Parameters:
       [in] string $url      The URL for x
       [in] array $arr       An associative array of y
       [in] int $num         The amount of z
       (in) boolean $flag    An optional flag to do k
                             (Default: false)
       (in) string $name     An optional name
                             (Default: "Larry")

    Return Values:           
       interger              -1 if an error occured
                             0 if authentication failed
                             1 on sucess

    Remarks:                 
       None                  
    """
    # ---------------------------------------------------
    # first line here
I can view this with Python's __doc__ attribute:
>>> print my_function.__doc__

    Function:                my_function

    Description:             1-3 line description of 
                             the function... with an 
                             extra line here... 

    Parameters:
       [in] string $url      The URL for x
       [in] array $arr       An associative array of y
       [in] int $num         The amount of z
       (in) boolean $flag    An optional flag to do k
                             (Default: false)
       (in) string $name     An optional name
                             (Default: "Larry")

    Return Values:           
       interger              -1 if an error occured
                             0 if authentication failed
                             1 on sucess

    Remarks:                 
       None                  
    
>>>
The following elisp allows me to M-x function-template to easily place the above template in a python-mode buffer.
(defvar py-indent-offset 4
  "*Indentation increment in Python mode")

(defun function-template ()
  "creates a template for a function in:  PHP, Perl or Python"
  (interactive)
  (if (eq major-mode 'python-mode)
      (progn 
 (line line-length-default)
 (insert-string "def my_function():\n")))
  (save-excursion 
    (let ((pos (point)))
      (if (eq major-mode 'python-mode)
   (progn 
     (insert-string "\"\"\"\n")
     (insert-string "Function:                my_function\n\n"))
 (progn
   (line-no-comment line-length-default))
   (insert-string "Function:                Class::MyFunction\n\n"))
      (insert-string "Description:             1-3 line description of \n")
      (insert-string "                         the function... with an \n")
      (insert-string "                         extra line here... \n\n")
      ; (insert-string "Type:                    public\n\n")
      (insert-string "Parameters:\n")
      (insert-string "   [in] string $url      The URL for x\n")
      (insert-string "   [in] array $arr       An associative array of y\n")
      (insert-string "   [in] int $num         The amount of z\n")
      (insert-string "   (in) boolean $flag    An optional flag to do k\n")
      (insert-string "                         (Default: false)\n")
      (insert-string "   (in) string $name     An optional name\n")
      (insert-string "                         (Default: \"Larry\")\n")
      (insert-string "\n")
      (insert-string "Return Values:           \n")
      (insert-string "   interger              -1 if an error occured\n")
      (insert-string "                         0 if authentication failed\n")
      (insert-string "                         1 on sucess\n")
      (insert-string "\n")
      (insert-string "Remarks:                 \n")
      (insert-string "   None                  \n")
      (if (eq major-mode 'python-mode)
   (progn
     (insert-string "\"\"\"\n")
     (line (- line-length-default py-indent-offset))
     (insert-string "# first line here\n")
     (indent-rigidly pos (point) py-indent-offset))
 (progn
   (line-no-comment line-length-default)
   (comment-region pos (point))))
      (if (eq major-mode 'php-mode)
   (progn 
     (insert-string "\nfunction MyFunction() {\n")
     (insert-string "\n}\n\n")))
      (if (eq major-mode 'perl-mode)
   (progn 
     (insert-string "\nsub MyFunction {\n")
     (insert-string "  my ($param1, $param2, ..., $paramn) = @_;\n\n")
     (insert-string "\n}\n\n")))
      (if (not (eq major-mode 'python-mode))
   (indent-region pos (point) nil)))))
I've attempted to incorporate my style into conformance with the Python Style Guide and borrowed a little from Tim Peters' improved Emacs Python mode suggestion.

Tuesday, May 20, 2008

twelve xterms

I squeeze 12 xterms onto two 19inch monitors. I start them with this script:
#!/bin/sh
# each term is 330 high and 1000 wide

# left side left monitor

# col 1
xterm -fg green -bg black -font 8x13 -geom 78x23-2000+50  & 
xterm -fg green -bg black -font 8x13 -geom 78x23-2000+380 & 
xterm -fg green -bg black -font 8x13 -geom 78x23-2000+710 & 

# col 2
xterm -fg green -bg black -font 8x13 -geom 78x23-1000+50  & 
xterm -fg green -bg black -font 8x13 -geom 78x23-1000+380 & 
xterm -fg green -bg black -font 8x13 -geom 78x23-1000+710 & 

# right side left monitor

# col 3
xterm -fg green -bg black -font 8x13 -geom 78x23-750+50  & 
xterm -fg green -bg black -font 8x13 -geom 78x23-750+380 & 
xterm -fg green -bg black -font 8x13 -geom 78x23-750+710 & 

# col 4
xterm -fg green -bg black -font 8x13 -geom 78x23-0+50  & 
xterm -fg green -bg black -font 8x13 -geom 78x23-0+380 & 
xterm -fg green -bg black -font 8x13 -geom 78x23-0+710 & 

Monday, May 19, 2008

Debian OpenSSH Vulnerability

The openssh predictable random number generator bug means that I might need to push a new key out to a lot of non-Debian-based systems or I'm open to threats and even sarcastic comics. Luckily my main Ubuntu system was installed with Ubuntu 6.10 in Feb 2007 and that's when I generated my keys. I then proceeded with upgrades as they came out so I went to 7.10 and now 8.10. So, did 6.10 have this bug? No, it affected 7.04, 7.10 and 8.04. So the keys on this system should be fine. This is also supported by ssh-vulnkey. So my only bad key came from a laptop running Xubuntu. That key is only used on a Savannah project which the Savannah admins were kind enough to disable.

Update: Russ Cox has good comments on the bug.

While I'm on the topic of SSH key's I 'd like to mention that Ubuntu 8.10 enables the Gnome Keyring SSH Agent. All you have to do is SSH into one system and the agent caches your pass phrase. You might want to make sure you uncache your key before you get lunch or go home:

$ crontab -l
# m h  dom mon dow   command
  0 12 *   *   *     /usr/bin/ssh-add -d
  0 17 *   *   *     /usr/bin/ssh-add -d
$ 

Friday, May 9, 2008

seekdir and data center on wheels

These are just cool links that I found:
  • A concise yet detailed explanation of a BSD seekdir bug
  • Images of a mobile data center

Monday, May 5, 2008

moving log files

I want to clean up some log files but first I want to be sure they are not being written too. Otherwise I'd move the log file and the process that is writing to them (Apache) would get upset and I might interrupt a production system. Note that this is all just paranoia since I know that log files which end in a number have already been rotated.

Here are the log files which are currently open:

lsof | fgrep /var/log/httpd/ | awk {'print $9'} | sort | uniq > open.txt

Here are the log files which I intend to move:

ls -l /var/log/httpd/*.[0-9] | awk {'print $9'} | sort | uniq > move.txt
Now I compare them and get 100% diff, i.e. no intersections:
$ wc -l move.txt open.txt 
  241 move.txt
   84 open.txt
  325 total
$ diff move.txt open.txt | wc -l
327
$ 
The extra two lines come from "1,241c1,84" and "---" which diff added. So I'll move the logs:
mv /var/log/httpd/*.[0-9] /root/oldlogs/

Thursday, May 1, 2008

remount,rw

If you misconfigure your /etc/fstab and your system won't boot you'll want to boot into single user mode by using 'e' to edit grub's kernel line and adding a '1' to end. You can then boot with a 'b'. You'll then have root shell. If your root filesystem is mounted read only just remount it read/write:
mount -o remount,rw /