Testimonial

Phil Schmidt pschmidt at omnimn.com
Wed Jan 22 14:31:56 CET 2003


> Out of curiosity, what did you end up doing for the "graphics" (text
> menus, etc)?  I'd like to do something similar and have it work for
> Windows (I don't think ncurses will work without Cygwin or something
> similar)
> 
> Shawn


Here's my basic "ui" module. Very simple, no windowing. I had to
comment out the line in getDate() with the time.strptime function, as
this won't run on Windows (which I'm on right now), but works fine on
Linux (which I have at home). I added the test section at the end as
an example for this post. Oh, and the normalDate module is from Vaults
of Parnassus.

The base_menu class as I've implemented it seems a bit clunky to me,
but it captures the functionality I wanted. I'll probably revisit it
some day, and try to give it some polish and better capability.

-------------------------------------------------------------
import string, os, time
import normalDate

DEFAULT_WIDTH = 78

def clrscr():
    """
    A screen clearing function.
    """
    if os.name == 'posix':
        os.system('clear')
    elif os.name == 'nt':
        os.system('cls')
    else:
        # guess!
        print('\n' * 25)

def header(text='=', pos='L', width=DEFAULT_WIDTH):
    """
    Prints a header string.
    pos may be 'L', 'C', or 'R' for left, center, right justify.
    If text is a single character, that character will be used
    to fill the width of the print field.
    """
    width -= 2
    if text == '':
        text = '='
    if len(text) == 1:
        print '|' + text * width + '|'
    else:
        pos = string.upper(pos)
        if pos == 'L':
            print '|' + string.ljust(text, width) + '|'
        elif pos == 'C':
            print '|' + string.center(text, width) + '|'
        elif pos == 'R':
            print '|' + string.rjust(text, width) + '|'
    
def get(prompt='', default=''):
    """
    A plain old input routine.
    """
    try:
        x = raw_input(prompt)
    except (KeyboardInterrupt):
        x = default
    if x == '':
        x = default
    return x

def getInt(prompt='Enter an integer', default=0):
    """
    Return an integer.
    """
    prompt += ' <%s> -->' % default
    try:
        return int(get(prompt, default))
    except ValueError:
        return default

def getString(prompt='Enter a string', default=''):
    """
    Return a string.
    """
    prompt += ' <%s> -->' % default
    return get(prompt, default)

def getYes(prompt='Yes or no?', default='n'):
    """
    Return 1 (yes) or 0 (no).
    """
    confirm = get(prompt + ' <Y/N> -->', default)
    if string.upper(confirm) == 'Y':
        return 1
    else:
        return 0

def getDate(prompt='Enter a date', default=''):
    """
    Return a date string.
    """
    if not default:
        default = time.strftime('%m/%d/%y')
    prompt += ' <' + default + '> -->'
    date = get(prompt, default)
    # the next line doesn't work on Windows. Works fine on Linux.
    # date = time.strftime('%Y%m%d', time.strptime(date, '%m/%d/%y'))
    return date
    
def getMonthYear(prompt='Enter a month & year mm/yy', default=''):
    """
    Return a date string.
    """
    if not default:
        default = time.strftime('%m/%y')
    prompt += ' <' + default + '> -->'
    date = get(prompt, default)
    date = time.strftime('%Y%m', time.strptime(date, '%m/%y'))
    return date

def getDollars(prompt='Enter a dollar amount', default='0.00'):
    """
    Return a dollar amount (float).
    """
    prompt += ' <%s> -->' % default
    dollars = float(get(prompt, default))
    return dollars

class base_menu:
    """
    This class is the base for other menus.
    """
    def __init__(self, menu):
        self.menu = menu
        self.prompt = 'Enter Command --> '
    def ShowHeader(self):
        clrscr()
        header("*", 'C')
        header(' ', 'C')
        header("Phil's Not-So-Simple Python Accountant", 'C')
        header(' ', 'C')
        header("*", 'C')
    def ShowSubHeader(self):
        pass
    def ShowMenu(self):
        print
        for m in self.menu:
            print m[1]
        print
    def ShowAll(self):
        self.ShowHeader()
        self.ShowSubHeader()
        self.ShowMenu()
    def GetInput(self):
        return string.upper(get(self.prompt))
    def ExecuteCmd(self, cmd, loop = 1):
        for m in self.menu:
            if m[0] == cmd:
                return m[2]()
        return loop
    def ExecutePreCmd(self):
        # this is to be overridden when needed
        pass
    def __call__(self, loop = 1):
        # when the menu instance is called, display and execute the
menu
        # if loop is nonzero, the menu will loop until exited by user
        while loop:
            self.ShowAll()
            self.ExecutePreCmd()
            loop = self.ExecuteCmd(self.GetInput(), loop)
        return 1
    def Exit(self):
        # basic menu quit function
        return 0

class ND(normalDate.NormalDate):
    def addmonth(self, months):
	offset = self.month() - 1 + months
	month = (offset % 12) + 1
	year = self.year() + (offset / 12)
	self.setMonth(month)
	self.setYear(year)


if __name__ == '__main__':
    class transactions_menu(base_menu):
        def __init__(self):
            menu = (
                ('T','<T>ransfer',self.Transfer),
                ('Q','<Q>uit this menu',self.Exit)
                )
            base_menu.__init__(self, menu)
        def ShowSubHeader(self):
            header('Transactions')
            header()
            #ledger.ShowAccounts()
        def Transfer(self):
            src = getInt('   Enter source account ID: ')
            dest = getInt('   Enter destination account ID: ')
            amount = getDollars('   Enter amount to transfer: ')
            date = getDate('   Transaction date')
            print
            print '    Transfer: %f' % amount
            print 'From account: #%i - %s' % (src, 'dummy_src') 
#(src, ledger.ledger[src][NAME])
            print '  To account: #%i - %s' % (dest, 'dummy_dest')
#(dest, ledger.ledger[dest][NAME])
            print '   Effective: %s' % date
            print
            if getYes('Is this correct?'):
                #ledger.Transfer(dest, src, amount, date)
                pass
            return 1

    class main_menu(base_menu):
        def __init__(self):
            menu = (
                ('T','<T>ransactions',transactions_menu()),
                ('R','<R>eports',self.Reports),
                ('!','<!> Quit Accountant',self.Quit)
                )
            base_menu.__init__(self, menu)
        def ShowSubHeader(self):
            #ledger.ShowAccounts()
            pass
        def Quit(self):
            print
            if getYes('Are you sure you want to quit?'):
                return 0
            else:
                return 1
        def Reports(self):
            print 'nothing here right now'
            get('press enter...')
            return 1


    main_menu()()




More information about the Python-list mailing list