Entradas no planeta de goncalogomes


  • Goncalo Gomes

    Just came across this while browsing the SimpleHTTPServer code from the standard lib in Python 2.7 and as I’m a sucker for lists of codes and their inherent meanings, I figured I’d post it here (see also signals)

    from BaseHTTPServer import BaseHTTPRequestHandler
    for code, meaning in BaseHTTPRequestHandler.responses.items():
        print code, "=>", meaning[0]
    

    Output:

    200 => OK
    201 => Created
    202 => Accepted
    203 => Non-Authoritative Information
    204 => No Content
    205 => Reset Content
    206 => Partial Content
    400 => Bad Request
    401 => Unauthorized
    402 => Payment Required
    403 => Forbidden
    404 => Not Found
    405 => Method Not Allowed
    406 => Not Acceptable
    407 => Proxy Authentication Required
    408 => Request Timeout
    409 => Conflict
    410 => Gone
    411 => Length Required
    412 => Precondition Failed
    413 => Request Entity Too Large
    414 => Request-URI Too Long
    415 => Unsupported Media Type
    416 => Requested Range Not Satisfiable
    417 => Expectation Failed
    100 => Continue
    101 => Switching Protocols
    300 => Multiple Choices
    301 => Moved Permanently
    302 => Found
    303 => See Other
    304 => Not Modified
    305 => Use Proxy
    307 => Temporary Redirect
    500 => Internal Server Error
    501 => Not Implemented
    502 => Bad Gateway
    503 => Service Unavailable
    504 => Gateway Timeout
    505 => HTTP Version Not Supported

  • Goncalo Gomes

    I was searching the web for a quick way to clone all of the XenServer repositories on github with little effort and came across this snippet on GIST by caniszczyk:

    curl -s https://api.github.com/orgs/twitter/repos?per_page=200 | ruby -rubygems -e 'require "json"; JSON.load(STDIN.read).each { |repo| %x[git clone #{repo["ssh_url"]} ]}'
    

    It worked neatly. Although, the sequential nature of the git-clone loop caused it to take a considerable amount of time to complete. This prompted me to think about how could I parallelize the git-clone and re-write it as a python oneliner instead, so my version of the script above, as translated to curl/python/xargs can be found below. The xargs -P command is used to control how many parallel processes are spawned, adjust according to your bandwidth/computer.

    curl -s https://api.github.com/orgs/xenserver/repos?per_page=200 | python -c 'import sys,json; print "\n".join(map(lambda x: x.get("ssh_url"), json.loads(sys.stdin.read())))' |xargs -L1 -P 10 git clone
    
  • Goncalo Gomes

    ## exploration and discovery
    try:
        from PriorExperience import insight,serendipity
        my_new_idea = gen_ideas(insight,serendipity,NewTechnology)
    except:
        my_new_idea = copy.copy(somebody_elses_idea)
    
    ## get funding and build a team
    funded = False
    while not funded:
        proposal = gen_proposal(my_new_idea).submit()
        wait(SIX_MONTHS)
        funded = proposal.was_funded
    from multiprocessing import Pool
    grads = Pool(5) ; postdocs = Pool(3) ; undergrads = Pool(8)
    
    ## do the work and write it up
    results = get_data(grads,postdocs,undergrads,proposal.cash).findresult()
    paper = results.write_paper()
    paper.submit(journal="Science") # this will be accepted without revision
    
    ## reap rewards
    cv_item = collect_prize(type="Nobel",thank=",".join([x.name for x in grads]))
    

    Original GitHub repository here.

  • Goncalo Gomes

    One of the many great advantages of python is introspection. Python’s introspective design allows you to read, modify, write (and in some cases call) the functions, objects, variables defined in the current running instance of python. Amongst other things it allows for your programs to do smart things such as listing all methods and properties of an object instance, obtaining a list of frames and accessing your call stack.

    One such case I needed to use introspection was in a debug function where I want it to print who the caller is, so that if I get a flood of debug messages, I know what their caller was. For my own needs, I don’t need to be specific as to the frame address because I know each parent would only have a single call to my debugging function, I just can’t tell which order they would be calling in due to the dynamic nature of my program.

    That said, there is a simple way to do this. Python comes bundled with an extensive library of modules, one of which is the inspect module. This module defines a function called stack which returns a list of records for the stack above the caller’s frame, where 0 is the parent function to your inspect.stack() call and -1 (which is an alias to the last item in a list) is the <module>, or the bare python interpreter prior to __main__. The return list is essentially a list of record frames packed as tupples. Each record contains a frame object, filename, line number, function name, a list of lines of context, and index within the context.

    #!/usr/bin/python
    import inspect
    
    def foo():
        debug("starting...")
    
    def main():
        foo()
    
    def debug(x):
        print "caller=%s :: %s" % (inspect.stack()[1][3], x)
    
    if __name__ == '__main__':
        main()
    

    The output is as follows:

    $ python foo.py
    caller=foo :: starting...
    

  • Goncalo Gomes

    This menu was the only example I found on python with curses, so I decided to utilise it and convert it into a reusable python object and tidy it up a little.

    #!/usr/bin/python
    #
    # Adapted from:
    # http://blog.skeltonnetworks.com/2010/03/python-curses-custom-menu/
    #
    # Goncalo Gomes 
    # http://promisc.org
    #
    
    import signal
    signal.signal(signal.SIGINT, signal.SIG_IGN)
    
    import os
    import sys
    import curses
    import traceback
    import atexit
    import time
    
    class cmenu(object):
        datum = {}
        ordered = []
        pos = 0
    
        def __init__(self, options, title="python curses menu"):
            curses.initscr()
            curses.start_color()
            curses.init_pair(1, curses.COLOR_RED, curses.COLOR_WHITE)
            curses.curs_set(0)
            self.screen = curses.initscr()
            self.screen.keypad(1)
    
            self.h = curses.color_pair(1)
            self.n = curses.A_NORMAL
    
            for item in options:
                k, v = item.items()[0]
                self.datum[k] = v
                self.ordered.append(k)
    
            self.title = title
    
            atexit.register(self.cleanup)
    
        def cleanup(self):
            curses.doupdate()
            curses.endwin()
    
        def upKey(self):
            if self.pos == (len(self.ordered) - 1):
                self.pos = 0
            else:
                self.pos += 1
    
        def downKey(self):
            if self.pos <= 0:
                self.pos = len(self.ordered) - 1
            else:
                self.pos -= 1
    
        def display(self):
            screen = self.screen
    
            while True:
                screen.clear()
                screen.addstr(2, 2, self.title, curses.A_STANDOUT|curses.A_BOLD)
                screen.addstr(4, 2, "Please select an interface...", curses.A_BOLD)
    
                ckey = None
                func = None
    
                while ckey != ord('\n'):
                    for n in range(0, len(self.ordered)):
                        optn = self.ordered[n]
    
                        if n != self.pos:
                            screen.addstr(5 + n, 4, "%d. %s" % (n, optn), self.n)
                        else:
                            screen.addstr(5 + n, 4, "%d. %s" % (n, optn), self.h)
                    screen.refresh()
    
                    ckey = screen.getch()
    
                    if ckey == 258:
                        self.upKey()
    
                    if ckey == 259:
                        self.downKey()
    
                ckey = 0
                self.cleanup()
                if self.pos >= 0 and self.pos < len(self.ordered):
                    self.datum[self.ordered[self.pos]]()
                    self.pos = -1
                else:
                    curses.flash()
    
    
    
    def top():
        os.system("top")
    
    def exit():
        sys.exit(1)
    
    try:
        c = cmenu([
            { "top": top },
            { "Exit": exit },
            ])
        c.display()
    
    except SystemExit:
        pass
    else:
        #log(traceback.format_exc())
        c.cleanup()