Saturday, November 21, 2009

Getch in Python - Read a Character without Enter

Sometimes it is more appropriate to read from keyboard without waiting for Enter to be codessed, for example, when choosing from a menu. The raw_input("Prompt String >") always waits for Enter, so a function similar to getch() in C is needed and there are some solutions for that in Python.
  1. There is getch() equivalent for Windows environment in library msvcrt:

    import msvcrt

    result = msvcrt.getch()

    Funny thing is that the code works fine from command window (cmd.exe), but does not in IDLE: in IDLE it does not wait for a key and gives out '\xff' as the result.

    In Linux the same can be done this way:

    import sys, tty, termios

    fd = sys.stdin.fileno()
    # save original terminal settings
    old_settings = termios.tcgetattr(fd)

    # change terminal settings to raw read
    tty.setraw(sys.stdin.fileno())

    ch = sys.stdin.read(1)

    # restore original terminal settings
    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    print '\ncodessed char is \'' + ch +'\'\n'

    Since the solution is system dependent some people propose a universal approach when program tries one implementation and if it fails - the other one, here is an example from ActiveState Code, Danny Yoo:

    class _Getch:
    """Gets a single character from standard input.
    Does not echo to the screen."""
    def __init__(self):
    try:
    self.impl = _GetchWindows()
    except ImportError:
    self.impl = _GetchUnix()

    def __call__(self): return self.impl()

    class _GetchUnix:
    def __init__(self):
    import tty, sys

    def __call__(self):
    import sys, tty, termios
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    try:
    tty.setraw(sys.stdin.fileno())
    ch = sys.stdin.read(1)
    finally:
    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    return ch

    class _GetchWindows:
    def __init__(self):
    import msvcrt

    def __call__(self):
    import msvcrt
    return msvcrt.getch()

    getch = _Getch()

  2. Using TK library the following code works OK:

    import Tkinter as tk

    def keycodess(event):
    if event.keysym == 'Escape':
    root.destroy()
    x = event.char
    if x == "a":
    print "A done"
    elif x == "b":
    print "B done"
    elif x == "c":
    print "C done"
    elif x == "d":
    print "D done"
    else:
    print x

    root = tk.Tk()
    print "a. Menu choice A"
    print "b. Menu choice B"
    print "c. Menu choice C"
    print "d. Menu choice D"
    root.bind_all('', keycodess)
    # hiding the tk window
    root.withdraw()
    root.mainloop()

    It works OK in Windows command window (cmd.exe), but in IDLE and Linux the line root.withdraw() should be commented out - the code works OK while the root window is in focus. This kind of examples you can find here.

  3. Curses library has its own getch implementation. I did not check it, just would like to mention for the record.
If you know any other solutions - I'd love to here from you about them!
Read more...

Sunday, November 15, 2009

Getting Out of The Python's Loops

Python is a great language - I used it many times for measurement automation. The only thing I stumbled on from time to time was a simple control over long time or infinite loops. When the loop is running it should check for a key or a button been pressed without stopping and waiting for input. Such stopping and waiting happens, for example, when a function like getch() is used.

The case in general looks like this:
while 1:
print 1,
and the problem is how to get out of the loop gracefully without killing the program.

I'm aware of the following variants to deal with the situation:
  1. Ctrl-C/Crtl-D keyboard program termination. It works but kills whole program. It is possible to avoid that by exception processing of the error:
    try:
    while 1:
    print 1,
    # on ctrl-d or ctrl-c
    except (EOFError, KeyboardInterrupt):
    print '\n exception handled'
    print 'Clean Exit on Ctrl-C/D'

  2. Tkinter - it allows to stop looping on event as "button pressed":
    import time
    from Tkinter import *

    class App:

    Var = 1

    def __init__(self, master):
    frame = Frame(master)
    frame.pack()

    self.button = Button(frame, text="QUIT",
    command=frame.quit)
    self.button.pack(side=LEFT)

    self.stoploop = Button(frame, text="Stop",
    command=self.stopLoop)
    self.stoploop.pack(side=LEFT)

    while self.Var == 1:
    time.sleep(1)
    print self.Var,

    print "\nClean exit from the loop"

    def stopLoop(self):
    self.Var = 0
    print "Var = %d" % self.Var

    root = Tk()
    app = App(root)
    root.mainloop()

  3. Loop in a separate thread (similar to Tkinter variant) - I came up with this idea before finding other better solutions: if the loop is running in a separate thread then user still has access to the main program from keyboard and hence can control the loop too:
    import threading, time

    class LoopThread (threading.Thread):

    Value = 0
    Counts = 0

    def run(self):
    print 'Loop is started'
    while self.Value != 10:
    time.sleep(1)
    self.Counts = self.Counts + 1
    print 'Loop was ended, Counts %d' % self.Counts

    def getVal(self):
    return self.Value

    def setVal(self, Val):
    self.Value = Val

    # Create the object
    MyLoop = LoopThread()

    # Start the thread
    MyLoop.start()

    # Send the loop termination value from
    # the main program whenever you need
    time.sleep(11)
    MyLoop.setVal(10)
    A disadvantage of this approach is that the loop thread can not use the terminal window since the main program needs it for input from a user. If it is about logging information in the loop - then the info should be saved into a file, for example.
If you know any other solutions - please, share your experience.
Read more...

Sunday, November 8, 2009

Doorway Chin-Up Bar Modification

A sound mind in a sound body... Keeping it that way is a big job especially for those who spend most of the time working with computers, but I'm still kicking. About a year ago I bought a doorway chin-up bar which had some imperfections I found possible to fix.

The exact item I bought at Amazon.com is not in stock any more, but there are many other similar pull-up/chin-up bars available from different manufacturers. For instance:

or

They may come in different quality and price and it is difficult to suggest any particular one without trying. I usually rely on reasonable comments from other buyers. As a reference - I got my chin-up bar for about $40...45 and it has been working well for all the time.

To my point of view there are two main drawbacks in the construction of the most of these chin-up bars:

  1. They have relatively short and narrow plank which goes against the wall above door. With a body hanging and convulsing on the bar, the plank applies too big pressure to the wall and leaves marks. To resolve the issue it is necessary just to make the plank a little bit longer than width of doorway. Also in this case the plank will rest on three vertical wall studs, not just one: the first one is in the middle above door and other two - at doorway sides.

  2. For my height I'd like the chin-up bar sitting in the doorway as high as possible and it is feasible - it's just necessary to screw properly the plank (or "wall bar") to the rest of the chin-up bar assembly.
Just to illustrate the idea I have drawn the original and the modified chin-up bars:




For those who wonder: all the parts and assemblies were done in Alibre, a mechanical 3D CAD tool, and printed out into 3D PDF, so one can click the image and get 3D control over the part. Whole collection of the Alibre files for the assemblies can be taken from here.

While it is easier to do accurate mechanical drawing with a 3D CAD software, SketchUp is more convenient for quick modeling. I've uploaded the models to 3D Warehouse: the original bar, the modified one and comparison between the both chin-ups on doors.

In practice the task is pretty simple:
  1. Buy a piece of wood: width is about 1 cm smaller than the gap between top door casing and the ceiling, slightly longer than door horizontal dimension, and the same thickness as the original plank (in my case the new plank was 94cm x 14cm x 2cm).

  2. Position the new plank in the proper place above the door, temporarily secure it there, for example, with masking tape - do not let the wood fall on your head!

  3. Then position the chin-up bar assembly without the original plank - ask someone for help to hold it in place for a while. Mark the location of the mounting holes on the plank, then drill the holes: make them of "counter drill" type to hide screw head below the plank surface.

  4. Assemble the chin-up bar, add some soft material to the side of the plank which faces the wall to protect it even more (I put some thin packing foam material).
That is what worked for me. Total cost for the improvement was some time + 49 cents for the wood - what is incomparable to usefulness of the modification and the fun I had doing that.

One more thing - for doorway mount I really like this type of chip-up bars and would not recommend any other "simplified" versions. Amazon has some available of the right kind - you can look though the search results:


Read more...

Saturday, November 7, 2009

Zimbra - Perfect E-Mail Client for Perfect People

It is common to use a separate e-mail account for each separate activity: work, home, hobby, web subscriptions, etc.. So happened that some of accounts I have at Yahoo and others at Google.  Neither Yahoo nor Google allows simultaneous access to multiple accounts. So I've been thinking for a long time how convenient it would be to have alive connections to all my web e-mail accounts from one place at the same time. Another problem with Yahoo - no support for IMAP (they offer POP3 for $ Mail Plus, but I don't even want POP3). Now solution for both the issues is available - it is Zimbra Desktop.

An attempt to install zdesktop_1_0_3_build_1691_win32.exe failed with a strange error, so I installed previous zdesktop_1_0_build_1537_win32.exe then allowed it upgrading to version 1.0 build 1593 - flawless.

I registered all my Yahoo and Google accounts in Zimbra Desktop and tested them - result is remarkable:
  • All accounts are in simultaneous access as expected.
  • Working from Zimbra Desktop is the same as if it would be from the web-account - all changes applied in the Desktop are properly reflected on the web-account and vice-versa.
  • Somehow Zimbra has true IMAP access to Yahoo free accounts - it's probably become possible because Zimbra is actually Yahoo Zimbra.
  • Zimbra enables IMAP access to Google e-mail accounts and it works fine too.
  • Zimbra provides an access not only to inbox but to all existing folders in the account.
  •  It can work with many other types of accounts as Hotmail, AOL, POP3, IMAP, etc.:

  • Zimbra has many other features which I don't need yet but I'm considering them interesting for the future.
  • Available for Linux and Windows.
I tested it on Yahoo and Google accounts - Zimbra gives a transparent control over e-mails as if you would be really logged in the web-account. Amazing!



The only inconvenience I faced with Zimbra Desktop is that it relies on computer account security, but the issue is related not to the program itself but to a user perfection and I am apparently not such one. So if you have not established a separate password protected account for every member of your crew, your parrot and your wooden leg, then Zimbra Desktop can be started by someone with access to the computer and all your e-mail accounts will be exposed whether you like it or not. I personally didn't want to change the sin way what got settled on my desktop PC - that's why I simply installed Zimbra on a virtual machine with all passwords and I run it only for myself.

Potentially, in order to satisfy imperfect people as myself, the issue could be easily fixed by adding a "user logon to Zimbra" with loading a corresponding account profile... but probably that would be too much to expect from Zimbra developers: Zimbra Desktop is already a great useful program.

It should be said that Desktop is just one application among many what Zimbra offers. The main product is Zimbra Collaboration Suit. It comes with different flavors and prices from the free Open Source Edition to the Professional Edition - check out their web-site for details.
Read more...