Section 13.18. Exercises


13.18. Exercises

13-1.

Programming. Name some benefits of object-oriented programming over older forms of programming.

13-2.

Functions versus Methods. What are the differences between functions and methods?

13-3.

Customizing Classes. Create a class to format floating point values to monetary amounts. In this exercise, we will use United States currency, but feel free to implement your own.

Preliminary work: Create a function called dollarize() which takes a floating point value and returns that value as a string properly formatted with symbols and rounded to obtain a financial amount. For example: dollarize(1234567.8901) '$1,234,567.89. The dollarize() function should allow for commas, such as 1,000,000, and dollar signs. Any negative sign should appear to the The MoneyFmt class contains a single data value, the monetary amount, and has five methods (feel free to create your own outside of this exercise). The __init__() constructor method initializes the data value, the update() method replaces the data value with a new one, the __nonzero__() method is Boolean, returning true if the data value is non-zero, the __repr__() method returns the amount as a float, and the __str__() method displays the value in the string-formatted manner that dollarize() does.

  1. Fill in the code to the update() method so that it will update the data value.

  2. Use the work you completed for dollarize() to fill in the code for the __str__() method.

  3. Fix the bug in the __nonzero__() method, which currently thinks that any value less than one, i.e., fifty cents ($0.50), has a false value.

  4. Extra credit: Allow the user to optionally specify an argument indicating the desire to see less-than and greater-than pairs for negative values rather than the negative sign. The default argument should use the standard negative sign.

You will find the code skeleton for moneyfmt.py presented as Example 13.11. You will find a fully documented (yet incomplete) version of moneyfmt.py on the Web site. If we were to import the completed class within the interpreter, execution should behave similar to the following:

Example 13.11. Money Formatter (moneyFmt.py)

String format class designed to "wrap" floating point values to appear as monetary amounts with the appropriate symbols.

1  #!/usr/bin/env python 2 3  class MoneyFmt(object): 4     def __init__(self, value=0.0)  :   # constructor 5         self.value = float(value) 6 7     def update(self, value=None):  # allow updates 8         ### 9         ### (a) complete this function 10        ### 11 12    def __repr__(self):    # display as a float 13        return 'self.value' 14 15    def __str__(self):     # formatted display 16        val = '' 17 18        ### 19        ### (b) complete this function... do NOT 20        ###     forget about negative numbers!! 21        ### 22 23        return val 24 25    def __nonzero__(self):         # boolean test 26        ### 27        ### (c) find and fix the bug 28        ### 29 30        return int(self.value)

    >>> import moneyfmt     >>>     >>> cash = moneyfmt.MoneyFmt(123.45)     >>> cash     123.45     >>> print cash     $123.45     >>>     >>> cash.update(100000.4567)     >>> cash     100000.4567     >>> print cash     $100,000.46     >>>     >>> cash.update(-0.3)     >>> cash     -0.3     >>> print cash     -$0.30     >>> repr(cash)     '-0.3'     >>> 'cash'     '-0.3'     >>> str(cash)     '-$0.30'


13-4.

User Registration. Create a user database (login, password, and last login timestamp) class (see problems 7-5 and 9-12) that manages a system requiring users to log in before access to resources is allowed. This database class manages its users, loading any previously saved user information on instantiation and providing accessor functions to add or update database information. If updated, the database will save the new information to disk as part of its deallocation (see __del__()).

13-5.

Geometry. Create a Point class that consists of an ordered pair (x, y) representing a point's location on the X and Y axes. X and Y coordinates are passed to the constructor on instantiation and default to the origin for any missing coordinate.

13-6.

Geometry. Create a line/line segment class that has length and slope behaviors in addition to the main data attributes: a pair of points (see previous problem). You should override the __repr__() method (and __str__(), if you want) so that the string representing a line (or line segment) is a pair of tuples, ((x1, y1), (x2, y2)). Summary:

__repr__

Display points as pair of tuples

length

Return length of line segmentdo not use "len" since that is supposed to be an integer

slope

Return slope of line segment (or None if applicable)


13-7.

Date Class. Provide an interface to a time module where users can request dates in a few (given) date formats such as "MM/DD/YY," "MM/DD/YYYY," "DD/MM/YY," "DD/MM/ YYYY," "Mon DD, YYYY," or the standard Unix date of "Day Mon DD, HH:MM:SS YYYY." Your class should maintain a single value of date and create an instance with the given time. If not given, default to the current time at execution. Additional methods:

update()

changes the data value to reflect time given or current time as a default

display()

takes format indicator and displays date in requested format:


    'MDY'  MM/DD/YY     'MDYY'  MM/DD/YYYY     'DMY'  DD/MM/YY     'DMYY'  DD/MM/YYYY     'MODYY'  Mon DD, YYYY


If no format is given, default to system/ctime() format. Extra Credit: Merge the use of this class into Exercise 6-15.

13-8.

Stack Class. A stack is a data structure with last-in-first-out (LIFO) characteristics. Think of a stack of cafeteria trays. The first one in the spring-loaded device is the last one out, and the last one in is the first one out. Your class will have the expected push() (add an item to the stack) and pop() (remove an item from the stack) methods. Add an isempty() Boolean method that returns TRue if the stack is empty and False otherwise, and a peek() method that returns the item at the top of the stack without popping it off.

Note that if you are using a list to implement your stacks, the pop() method is already available as of Python 1.5.2. Create your new class so that it contains code to detect if the pop() method is available. If so, call the built-in one; otherwise, it should execute your implementation of pop(). You should probably use a list object; if you do, do not worry about implementing any list functionality (i.e., slicing). Just make sure that your Stack class can perform both of the operations above correctly. You may subclass a real list object or come up with your own list-like object, as in Example 6.2.

13-9.

Queue Class. A queue is a data structure that has first-in-first-out (FIFO) characteristics. A queue is like a line where items are removed from the front and added to the rear. The class should support the following methods:

enqueue()

adds a new element to the end of a list

dequeue()

returns the first element and removes it from the list.


See the previous problem and Example 6.3 for motivation.

13-10.

Stacks and Queues. Write a class which defines a data structure that can behave as both a queue (FIFO) or a stack (LIFO), somewhat similar in nature to arrays in PERL. There are four methods that should be implemented:

shift()

returns the first element and removes it from the list, similar to the earlier dequeue() function

unshift()

"pushes" a new element to the front or head of the list

push()

adds a new element to the end of a list, similar to the enqueue() and push() methods from previous problems

pop()

returns the last element and removes it from the list; it works exactly the same way as pop() from before


See also Exercises 13-8 and 13-9.

13-11.

Electronic Commerce. You need to create the foundations of an e-commerce engine for a B2C (business-to-consumer) retailer. You need to have a class for a customer called User, a class for items in inventory called Item, and a shopping cart class called Cart. Items go in Carts, and Users can have multiple Carts. Also, multiple items can go into Carts, including more than one of any single item.

13-12.

Chat Rooms. You have been pretty disappointed at the current quality of chat room applications and vow to create your own, start up a new Internet company, obtain venture capital funding, integrate advertisement into your chat program, quintuple revenues in a six-month period, go public, and retire. However, none of this will happen if you do not have a pretty cool chat application.

There are three classes you will need: a Message class containing a message string and any additional information such as broadcast or single recipient, and a User class that contains all the information for a person entering your chat rooms. To really wow the VCs to get your start-up capital, you add a class Room that represents a more sophisticated chat system where users can create separate "rooms" within the chat area and invite others to join. Extra credit: Develop graphical user interface (GUI) applications for the users.

13-13.

Stock Portfolio Class. For each company, your database tracks the name, ticker symbol, purchase date, purchase price, and number of shares. Methods include: add new symbol (new purchase), remove symbol (all shares sold), and YTD or Annual Return performance for any or all symbols given a current price (and date). See also Exercise 7-6.

13-14.

DOS. Write a Unix interface shell for DOS machines. You present the user a command line where he or she can type in Unix commands, and you interpret them and output accordingly, i.e., the "ls" command calls "dir" to give a list of filenames in a directory, "more" uses the same command (paginating through a text file), "cat" calls "type," "cp" calls "copy," "mv" calls "ren," and "rm" invokes "del," etc.

13-15.

Delegation. In our final comments regarding the CapOpen class of Example 13.8 where we proved that our class wrote out the data successfully, we noted that we could use either CapOpen() or open() to read the file text. Why? Would anything change if we used one or the other?

13-16.

Delegation and Functional Programming.

  1. Implement a writelines() method for the CapOpen class of Example 13.8. Your new function will take a list of lines and write them out converted to uppercase, similar to the way the regular writelines() method differs from write(). Note that once you are done, writelines() is no longer "delegated" to the file object.

  2. Add an argument to the writelines() method that determines whether a NEWLINE should be added to every line of the list. This argument should default to a value of False for no NEWLINEs.

13-17.

Subclassing Numeric Types. Take your final moneyfmt.py script as seen in Example 13.3 as Example 13.8 and recast it so that it extends Python's float type. Be sure all operations are supported, but that it is still immutable.

13-18.

Subclassing Sequence Types. Create a subclass similar to your solution of the previous problem to your user registration class as seen earlier in Exercise 13-4. Allow users to change their passwords, but do not allow them to reuse the same password within a 12-month period. Extra credit: Add support for determining "similar passwords" (any algorithm is fine) and do not even allow passwords similar to any used within the last 12 months.

13-19.

Subclassing Mapping Types. As speculated for the dictionary subclass in Section 13.11.3, what if the keys() method were (re)written as:

def keys(self):     return sorted(self.keys())


  1. What happens when keys() is called for a method?

  2. Why is this, and what makes our original solution work?

13-20.

Class Customization. Improve on the time60.py script as seen in Section 13.13.2, Example 13.3.

  1. Allow "empty" instantiation: If hours and minutes are not passed in, then default to zero hours and zero minutes.

  2. Zero-fill values to two digits because the current formatting is undesirable. In the case below, displaying wed should output "12:05."

    >>> wed = Time60(12, 5) >>> wed 12:5

  3. In addition to instantiating with hours (HR) and minutes (min), also support time entered as:

    • A tuple of hours and minutes (10, 30)

    • A dictionary of hours and minutes ({'HR' : 10, 'min': 30})

    • A string representing hours and minutes ("10:30") Extra Credit: Allow for improperly formatted strings like "12:5" as well.

  4. Do we need to implement __radd__()? Why or why not? If not, when would or should we override it?

  5. The implementation of __repr__() is flawed and misguided. We only overrode this function so that it displays nicely in the interactive interpreter without having to use the print statement. However, this breaks the charter that repr() should always give a (valid) string representation of an evaluatable Python expression. 12:05 is not a valid Python expression, but Time60('12:05') is. Make it so.

  6. Add support for sexagesimal (base 60) operations. The output for the following example should be 19:15 not 18:75:

    >>> thu = Time60(10, 30) >>> fri = Time60(8, 45) >>> thu + fri 18:75

13-21.

Decorators and Function Call Syntax. Toward the end of Section 13.16.4, we used a function decorator to turn x into a property object, but because decorators were not available until Python 2.4, we gave an alternate syntax for older releases:

X = property (**x()).


Exactly what happens when this assignment is executed, and why is it equivalent to using a decorator?



Core Python Programming
Core Python Programming (2nd Edition)
ISBN: 0132269937
EAN: 2147483647
Year: 2004
Pages: 334
Authors: Wesley J Chun

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net