Programming and writing about it.

echo $RANDOM

Category: Code

C-x C-p for import pdb; pdb.set_trace()

I worked through most of the Learn Emacs Lisp in 15 minute tutorial and learned enough to write something useful:

;; Inset import pdb; pdb.set_trace() on C-x, C-p
(defun pdb-set-trace ()
  ;; http://www.emacswiki.org/emacs/InteractiveFunction
  (interactive)
  (insert "import pdb; pdb.set_trace()\n"))
(global-set-key [(control ?x) (control ?p)] 'pdb-set-trace)

Once you place this function in your Emacs init file, when you press the keys C-x and C-p, import pdb; pdb.set_trace() will magically appear in your Python program (well, anywhere for that matter, since there is no check in place). This is something which I know will be very useful to me. If you don’t like the key combination, you can change it in the last line of the above function.

If you don’t know Emacs lisp, you should try to work through the tutorial. Although, I must say I did make various attempts long time back to learn Common Lisp and Clojure, so it was not so unfamiliar to me.

Advertisement

Writing git hooks using Python

Since git hooks can be any executable script with an appropriate #! line, Python is more than suitable for writing your git hooks. Simply stated, git hooks are scripts which are called at different points of time in the life cycle of working with your git repository.

Let’s start by creating a new git repository:


~/work> git init git-hooks-exp
Initialized empty Git repository in /home/gene/work/git-hooks-exp/.git/
~/work> cd git-hooks-exp/
~/work/git-hooks-exp (master)> tree -al .git/
.git/
├── branches
├── config
├── description
├── HEAD
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── prepare-commit-msg.sample
│   ├── pre-rebase.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags

9 directories, 12 files

Inside the .git are a number of directories and files, one of them being hooks/ which is where the hooks live. By default, you will have a number of hooks with the file names ending in .sample. They may be useful as starting points for your own scripts. However, since they all have an extension .sample, none of the hooks are actually activated. For a hook to be activated, it must have the right file name and it should be executable. Let’s see how we can write a hook using Python.

We will write a post-commit hook. This hook is called immediately after you have made a commit. We are going to do something fairly useless, but quite interesting in this hook. We will take the commit SHA1 of this commit, and print how it may look like in a more human form. I do the latter using the humanhash module. You will need to have it installed.

Here is how the hook looks like:


#!/usr/bin/python

import subprocess
import humanhash

# get the last commit SHA and print it after humanizing it
# https://github.com/zacharyvoase/humanhash
print humanhash.humanize(
    subprocess.check_output(
        ['git','rev-parse','HEAD']))

I use the subprocess.check_output() function to execute the command git rev-parse HEAD so that I can get the commit SHA1 and then call the humanhash.humanize() function with it.

Save the hook as a file, post-commit in your hooks/ directory and make it executable using chmod +x .git/hooks/post-commit. Let’s see the hook in action:

~/work/git-hooks-exp (master)> touch file
~/work/git-hooks-exp (master)> git add file
~/work/git-hooks-exp (master)> git commit -m "Added a file"
carbon-network-connecticut-equal
[master (root-commit) 2d7880b] Added a file
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 file

The commit SHA1 for the commit turned out to be 2d7880be746a1c1e75844fc1aa161e2b8d955427. Let’s check it with the humanize function and check if we get the same message as above:

>>> humanhash.humanize('2d7880be746a1c1e75844fc1aa161e2b8d955427')
'carbon-network-connecticut-equal'

And you can see the same message above as well.

Accessing hook parameters

For some of the hooks, you will see that they are called with some parameters. In Python you can access them using the sys.argv attribute from the sys module, with the first member being the name of the hook of course and the others will be the parameters that the hook is called with.

Current working directory

For some reason, it may be useful if you know what is the current working directory of your hook. The os.getcwd() function can help there and it turns out to be the local file system path to your
git repository (~/work/git-hooks-exp in the above case).

Sphinx as a Static Site Generator

In this article, we will take a look at Sphinx (specifically Sphinx 1.1.3) as a static
site generator tool. Let’s get started.

Installing Sphinx

Installing sphinx is as easy as pip install sphinx (on Linux and
Windows). pip will download a bunch of other dependencies (docutils,
Jinja2, pygments
as well). Once installed, check whether sphinx is
available to you by typing $ sphinx-quickstart at the command
line. This should give you a welcome message. We proceed from there in
the next section. (On Windows, if you have added
C:\Python27\Scripts to the Windows Path variable, the sphinx
commands should be already available to be executed since the
sphinx binaries are also installed in this location).

Read the entire article here.

Compilation and Interpretation in C and CPython

It is common knowledge that programs written in high level languages
have to be translated into a low level language using programs
referred to as translators. This low level language is either in a native form, in the sense that it is understood by the operating system itself, or in an intermediate
form which is understood by an intermediate program such as the bytecode
interpreter
. It is also known that C is a compiled language, whereas
CPython is both first compiled and then interpreted.

Read the entire article here.

Data in C and CPython: A comparison

In my last two articles (Data in CPython and Data in C), as it
turned out, I discussed two fundamental points in each language:

  • What happens in an assignment operation (such as a=2)?
  • Are separate copies of data created or references passed to the original when they are sent as function parameters?

In this article, I will summarize the findings by presenting a
comparative analysis. Read the entire article here.

Data in C

In C, the data you use in your programs will usually fall into one of the three
basic categories: int, char and float. Data in C has no
existence without an associated memory location labeled by an
identifier, usually referred to as a variable (the term variable
is a bit misleading, since it essentially means that it must always
vary, but you can have constant variables – i.e. variables whose
values do not vary). Considering this and C’s requirement for static
typing
, a variable declaration statement is required before data
can be stored in a variable. This declaration statement usually takes the
form of data-type var-name [= value], where the =value part may
or may not be present. For example, the statement int a=1;
declares a variable a which will store integer data and stores
1 in it. What this statment basically tells the C compiler is
that it should allocate a block of memory large enough to store an
integer and it will referred to as a. It is possible to obtain the
address of this memory location using the & operator.

Read the entire article here.

Data in CPython

When writing programs in Python (CPython), you have access to data types such as a int, str, tuple, list and a dict. It is fairly obvious what each of these data types would be used to represent: an int data type would represent an integer and a list would represent a list of items – homeogeneous or
heterogenous. As opposed to a language like C, the Python compiler
automatically decides what type to use for your data without the need
to be explicitly specified.

Read the entire article here.

Personalising my toolset: Konsole, BASH, Emacs, weechat, tmux..

Terminal Emulator and Shell

I use the KDE desktop (on Fedora), hence my choice of terminal emulator is KDE’s Konsole with the Solarized theme, which is built-in. I use the BASH shell, with almost no aliases and exports. However, I use a custom prompt so that I have a different color for the prompt and the output of the commands:

# prompt
# http://maketecheasier.com/8-useful-and-interesting-bash-prompts/2009/09/04
PS1="\[33[35m\]\t\[33[m\]-\[33[36m\]\u\[33[m\]@\[33[32m\]\h:\[33[33;1m\]\w\[33[m\]\$ "

Emacs

I have been a Emacs user for few years now. Unlike most people, I usually do very few customisations and/or install extra Emacs packages to enhance its functionality beyond the default features. However, last time I installed it after my upgrade to Fedora 18, I decided to spend some time customising it to my liking. I came across the awesome Mastering Emacs [1] blog of Mickey and used it as a reference point for making my Emacs customized to the way I hadn’t done before. When you first install Emacs (Emacs 24 is what I am using), on starting it what you see is something like this:

Image

The first things I do is remove the Menu bar, tool bars, scrollbar and the startup splash screen and message, which can be done with the following lines of Emacs Lisp:

(setq inhibit-startup-message t
      inhibit-startup-echo-area-message t)  
(menu-bar-mode -1) 
(tool-bar-mode -1) 
(scroll-bar-mode -1)

Now, where do you put these customization code snippets? There are three choices: ~/.emacs, ~/.emacs.el and ~/.emacs.d/init.el (where ~ indicates your home directory). I have the customization scripts in ~/.emacs.d/init.el (since that allows me to have everything in .emacs.d directory). See [2] for more details on init files.

Next, I add a few more customisations: always have line numbers and column numbers displayed and set auto-fill mode on (to automatically wrap lines). Here is how my init.el looks like now (lines beginning with ;; are comments are hence ignored):

;; hide them all.
(setq inhibit-startup-message t
inhibit-startup-echo-area-message t)
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)

;; Line number
(global-linum-mode 1)
;; Show column-number in the mode line
(column-number-mode 1)

;; Auto-fill mode
(add-hook 'text-mode-hook 'auto-fill-mode)

With the writing area quite to my liking, I next explore Emacs’s package manager [3] which will allow me to customize Emacs with a few more enhancements by installing packages. The package-list-package command will list all the currently available pacakages in ELPA with their status in my Emacs installation such as available, built-in.:

M-x package-list-packages

M-x package-list-packages

To install a new package, I can use the command package-install RET RET (or, you could use the mouse).

Theme: The first package I want to install is the solarized theme for Emacs. However, it is not available in ELPA for that, I will need to add another package repository, that of MELPA [4]. The following code in my init.el does that:

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.milkbox.net/packages/") t)

I restart Emacs and the command package-list-packages displays a number of other packages from the MELPA repository, one of them being the solarized theme which I can install using: package-install RET color-theme-solarized RET . Now, I will need to add code to load the theme on startup. The following snippet does it:

(add-to-list 'custom-theme-load-path "~/.emacs.d/themes/solarized")
(load-theme 'solarized-dark t)

By default, the solarized theme will be installed (like other packages) in ~/emacs.d/elpa. To keep my themes in a separate directory, I create a sub-directory themes under my emacs.d directory and keep all the solarized files in a separate directory solarized. Now, when I restart Emacs, I see something like this:

Emacs + Solarized

Emacs + Solarized

This is pretty much my workable Emacs configuration right now leaving aside one more package: IEdit [5]. I think this will be pretty useful for a bulk search and replace. I installed it using: package-install RET iedit RET. To enable it, use the command iedit-mode or, use C-;. See: http://ascii.io/a/1923 for a quick demo. . I hope to learn more about IEdit as I start using it more.

Like other editors, Emacs creates a backup copy when you are editing a file. This leads to a pollution of your working directory with files whose names end with ~. To tell Emacs to save to a different directory, you can add the following snippet to your init.el (taken from [7]).:

(setq
   backup-by-copying t      ; don't clobber symlinks
   backup-directory-alist
    '(("." . "~/.saves"))    ; don't litter my fs tree
   delete-old-versions t
   kept-new-versions 6
   kept-old-versions 2
   version-control t)       ; use versioned backups

 

That’s it for my Emacs configuration for now. You may want to see some of the resources I have gathered so far here [6]. My init.el file looks like this now:

;; hide them all.
(setq inhibit-startup-message t
      inhibit-startup-echo-area-message t)  
(menu-bar-mode -1) 
(tool-bar-mode -1) 
(scroll-bar-mode -1)

;; Line number
(global-linum-mode 1)
;; Show column-number in the mode line
(column-number-mode 1)

;; Auto-fill mode
(add-hook 'text-mode-hook 'auto-fill-mode)

;; Package repo
(require 'package)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.milkbox.net/packages/") t)
;; ;; (add-to-list 'package-archives
;; ;;              '("marmalade" . "http://marmalade-repo.org/packages/") t)

;;(package-initialize)

;; Solarized theme
(add-to-list 'custom-theme-load-path "~/.emacs.d/themes/solarized")
(load-theme 'solarized-dark t)

;; Font setting
(add-to-list 'default-frame-alist '(font . "DejaVu Sans Mono-14"))

;; Backup settings
(setq
   backup-by-copying t      ; don't clobber symlinks
   backup-directory-alist
    '(("." . "~/.editing_backups"))    ; don't litter my fs tree
   delete-old-versions t
   kept-new-versions 6
   kept-old-versions 2
   version-control t)       ; use versioned backups

Links:

[1] http://masteringemacs.org/
[2] http://www.gnu.org/software/emacs/manual/html_node/emacs/Init-File.html
[3] http://emacswiki.org/emacs/ELPA
[4] http://melpa.milkbox.net/
[5] http://www.masteringemacs.org/articles/2012/10/02/iedit-interactive-multi-occurrence-editing-in-your-buffer/
[6] https://gist.github.com/4600244
[7] http://emacswiki.org/emacs/BackupDirectory

One last bit of customisation I do is always start Emacs in maximized mode. Hence, I have added a BASH alias: alias emacs='emacs -mm' in my .bashrc.

Weechat for IRC

I have been using Weechat for few weeks now and really like it. I have been meaning to switch to a console based IRC client for a while now, and weechat finally looked friendly enough for me to switch to one. Here are my notes [1] on how to setup a new server, autoconnect on startup, auto join channels, etc.

[1] https://gist.github.com/4487378

tmux

No customisations yet.

input() and raw_input() in Python

Consider the following Python interactive console session with the input() function:

>>> input()
1
1
>>> input()
'f00 bar'
'f00 bar'
>>> input()
'f00
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 1
    'f00
       ^
SyntaxError: EOL while scanning string literal
>>> input()
1 67
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 1
    1 67
       ^
SyntaxError: unexpected EOF while parsing

>>> input()
'1 67'
'1 67'

And now, the raw_input() function:

>>> raw_input()
1
'1'
>>> raw_input()
2 56
'2 56'
>>> raw_input()
'f00 bar
"'f00 bar"
>>> raw_input()
f00bar
'f00bar'
>>> 

And finally:

>>> input()
5+4
9
>>> raw_input()
5+4
'5+4'

As mentioned in the documentation for the input() function (Python 2), the eval() function is called on the input using input(). Hence, the input should be syntactically valid Python. With raw_input(), the input is returned as a string and hence can be anything that your program wants to handle. In Python 3, raw_input() has been renamed to input() and raw_input doesn’t exist.

Python 3.2.3 (default, Jun  8 2012, 05:36:09) 
[GCC 4.7.0 20120507 (Red Hat 4.7.0-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> input

>>> raw_input
Traceback (most recent call last):
  File "", line 1, in 
NameError: name 'raw_input' is not defined
>>> input()
'f00bar
"'f00bar"
>>> 

Simulating c like scanf()

You can simulate C like scanf() behavior using raw_input() and split(). For example ( In Python 2):

>>> x,y,z=raw_input('Enter the co-ordinates:: ').split()
Enter the co-ordinates:: 1 5 6
>>> x
'1'
>>> y
'5'
>>> z
'6'
>>> int(x)
1
>>> int(y)
5
>>> int(z)
6

Since the input is considered a string, we have to do explicit type conversion if we want to treat the input as integers, for example.

self in Python

self keyword is a reference to the invoking class instance/object. Consider the following code:


''' Self really refers to the instance called with '''
class Point:
    
    def __init__(self):
        print 'Self identifier:: ',id(self)

if __name__ == '__main__':
    # create an instance of the class
    p = Point()

    print 'Point object identifier', id(p)
    
    # create an instance of the class
    p = Point()

    print 'Point object identifier', id(p)

As you can see, a class (that does nothing) called Point is defined and then two objects/instances are created. To verify that self is really a reference to the invoking object, we print the identifier for the calling object and self. Unsurprisingly, both are the same.

Update:
Soon after posting this, I realized that self is not a keyword. In fact its just a convention to use self as a reference to the invoking object. You can use anything else, for example, this:

class Point:
    
    def __init__(this):
        print 'This identifier:: ',id(this)

if __name__ == '__main__':
    # create an instance of the class
    p = Point()

    print 'Point object identifier', id(p)
    
    # create an instance of the class
    p = Point()

    print 'Point object identifier', id(p)