Friday, November 30, 2012

Configing Emacs: TRAMP with Putty

I've already written how to configure TRAMP in Emacs, but it only works on Mac and Linux. Unfortunately there are some who continue to use Windows as a desktop platform.   While they may be second class netizens, they do not need to settle for second class remote editing.

Emacs is available for Windows.  For secure remote editing you need ssh.  Enter Putty, an excellent implementation of the SSH protocol for Windows.  Putty comes with plink.exe which is the command line executable.   Once you've installed Emacs and Putty on Windows you'll want to update the Path environment variable.

Right-click Computer → Properties → Advanced System Settings → Environment Variables



Once the Putty path has been appended, update your emacs config.  Set your default tramp method to be plink and the tramp auto save directory to your username's temp directory.

(require 'tramp)
(set-default 'tramp-auto-save-directory "C:\Users\<username>\AppData\Local\Temp")
(set-default 'tramp-default-method "plink")

This all you need to start remote editing with emacs using ssh. You can setup password-less logins to make it even easier.  And if you have to go through an intermediary ssh server you can use transparent multihop with Putty.

§

Thursday, November 29, 2012

Python Metaprogramming: Dynamic Class and Metaclass Creation

Python has great metaprogramming capabilities.


Python classes are typically created using the class definition.  Classes are used in much the same other classes in other OOP languages are used.  They are used to define an instantiable object with associated methods and attributes.  Classes are also one of the primary namespacing mechanisms in Python. The terms class and type are often used interchangeably in Python. Occasionaly you may need to dynamically create a class.

There are use cases for dynamically creating a class or type.  Often it's a static definition doesn't meet your needs such as a type factory that needs to work on incoming types.  You may need to create a type dynamically for testing purposes, or because it's required by a framework or library you need to use.


NewClass = type('NewClass', (object, ), {})



Metaclasses are a another kind of class.  They are created in the same way as other classes except they derive from `type`.  You can programmaticlly create a a metaclass as follows:

def new(cls, name, bases, dct):
    print "metaclass new", name
    return type.__new__(cls, name, bases, dct)

def init(cls, name, bases, dct):
    print "metclass init", name
    super(type(cls), cls).__init__(name, bases, dct)

DynamicMetaClass = type('DynamicMetaClass',(type, ),dict(__init__=init, __new__=new))
X = DynamicMetaClass('X',(), dict(foo=lambda self:'foo'))
# returns metaclass new X
#         metclass init X

§

Wednesday, November 28, 2012

Python Metaprogramming: Dynamic Module Creation

Python has great metaprogramming capabilities.

Python modules are implicitly created with a file.  It is one of the primary namespacing mechanisms in Python.  Occasionally you may wan to dynamically create one.

There are a few use cases for dynamic module creation.  The use case that comes up most frequently is modules created in the service of automated tests.  Sometimes a module is needed as input and sometimes it's needed as a mock.  Other use cases exist, but are more rare in my experience.  One I have done recently is automatic module creation to create the appropriate modules a framework or library expects. There have been other instances as well, although infrequent.  Regardless, it's a useful tool to have in your toolbox should the need ever arise.


from types import ModuleType
import sys

def make_module(new_module, doc="", scope=locals()):
    """
    make_module('a.b.c.d', doc="", scope=locals()]) -> 

    * creates module (and submodules as needed)
    * adds module (and submodules) to sys.modules
    * correctly nests submodules as needed
    """
    module_name = []
    for name in new_module.split('.'):
        m = ModuleType(name, doc)
        parent_module_name = '.'.join(module_name)
        if parent_module_name:
            setattr(sys.modules[parent_module_name], name, m)
        else:
            scope[name] = m
        module_name.append(name)
        sys.modules['.'.join(module_name)] = m
    return sys.modules['.'.join(module_name)]


§

Friday, November 16, 2012

Python Class Decorator: Logging

Python class decorators provide powerful metaprogramming capabilities.  Instead of a function, a class decorator takes a class and returns a class.  The decorator can manipulate the incoming class, or simply create a new class and return it.

The following piece of code is an example of leveraging a decorator to do Aspect Oriented Programming.  The classic example in AOP is the addition of logging to methods and functions.  Rather than writing a function decorator, and adding the decorator to each function, you can choose to create a class decorator and logging by class.



import logging
log = logging.getLogger(name)


from functools import wraps
from types import MethodType

def class_logging(klass):
    """
    Class decorator that adds logging to all "public" class methods.
    """
    method_p = lambda m: not m.startswith('_') and \
                         isinstance(getattr(klass, m), MethodType)
    public_methods = filter(method_p, dir(klass))

    for method_name in public_methods:
        class_method = getattr(klass, method_name)

        def helper(mname, method):
            @wraps(method)
            def wrapper(*a, **kw):
                msg = '{0}({1}, {2})'.format(mname, a, kw)
                log.debug(msg)
                try:
                    response = method(*a, **kw)
                except Exception, e:
                    error_message = 'no additional information'
                    if hasattr(e, 'message'):
                        error_message = e.message
                    msg = '{0} raised {1}, {2}'.format(mname, type(e), error_message)
                    log.debug(msg)
                    raise
                else:
                    msg = '{0} returned {1}'.format(mname, response)
                    log.debug(msg)

                return response
            return wrapper
        
        fn = MethodType(helper(method_name, class_method), None, klass)
        setattr(klass, method_name, fn)
    return klass



§

Wednesday, November 14, 2012

Caveat Scriptor: Python Closures


You can read more/ about the generic gotchas associated with closures here.  The following are specific to closures as they are implemented in Python.

Closure variables are read only
In Python closures variables are readonly. This means the only way you can keep and modify state is by using an element in a mutable multi-element object like a dict or list. You cannot allocate a whole new list, dict, int, etc. So this won't work.

def mk_closure():
   storage=0
   def adder():
      storage+=1
      return storage
   return adder

It will work if a list is used instead.

def mk_closure():
   storage=[0]
   def adder():
      storage[0]+=1
      return storage[0]
   return adder

Looping structures (for, while) do not have there own lexical environments
Closures capture values from lexical environments. These are only created by executing a function which means this won't work:

functions=[]
storage=[0] * 5
for i in (1, 2, 3, 4, 5):
   def adder():
      storage[i-1] += i
      return storage[i-1]
   functions.append(adder)

A lexical environment is needs to be created in every iteration that can be closed over.

functions=[]
storage=[0]*5
for i in (1, 2, 3, 4, 5):
   def helper(x):
      def adder():
         storage[x-1] += x
         return storage[0]
      return adder
   functions.append(helper(i))

There is a shortcut in Python that eliminates the need to define the helper function.  This happens to work because the default value is set at definition time of the function which acts similarly to the function execution of helper.

functions=[]
storage=[0] * 5
for i in (1, 2, 3, 4, 5):
   def adder(x=i):
      storage[x-1] += x
      return storage[x-1]
   functions.append(adder)

§

Thursday, November 1, 2012

Ubuntu: Oracle Java Browser Plugin

Web8 has create ppa for Oracle Java which installs not only java, but the web browser plugin.  You can find the details here.  Here are the cliff notes version:
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java7-installer

Once you've install Java you need to disable the IceTea plugin in your browser.


Now you should be able to run java applets using Oracle's Java.

§