[Tutor] OOPs?
Kirby Urner
urnerk@qwest.net
Sat, 30 Mar 2002 16:34:01 -0800
>
>#!/usr/bin/python
>
>import time, shelve
>
>class Stock:
> "Simple stock class, keeps history using current time"
>
> # the constructor defines some attributes of the instance
> def __init__(self, code, price, datetime):
> self.code = code
>
> # the history is a dictionary that tracks the instance's
Actually, history is just a simple list [], containing
(price, datetime) tuples () -- not a dictionary {}.
> # prices and the datetimes of those prices
> self.history = [(price, datetime)]
> self.price = price
>
> # the newprice() method adds a new price/datetime to the
> # instance's history dictionary
history *list* -- I won't keep saying it, now that you've
got it.
> def newprice(self, price, datetime):
> self.history.append((price, datetime))
>
> # the showhist() method prints the history of the instance
> # (a dictionary)
> def showhist(self):
> return self.history
>
>def getcode():
> "Handle cases where user inputs code we don't have"
>
> # accept a stock code
> code = raw_input("Code? > ")
>
> # check to see if stock code is in the dictionary
> try:
> stockobj = stockdict[code]
> # if it can't be done, print an error message and exit
> except:
> print "Not a legal code"
> return 0
Another way of doing this is stockobj = stockdict.get(code,0)
-- would have to rewrite the calling function a tiny bit.
This latter syntax becomes an option only in version 2,
where I substituted a real dictionary for the shelve file
pseudo-dictionary.
> # if it is, return the object represented by the 'stockdict[code]'
> # element of the dictionary that keeps track of stock objects by code
> return stockobj
>
>def addstock():
> "Add new stock, any code acceptable"
>
> # accept a stock code
> code = raw_input("Code? > ")
> # accept a price
> price = raw_input("Price? > ")
> # assign an instance of the Stock class to 'stockdict[code]'
> stockdict[code] = Stock(code, price, time, asctime())
More error check could go here, if you wanted to guard
the price from being assigned some nonsense.
>def update():
> # assign to 'obj' an instance of the Stock class from getcode()
> obj = getcode()
>
> # if a Stock class instance was pulled and assigned to 'obj'
> if obj:
Actually, not that I look at it,
stockobj = stockdict.get(code,0)
in getcode (without a try block) wouldn't require any
rewrite. In other words, getcode could be:
def getcode():
"Handle cases where user inputs code we don't have"
code = raw_input("Code? > ")
stockobj = stockdict.get(code,0)
return stockobj
> # accept a price
> price = raw_input("Price? > ")
> # call the newprice() method of the instance
> obj.newprice(price, time.asctime())
> # print the number of items in the instance's history
> dictionary
> print "%s prices on file" % len(obj.history)
> # would not have to do next step if using real dictionary
> stockdict[obj.code] = obj # overwrites old copy
OK, so you're using the older version. In the revamp, stockdict
becomes a real dictionary {}, with the shelve construct
only being used at the start and end of mainloop, to read
from and write to disk.
>def dumphist():
> # assign to 'obj' an instance of the Stock class from getcode()
> obj = getcode()
> # if a Stock class instance was pulled and assigned to 'obj'
> if obj:
> # call the 'showhist()' method of the Stock instance 'obj',
> # and assign it to the 'hist' variable
> hist = obj.showhist()
> # print the value of the 'hist' variable
> print hist
I also made this prettier. Here's the up to date
version of this tutorial code:
http://www.inetarena.com/~pdx4d/ocn/python/stocks.py
>def quit():
> # call the close() method of the stockdict object
> stockdict.close()
> print "Stocks saved"
>
>def mainmenu():
> "Using dictionary-like syntax to do file i/o"
>
> # globalize the stockdict name
> global stockdict
> # create a 'stockdict' object and give it the current value
> # of 'shelve.open("mystocks")'
> stockdict = shelve.open("mystocks")
> # create a tuple called 'callables'
> callables = [quit, addstock, update, dumphist]
> # display the menu
No, wait, you *are* using the more recent. OK, well then
update() could be simpler -- check link. I see I failed to
simplify it in my post to this list.
> while 1:
> print \
> """
> (1) add new stock
> (2) update price of stock
> (3) dump history of stock
> (0) save/quit
> """
>
> # accept a selection
> sel = raw_input("Your choice: > ")
> try:
> # make sel an integer
> sel = int(sel)
Note that this will fail if the user type in 'a' or something
that can't convert to int.
> # test that sel is less than or equal to 3
> # and greater than or equal to 0
But if it passes this first test then....
> assert int(sel) <= 3 and int(sel) >= 0
> # call whichever function is represented by sel
> callables[int(sel)]()
> if int(sel) == 0:
> break
> # if the try fails
> except:
> print "Not a legal choice"
Looks like you understand quite well.
Thanks for sharing your comments.
Kirby