Python 3 bytes indexing returns integers!

While converting a bunch of werkzeug code to Python 3.1, I ran into an issue with one of the bytes objects that was previously a string.

The line of code in question was originally this:

if value and value[0] == value[-1] == b'"':
   ...

If value is something, and the first and last characters are a quote character, then…

However, as it turns out, the bytes object is actually a list of integers in the range of 0-255.

So when you use an indexing operation on a byte, you actually get an integer back. For example:

>>> x = b'Hello World'
>>> x[0]
72

>>> x = 'Hello World'
>>> x[0]
'H'

Big difference, eh?

Example Automated MySQL Backup Script

Rather than use --all-databases, which will prevent you from being able to selectively restore any single database, consider the following:

Ideally, you should have a daily backup, with some history. It should be bulletproof (--force), it should be logged (>> ...log), it should be compressed (| gzip), it should keep separate copies of each database, and it should automatically pick up any databases that are added.

Consider, rather, a shell script like this:

#!/bin/bash

Host=server.domain.com
BDir=/home/backup/backup/mysql

Dump="/usr/bin/mysqldump --skip-extended-insert --force"
MySQL=/usr/bin/mysql

Today=$(date "+%a")

# Get a list of all databases
Databases=$(echo "SHOW DATABASES" | $MySQL -h $Host)

for db in $Databases; do
        date=`date`
        file="$BDir/$Host-$db-$Today.sql.gz"
        echo "Backing up '$db' from '$Host' on '$date' to: "
        echo "   $file"
        $Dump -h $Host $db | gzip > $file
done

Which is assuming that you have a file ~/.my.cnf (chmod 600), that has:

[client]
user = "BACKUP"
password = "SOMEPASS8342783492"

Make sure that whatever user you are using for BACKUP has this grant statement:

GRANT
  SELECT, SHOW VIEW ON *.*
  TO BACKUP@localhost
  IDENTIFIED BY 'SOMEPASS8342783492';

So simply add this to a nightly cronjob, and you have a daily backup that rotates each 7 days week.

0 3 * * *   backup-mysql >> backup-mysql.log 2>> backup-mysql.log

The backup directory then contains:

-rw-r--r-- 1 backup backup 2217482184 Sep  3 13:35 base.appcove.net-VOS4_0-20090903.sql.gz
-rw-rw-r-- 1 backup backup 2505876287 Dec 25 00:48 base.appcove.net-VOS4_0-Fri.sql.gz
-rw-r--r-- 1 backup backup 2500384029 Dec 21 00:48 base.appcove.net-VOS4_0-Mon.sql.gz
-rw-r--r-- 1 backup backup 2506849331 Dec 26 00:48 base.appcove.net-VOS4_0-Sat.sql.gz
-rw-r--r-- 1 backup backup 2499859469 Dec 20 00:48 base.appcove.net-VOS4_0-Sun.sql.gz
-rw-rw-r-- 1 backup backup 2505046147 Dec 24 00:48 base.appcove.net-VOS4_0-Thu.sql.gz
-rw-rw-r-- 1 backup backup 2502277743 Dec 22 00:48 base.appcove.net-VOS4_0-Tue.sql.gz
-rw-r--r-- 1 backup backup 2504169910 Dec 23 00:48 base.appcove.net-VOS4_0-Wed.sql.gz
-rw-r--r-- 1 backup backup   76983829 Dec 25 00:49 base.appcove.net-VOS4_Mail_0-Fri.sql.gz
-rw-r--r-- 1 backup backup   76983829 Dec 21 00:49 base.appcove.net-VOS4_Mail_0-Mon.sql.gz
-rw-r--r-- 1 backup backup   76983829 Dec 26 00:49 base.appcove.net-VOS4_Mail_0-Sat.sql.gz
-rw-r--r-- 1 backup backup   76983829 Dec 20 00:48 base.appcove.net-VOS4_Mail_0-Sun.sql.gz
-rw-rw-r-- 1 backup backup   76983829 Dec 24 00:49 base.appcove.net-VOS4_Mail_0-Thu.sql.gz
-rw-rw-r-- 1 backup backup   76983829 Dec 22 00:49 base.appcove.net-VOS4_Mail_0-Tue.sql.gz
-rw-r--r-- 1 backup backup   76983829 Dec 23 00:49 base.appcove.net-VOS4_Mail_0-Wed.sql.gz
-rw-r--r-- 1 backup backup  304803726 Dec 25 00:49 base.appcove.net-WeSell_0-Fri.sql.gz
-rw-r--r-- 1 backup backup  303480087 Dec 21 00:49 base.appcove.net-WeSell_0-Mon.sql.gz
-rw-r--r-- 1 backup backup  304710121 Dec 26 00:49 base.appcove.net-WeSell_0-Sat.sql.gz
-rw-r--r-- 1 backup backup  303791294 Dec 20 00:49 base.appcove.net-WeSell_0-Sun.sql.gz
-rw-rw-r-- 1 backup backup  305315415 Dec 24 00:49 base.appcove.net-WeSell_0-Thu.sql.gz
-rw-rw-r-- 1 backup backup  302516217 Dec 22 00:49 base.appcove.net-WeSell_0-Tue.sql.gz
-rw-r--r-- 1 backup backup  303314217 Dec 23 00:49 base.appcove.net-WeSell_0-Wed.sql.gz
-rw-r--r-- 1 backup backup     135301 Dec 25 00:30 dc40.appcove.net-mysql-Fri.sql.gz
-rw-r--r-- 1 backup backup     135301 Dec 21 00:30 dc40.appcove.net-mysql-Mon.sql.gz
-rw-r--r-- 1 backup backup     135301 Dec 26 00:30 dc40.appcove.net-mysql-Sat.sql.gz
-rw-r--r-- 1 backup backup     135301 Dec 20 00:30 dc40.appcove.net-mysql-Sun.sql.gz
-rw-rw-r-- 1 backup backup     135301 Dec 24 00:30 dc40.appcove.net-mysql-Thu.sql.gz
-rw-rw-r-- 1 backup backup     135301 Dec 22 00:30 dc40.appcove.net-mysql-Tue.sql.gz
-rw-r--r-- 1 backup backup     135301 Dec 23 00:30 dc40.appcove.net-mysql-Wed.sql.gz

How to Author a *simple* jQuery plugin

I use jQuery as the JavaScript library for most projects. It’s terribly convenient for selecting elements and processing them.

However, jQuery is not JavaScript, and there is a lot of things it cannot do. Rather than writing a separate set of functionality outside of jQuery, why not simply extend it on an application-per-application basis? It really is that easy. Perhaps if you get some functionality that is good enough, you will want to convert them into a formal plugin and post it to http://plugins.jquery.com/

Here is the document that explains, in depth, how to author plugins.
http://docs.jquery.com/Plugins/Authoring

Here is an example at a very simple plugin that I whipped together while learning about plugins… It’s designed to accept an object of data, and apply it to any of the elements whose name attribute match the key of the data.

jQuery.fn.populate = function(Data) {
   this.each(function() {
      if (this.name in Data)
      {
         switch(this.type)
         {
            case 'text': this.value = Data[this.name]; break;
            case 'checkbox': this.checked = Data[this.name]; break
         }
      }
   });
   return this;
};

To call it… Select all input elements of the #Login form, and populate them with the passed data.

$('#Login :input').populate({ FirstName: 'sammy', LastName: 'jones' });

The .fn attribute of the jQuery object is where you attach new methods. The this member of those functions is set to the current jQuery object. The function must return the current jQuery object (self) unless explicitly stated otherwise.

Iterating through the elements of the current jQuery object should be done with this.each(…).

All in all, it’s very simple, and very powerful to be able to nest custom functionality into the jQuery object within a given application.

Read more at:

jQuery mouseout vs. mouseleave

Hello!

jQuery has a mouseout and a mouseleave event. The main difference is in how they handle child elements. Mouseout fires when the pointer moves into or out from child element, while mouseleave doesn’t.

This was causing a slight problem of having some menu’s close when the mouse encountered a link or other child element within the menu, it was triggering the mouseout event of the menu.

The fix, was to convert to mouseleave.

   $("#Nav1_Content > p").mouseleave(CloseTopMenuArea);

http://docs.jquery.com/Events/mouseout

Python has keyword only parameters!

Maybe I should have known this about Python by now, but…

Little did I know (was wishing for it today), but there IS a way to specify that arguments MUST be keyword only.

>>> def foo(a,b,*,c,d):
...     print(a,b,c,d)
...
>>> foo(1,2,3,4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes exactly 2 positional arguments (4 given)
In this case, everything after the * is required to be keyword only. This means that you can safely amend the function definition to re-order or even add keyword arguments.
Likewise, the following requires ALL keyword arguments.
>>> def foo(*,a,b):
...     print(a,b)
...
>>> foo(1,2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() takes exactly 0 positional arguments (2 given)

>>> foo(a=1, b=2)
1 2


Read more about it at:

http://www.python.org/dev/peps/pep-3102/