Thread: code reuse?

Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    88
    Rep Power
    10

    code reuse?


    I recently showed some of my code to a friend of the following program:
    Code:
    #Periodic Python project started Feb. 10, 2005
    #Visit me on the web @ http://www.ionicdomain.com
    import os
    print "Welcome to Periodic Python"
    print "Version 0.01"
    print "~~~~~~~~~~~"
    
    class PerTbl:
    	def addelement(self):
    		element = raw_input("What is the name of this element? ")
    		pernum = raw_input("What is its atomic number? ")
    		atmwei = raw_input("What is its atomic weight? ")
    		prioxinum = raw_input("What is its primary oxidation number? ")
    		symbol = raw_input("What is its symbol?[No Caps] ")
    		sto = open("C:/Program Files/PP/Elements/"+symbol+".txt",'w')
    		sto.write(element+"/n")
    		sto = open("C:/Program Files/PP/Elements/"+symbol+".txt",'a')
    		sto.write(pernum+"/n")
    		sto.write(atmwei+"/n")
    		sto.write(prioxinum+"/n")
    		sto.write(symbol+"/n")
    		sto.close()
    	def searchelement(self):
    		query = raw_input("Please enter the atomic symbol of the element you which to get information on ")
    		search = "/"+query+".txt"
    		dir = os.getcwd()
    		if search in dir:
    			search = open(search,'r')
    			info = search.readlines()
    			print info
    			search.close()
    		else:
    			print "I'm sorry, that element is not in our database currently"
    running = 1
    while running == 1:	
    	rc = 0
    	while rc == 0:
    		print "What would you like to do?"
    		print "1- Get Info on an element"
    		print "2- Add an element"
    		print "3- Exit"
    		choice = raw_input("> ")
    		rc = 1
    	if choice == "1":
    		per = PerTbl()
    		per.searchelement()
    	elif choice == "2":
                    per = PerTbl()
    		per.addelement()
    	elif choice == "3":
    		running = 0
    	else:
    		rc = 0
    He said it was horrible OOP because it didn't reuse code or inherit objects. What does all that mean??? I thought an object was just a grouping of functions.
    He also said something about having objects as elements, what was that all about?

    Comments on this post

    • SimonGreenhill agrees
  2. #2
  3. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    One of the main advantages to OOP is that it is supposed to improve code reuse however people tend to go overboard. I don't believe every class you write should be reusable since it isn't always necessary, especially with small programs: complicating things seems pointless to say the least .

    Now if you found yourself doing the same kind of thing a lot asking the user for input and adding it to a file store you might want to write a more generalized Storage class and subclass this from PerTbl.

    This would make the functionality of the storage class available from instances of PerTbl (and any other subclasses). This is a very powerful idea but that doesn't mean you have to go class crazy .

    Note: that you can use './' to signify the current working directory in your program. This means that you wont have to call os.getcwd() .

    Take care,

    Mark.

    Comments on this post

    • burninator disagrees : The best brief description of 'object' I have ever read. Beautiful and to the point.
    • SimonGreenhill agrees
    programming language development: www.netytan.com Hula

  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    88
    Rep Power
    10
    Thanks for all that, I appreciate it.
    One thing though, can you elaborate on this:
    Now if you found yourself doing the same kind of thing a lot asking the user for input and adding it to a file store you might want to write a more generalized Storage class and subclass this from PerTbl.
    Also, give me a rough example of how I would put that into the code?
    Thanks.
  6. #4
  7. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    Here you go .

    Code:
    >>> import os
    >>> os.getcwd()
    '/Users/Mark'
    >>> os.listdir(os.getcwd())
    ['.bash_history', '.CFUserTextEncoding', '.DS_Store', '.fonts.cache-1', '.gaim', '.gimp-2.2', '.java', '.lpoptions', '.profile', '.ssh', '.Trash', '.viminfo', '.Xauthority', 'Desktop', 'Documents', 'Downloads', 'Library', 'Movies', 'Music', 'Pictures', 'Projects', 'Public', 'Sites']
    >>> os.listdir('./')
    ['.bash_history', '.CFUserTextEncoding', '.DS_Store', '.fonts.cache-1', '.gaim', '.gimp-2.2', '.java', '.lpoptions', '.profile', '.ssh', '.Trash', '.viminfo', '.Xauthority', 'Desktop', 'Documents', 'Downloads', 'Library', 'Movies', 'Music', 'Pictures', 'Projects', 'Public', 'Sites']
    >>>
    Mark.
    programming language development: www.netytan.com Hula

  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    88
    Rep Power
    10
    Thanks, one final thing:
    What is this "__main__" and "__self" stuff I'll see in the code of OOP programs. I've never found out what they mean, and they bug me.
  10. #6
  11. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    In classes the self variable refers to the classes instance. The if __name__ == "__main__" statement that you often see in programs is useful for self testing, basically your checking if the program is running. So anything inside this block will only run when the program runs; not when it's imported

    Mark.
    programming language development: www.netytan.com Hula

  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Posts
    624
    Rep Power
    34
    Originally Posted by pylon
    I recently showed some of my code to a friend of the following program:

    He said it was horrible OOP because it didn't reuse code or inherit objects.
    I'd agree that it's not good OOP, but not for those reasons. I can't see any use for inheritance in a program that simple.

    That said, I can't see any reason for making PerTbl a class either, from what you've done, which is why it's not (IMHO) good OOP.

    What does all that mean??? I thought an object was just a grouping of functions.
    Nope. If you take away your PerTbl class it will behave exactly the same way.

    An object is

    - some data
    - some functions that change and query that data
    - all grouped together because they make sense when grouped together.

    Thus you might have created a class of 'Element', with the data being:

    - atomic_weight
    - atomic_number
    - symbol
    - boiling_point_kelvins
    - melting_point_kelvins

    And methods to work with that data such as:
    - get_atomic_weight_in_kilos
    - get_atomic_weight_in_electronVolts
    - get_next_heavier_element
    - get_boiling_point_in_celcius
    and so on.

    All the sorts of things that you might do with or to an element.

    Right.

    This means, you can create multiple elements from your class:

    Code:
    lead = Element()
    lead.symbol = 'pb'
    
    antimony = Element()
    antimony.symbol = 'sb'
    OK so far? Because this doesn't seem to add anything to your code, does it?

    But now you can build on that structure to do all sorts of interesting things:

    You could define comparison functions to sort Elements in order of their atomic weight.

    You could make a class RadioActiveElement which inherits from Element, and also adds details about radioactive half-life and so on. Yet it could also be sorted by atomic-weight, because it's based on 'Element', and gets that ability for free.

    You could define a new class Compound which is made from two Elements, then add calculations about combining the two.

    Elements could be pickled and sent over a network, then unpickled into an Element class on the other side (if it had the right module), which you couldn't do now.

    You could build it into a module, and then do:
    from chemistry import Element

    and import everything to do with Elements in one go because it's all neatly encapsulated (Which you couldn't do at the moment).

    Comments on this post

    • SimonGreenhill agrees
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    88
    Rep Power
    10
    Any comments on this:
    Code:
    #Created by Pinko (C) 2005
    #Project Started March 30th, 2005
    #http://www.ionicdomain.com
    
    class element:
        def ename(ename,number,symbol,weight,velectrons):
            if "./element/"+ename+".txt" in "./element":
                print "That element is already in our database, if you continue, you will overwrite its current data."
                continuenow = raw_input("Do you want to continue? y/n")
                if continuenow =="y":
                        continuenow = 1
                else:
                        continuenow =0
            else:
                continuenow = 1
            while continuenow == 1:
                file=open("./element/"+ename+".txt",'w')
                file.write(ename+"\n")
                file.close
                file=open("./element/"+ename+".txt",'a')
                file.write(number+"\n"+symbol+"\n"+weight+"\n"+velectrons)
                file.close
                continuenow =0
    e=element()
    running = 1
    while running == 1:	
    	rc = 0
    	while rc == 0:
                print "What would you like to do?"
                print "1- Get Info on an element"
                print "2- Add an element"
                print "3- Exit"
                choice = raw_input("> ")
                rc = 1
                if choice == "1":
                    print ""
                elif choice == "2":
                    ename=raw_input("What is this elements name? ")
                    number=raw_input("What is its atomic number? ")
                    symbol=raw_input("What is its symbol? ")
                    weight=raw_input("What is its atomic weight? ")
                    velectrons=raw_input("How many valence electrons does it have? ")
                    e.ename(ename,number,symbol,weight,velectrons)
                    print "Success!"
                elif choice == "3":
                        running = 0
                else:
                        rc = 0
    I've tried running it, but it fails horribly, it doesn't write the file and nothing really works.
    But, is that the concept you're trying to get me to grasp?
  16. #9
  17. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    Not so much, there is a lot of looping in there for no real reason and there's even less point in making this a class now since there's only one method you might as well make this a function .

    You should also note that files are written to the current working directory so unless you change this you don't need to put ./ before your file names. Also not seeing the search function that you had before.

    Take care,

    Mark.
    programming language development: www.netytan.com Hula

  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2005
    Posts
    78
    Rep Power
    10
    I'd like to highlight some misfeatures in one section of the original code (it's still effectively there in the revised code) - this has nothing to do with objects, just flow control:
    Code:
    while running == 1:	
    	rc = 0
    	while rc == 0:
    		print "What would you like to do?"
    		print "1- Get Info on an element"
    		print "2- Add an element"
    		print "3- Exit"
    		choice = raw_input("> ")
    		rc = 1
    	if choice == "1":
    		per = PerTbl()
    		per.searchelement()
    	elif choice == "2":
                    per = PerTbl()
    		per.addelement()
    	elif choice == "3":
    		running = 0
    	else:
    		rc = 0
    Don't use tabs. They will cause you pain. Use four spaces per indent. If your editor doesn't handle automatic tab-key to space conversion, change your editor. Python comes with IDLE, but there are many free alternatives.

    Flags (ie: "running = 0" and "rc = 0" are almost always the wrong thing to be using). If you think you need a flag, what you probably need to do is to redesign your code.

    Hokay...
    Code:
    while running == 1:
    The use of that is poor, but any truth test like this may be written as the following for a true value:
    Code:
    while running:
    or the following for a false value:
    Code:
    while not rc:
    You can use "break" to break out of a loop. Both flags are thus unnecessary:
    Code:
    per = PerTbl()                         # Only created once!
    while True:
        print "What would you like to do?"
        print "1- Get Info on an element"
        print "2- Add an element"
        print "3- Exit"
        choice = raw_input("> ")
        if choice == "3":
            break
        elif choice == "1":
            per.searchelement()
        elif choice == "2":
            per.addelement()
    --OH.

    Comments on this post

    • SimonGreenhill agrees
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    88
    Rep Power
    10
    Data:
    - atomic_weight
    - atomic_number
    - symbol
    - boiling_point_kelvins
    - melting_point_kelvins

    And methods to work with that data such as:
    - get_atomic_weight_in_kilos
    - get_atomic_weight_in_electronVolts
    - get_next_heavier_element
    - get_boiling_point_in_celcius
    and so on.
    Ok, how would I go about doing that, because thats what I was looking for, but I don't know how to put it into code?
    Thanks, Hydroxide for your tips, I'll implement them from now on.
    However, why doesn't the latest code I gave out save any files?
  22. #12
  23. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Posts
    624
    Rep Power
    34
    However, why doesn't the latest code I gave out save any files?
    I get a bunch of errors when trying to use it:

    First that

    element.ename requires 5 parameters, but 6 are passed to it - you haven't made room for 'self', and it crashes. Which means if it did work, the first parameter passed to the method to arrive as 'ename' is Python's internal representation of the object. Which is also probably why you can't make a file called that - because 'ename' isn't what you expect it to be.

    Also

    Code:
    open("./file.txt")
    Isn't valid - dot slash means nothing to Python on Windows as a directory name. Just use "file.txt" to mean "the current directory".

    And that you have inconsistant indentation in your while rc == 0: loop. The while line is indented with a tab, then the following line is indented with 12 spaces, etc.

    Just for emphasis:

    Flags (ie: "running = 0" and "rc = 0" are almost always the wrong thing to be using). If you think you need a flag, what you probably need to do is to redesign your code.
    Ok, how would I go about doing that, because thats what I was looking for, but I don't know how to put it into code?
    I'll have to come back to this...
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    88
    Rep Power
    10
    Ok, I did what you suggested with replacing "./" with "/"
    and the result:
    file=open("/element/"+ename+".txt",'w')
    IOError: [Errno 2] No such file or directory: '/element/Hydrogen.txt'
    Something's awry.
    I thought if you wanted to create a new file/folder, you could just tell it to write to that directory/file and it would create it if it didn't already exist.
    Originally Posted by sfb
    I'll have to come back to this...
    You don't have to rush it, its not like it'll be the end of the world if I don't get it, but I'd like to see a simple example sometime
    I also took care of the 'self' problem.
    Also, one more of those __ thingys, what's __init__ ?
  26. #14
  27. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2005
    Posts
    78
    Rep Power
    10
    Originally Posted by pylon
    Ok, how would I go about doing that, because thats what I was looking for, but I don't know how to put it into code?
    Thanks, Hydroxide for your tips, I'll implement them from now on.
    However, why doesn't the latest code I gave out save any files?
    Ok....
    Think about about it this way:
    You have a periodic table which stores a bunch of elements.

    Each element has a bunch of data associated with it, and some functions to operate on that data.

    The periodic table has some functions which operate on elements - creating, loading, saving, and locating.

    For some things, responsbilities might be split. For instance the element might have a function to return a set of data for priinting, while the periodic table might have a function to print that data. There's often a few reasonable ways to design. For instance a lot of people would choose to use a weight_in_ev() method on the element (which is a perfectly valid way of doing things). I would probably use a Weight class, because I like the aesthetics of:
    Code:
    myelem.weight.to_ev()
    myelem.weight.to_k()
    What you should do is write out in detail which data and behaviours belong in Element, and which in PerTbl, and then tell us...

    --OH.
  28. #15
  29. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    88
    Rep Power
    10
    I'm sorry for the confusion, but I made element as an updated version of PerTbl, which was stupid because I didn't say that.
    I want element to contain: the element's name, atomic number, weight, symbol, valence electrons, oxidation number(s), and whether or not it is radioactive
    However, I was very interested in this:
    Code:
    lead = Element()
    lead.symbol = 'pb'
    
    antimony = Element()
    antimony.symbol = 'sb'
    And I was wondering how I could implement that into my program. Also, I'm not sure if this belongs in the same class but, i'll need a way to search for elements.
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo