Re: help with my first use of a class
Fulvio a écrit : *** Your mail has been scanned by InterScan MSS. *** On Saturday 21 October 2006 02:01, James Stroud wrote: I think the trick is to identify when a class would make more sense than a collection of subroutines I do believe that's a bit of forecasting, in sense to determine whether a piece of code may have a future. Usually in hobbistic term I think we can bear with copypasting pieces of code across programs rather than go for a class(es) module. OO and reuse are two orthogonal concerns. You don't need OO to reuse code, and OO is not so much about code reuse - even if it can improve reusability - than about how to best structure your code. To illustrate James' POV, if you end up with half a dozen functions working on a same well-defined data structure, then it might be time to 'integrate' these functions and the data structure into a class. Some other hints are when you have a small set of functions depending on a common set of globals, or when you find yourself adding to your functions signature too much additional params that are only meant to be passed to other functions that themselves will pass them etc... Copy-paste reuse should IMHO be limited to very trivial helper functions that are not worth the pain of dependencies management... My 2 cents -- http://mail.python.org/mailman/listinfo/python-list
Re: help with my first use of a class
*** Your mail has been scanned by InterScan MSS. *** On Saturday 21 October 2006 02:01, James Stroud wrote: I think the trick is to identify when a class would make more sense than a collection of subroutines I do believe that's a bit of forecasting, in sense to determine whether a piece of code may have a future. Usually in hobbistic term I think we can bear with copypasting pieces of code across programs rather than go for a class(es) module. Only I remembered the mottos when I ran this,py which gives me some good points of view. F -- http://mail.python.org/mailman/listinfo/python-list
help with my first use of a class
I am a mere hobbyist. Spent several hours trying to make a class, because I think this is an occasion where I need one. But I can't make it work. This code works (only because of the global c, which I know I'm supposed to avoid, by using a Class). I edited the rest to leave out the irrelevant formatting and printing of the quotations. I've read about Classes several times, but I don't get them yet. Obviously. If I can solve one real life problem like this, then maybe I'll see the light. If I understand the power of Classes correctly, I could make one that would allow me to make a new instance that would connect to, say, an SQLite3 db instead of the Access db, as well as to create more methods that will do different SQL searches. Thank you for any help, rd -- import mx.ODBC.Windows as odbc import sys import random def connect(): global c db='DSN=Quotations' conn = odbc.DriverConnect(db) c = conn.cursor() def random_quote(): Counts all of the quotes in MS Access database Quotations2005.mdb. Picks one quote at random and displays it using textwrap. c.execute (SELECT COUNT(Quote) FROM PythonQuoteQuery) # Yields the number of rows with something in the quote field total_quotes = c.fetchone() # Get a random number somewhere between 1 and the number of total quotes quote_number = (random.randint(1, total_quotes[0]),) # Select a quote where the ID matches that number c.execute (SELECT Author, Quote FROM PythonQuoteQuery WHERE ID=?, quote_number) quote = c.fetchone() blah blah blah def print_quote() code to format and print the quote (which will also have to be global, unless I learn Classes!) if __name__ == '__main__': if len(sys.argv) == 1: connect() random_quote() print_quote() -- http://mail.python.org/mailman/listinfo/python-list
Re: help with my first use of a class
Whoah. At least I got the connection. I think. Maybe I can figure more on my own. Any help appreciated. Thanks - class Connection: def __init__(self, aDatasource): self.db = aDatasource self.conn = odbc.DriverConnect(self.db) self.conn.cursor() def random_quote(): Counts all of the quotes in MS Access database Quotations2005.mdb. Picks one quote at random and displays it using textwrap. c = Connection('DSN=Quotations') c.execute (SELECT COUNT(Quote) FROM PythonQuoteQuery) -- http://mail.python.org/mailman/listinfo/python-list
Re: help with my first use of a class
BartlebyScrivener wrote: I am a mere hobbyist. Spent several hours trying to make a class, because I think this is an occasion where I need one. But I can't make it work. This code works (only because of the global c, which I know I'm supposed to avoid, by using a Class). I edited the rest to leave out the irrelevant formatting and printing of the quotations. I've read about Classes several times, but I don't get them yet. Obviously. If I can solve one real life problem like this, then maybe I'll see the light. If I understand the power of Classes correctly, I could make one that would allow me to make a new instance that would connect to, say, an SQLite3 db instead of the Access db, as well as to create more methods that will do different SQL searches. Thank you for any help, rd -- import mx.ODBC.Windows as odbc import sys import random def connect(): global c This means you want to use a global variable c which doesn't exist yet, an example would be to save this code to a file: #!/usr/bin/env python c = 0 def test_global(): global c c = 1 print c this will print 0 when you run it db='DSN=Quotations' conn = odbc.DriverConnect(db) c = conn.cursor() def random_quote(): Counts all of the quotes in MS Access database Quotations2005.mdb. Picks one quote at random and displays it using textwrap. c.execute (SELECT COUNT(Quote) FROM PythonQuoteQuery) # Yields the number of rows with something in the quote field total_quotes = c.fetchone() # Get a random number somewhere between 1 and the number of total quotes quote_number = (random.randint(1, total_quotes[0]),) # Select a quote where the ID matches that number c.execute (SELECT Author, Quote FROM PythonQuoteQuery WHERE ID=?, quote_number) quote = c.fetchone() blah blah blah def print_quote() code to format and print the quote (which will also have to be global, unless I learn Classes!) A class structure could look like - please bear in mind that I don't know mx.ODBC.Windows - I guess it is not completely DB-API compliant, as you don't use a connect method. class SQLQuery(object): Object which connects to the database and can execurte SQL commands def __init__(self, conn): conn is a dictionary {'serverId': XX, 'userId': YY, 'passWord': ZZ} self.connection = connect(conn['userId'], conn['passWord'], conn['serverId']) self.cursor = self.__connection.cursor() def select(self, selectqry): argument selectqry specifies a sql which returns data, like a select self.cursor.execute(selectqry) return self.cursor.fetchall() sql = SQLQuery('serverId': 'XX', 'userId': 'YY', 'passWord': 'ZZ') qoutes = sql.select(SELECT COUNT(Quote) FROM PythonQuoteQuery) print quotes if __name__ == '__main__': if len(sys.argv) == 1: sys.argv is a list, where the first argument is the name of the running script, the second element is the first argument, etc. connect() random_quote() print_quote() -- http://mail.python.org/mailman/listinfo/python-list
Re: help with my first use of a class
BartlebyScrivener wrote: I am a mere hobbyist. Spent several hours trying to make a class, because I think this is an occasion where I need one. But I can't make it work. This code works (only because of the global c, which I know I'm supposed to avoid, by using a Class). I edited the rest to leave out the irrelevant formatting and printing of the quotations. I've read about Classes several times, but I don't get them yet. Obviously. If I can solve one real life problem like this, then maybe I'll see the light. If I understand the power of Classes correctly, I could make one that would allow me to make a new instance that would connect to, say, an SQLite3 db instead of the Access db, as well as to create more methods that will do different SQL searches. Thank you for any help, rd -- import mx.ODBC.Windows as odbc import sys import random def connect(): global c db='DSN=Quotations' conn = odbc.DriverConnect(db) c = conn.cursor() def random_quote(): Counts all of the quotes in MS Access database Quotations2005.mdb. Picks one quote at random and displays it using textwrap. c.execute (SELECT COUNT(Quote) FROM PythonQuoteQuery) # Yields the number of rows with something in the quote field total_quotes = c.fetchone() # Get a random number somewhere between 1 and the number of total quotes quote_number = (random.randint(1, total_quotes[0]),) # Select a quote where the ID matches that number c.execute (SELECT Author, Quote FROM PythonQuoteQuery WHERE ID=?, quote_number) quote = c.fetchone() blah blah blah def print_quote() code to format and print the quote (which will also have to be global, unless I learn Classes!) if __name__ == '__main__': if len(sys.argv) == 1: connect() random_quote() print_quote() You really don't need classes for this, just parameters + return values. Probably best would be to master the idea of parameters + return values before yo move on to classes. This is called procedural programming. Notice that there is no name collision because of strict python namespaces (a good idea, according to Tim Peters). For example: def connect(): db='DSN=Quotations' conn = odbc.DriverConnect(db) c = conn.cursor() # NOTE THE RETURN VALUE: return c def random_quote(c): # == NOTE THE PARAMETER Counts all of the quotes in MS Access database Quotations2005.mdb. Picks one quote at random and displays it using textwrap. c.execute (SELECT COUNT(Quote) FROM PythonQuoteQuery) # Yields the number of rows with something in the quote field total_quotes = c.fetchone() # Get a random number somewhere between 1 and ... quote_number = (random.randint(1, total_quotes[0]),) # Select a quote where the ID matches that number q = SELECT Author, Quote FROM PythonQuoteQuery WHERE ID=? c.execute (q, quote_number) quote = c.fetchone() # NOTE THE RETURN VALUE: return quote def print_quote(quote): # == NOTE THE PARAMETER print quote # == WHATEVER YOU WANT TO DO if __name__ == '__main__': if len(sys.argv) == 1: c = connect()# == NO COLLISION: NAMESPACES quote = random_quote(c) # == DITTO print_quote(quote) # THERE YOU HAVE IT James -- http://mail.python.org/mailman/listinfo/python-list
Re: help with my first use of a class
Wow, That's great, James. Thanks. I shall put it together. Appreciate it. rd -- http://mail.python.org/mailman/listinfo/python-list
Re: help with my first use of a class
BartlebyScrivener wrote: I am a mere hobbyist. Spent several hours trying to make a class, because I think this is an occasion where I need one. But I can't make it work. This code works (only because of the global c, which I know I'm supposed to avoid, by using a Class). I edited the rest to leave out the irrelevant formatting and printing of the quotations. I've read about Classes several times, but I don't get them yet. Think of a class as both a blueprint for objects and a factory creating these objects. The class lets you define the attributes and behaviors of it's instances. Obviously. If I can solve one real life problem like this, then maybe I'll see the light. If I understand the power of Classes correctly, I could make one that would allow me to make a new instance that would connect to, say, an SQLite3 db instead of the Access db, as well as to create more methods that will do different SQL searches. Thank you for any help, import mx.ODBC.Windows as odbc import sys import random def connect(): global c db='DSN=Quotations' conn = odbc.DriverConnect(db) c = conn.cursor() def random_quote(): Counts all of the quotes in MS Access database Quotations2005.mdb. Picks one quote at random and displays it using textwrap. c.execute (SELECT COUNT(Quote) FROM PythonQuoteQuery) # Yields the number of rows with something in the quote field total_quotes = c.fetchone() # Get a random number somewhere between 1 and the number of total quotes quote_number = (random.randint(1, total_quotes[0]),) # Select a quote where the ID matches that number c.execute (SELECT Author, Quote FROM PythonQuoteQuery WHERE ID=?, quote_number) quote = c.fetchone() blah blah blah def print_quote() code to format and print the quote (which will also have to be global, unless I learn Classes!) Ever wondered what arguments and return values were for ?-) if __name__ == '__main__': if len(sys.argv) == 1: connect() random_quote() print_quote() First, notice that you *don't* need a class here to avoid globals. Learning to use function as *functions* (ie: taking arguments and returning values) instead of procedure would help: def random_quote(cursor): c.execute (SELECT COUNT(Quote) FROM PythonQuoteQuery) total_quotes = c.fetchone() quote_number = (random.randint(1, total_quotes[0]),) c.execute ( SELECT Author, Quote FROM PythonQuoteQuery WHERE ID=?, quote_number ) return c.fetchone() def format_quote(quote): # code here return formatted_quote def main(*args): if len(args) 2: print sys.stderr, Missing dsn arg\nusage : %s dsn % args[0] return 1 dsn = args[1] try: conn = odbc.DriverConnect(dsn) except SomeODBCErrorHere, e: print sys.stderr Cannot connect to %s : %s % (dsn, e) return 1 quote = random_quote(conn.cursor()) print format_quote(quote) conn.close() return 0 if __name__ == '__main__': sys.exit(main(*sys.argv)) Now for an OO version - that won't buy you much IMHO: class SQLFortune(object): def __init__(self, dsn): self._dsn = dsn self._cnx = None @apply def connection(): def fget(self): if self._cnx is None: self._cnx = odbc.DriverConnect(self.dsn) return self._cnx def fset(self, _): raise AttributeError(Attribute is read-only) return property(**locals()) def random_quote(self): c = self.connection.cursor() c.execute (SELECT COUNT(Quote) FROM PythonQuoteQuery) total_quotes = c.fetchone() quote_number = (random.randint(1, total_quotes[0]),) c.execute ( SELECT Author, Quote FROM PythonQuoteQuery WHERE ID=?, quote_number ) return c.fetchone() def format_quote(self, quote): # code here return formatted_quote def close(self): try: self._cnx.close() except: pass def main(*args): if len(args) 2: print sys.stderr, Missing dsn arg\nusage : %s dsn % args[0] return 1 dsn = args[1] fortune = SQLFortune(dsn) print fortune.format_quote(fortune.random_quote()) fortune.close() return 0 if __name__ == '__main__': sys.exit(main(*sys.argv)) -- bruno desthuilliers python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')]) -- http://mail.python.org/mailman/listinfo/python-list
Re: help with my first use of a class
BartlebyScrivener wrote: Whoah. At least I got the connection. I think. Maybe I can figure more on my own. Any help appreciated. Thanks - class Connection: def __init__(self, aDatasource): self.db = aDatasource self.conn = odbc.DriverConnect(self.db) self.conn.cursor() This creates a cursor, that's immediatly discarded. def random_quote(): Counts all of the quotes in MS Access database Quotations2005.mdb. Picks one quote at random and displays it using textwrap. c = Connection('DSN=Quotations') c.execute (SELECT COUNT(Quote) FROM PythonQuoteQuery) And this will raise an AttributeError, since your (mostly useless) Connection class doesn't define an 'execute' method. -- bruno desthuilliers python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')]) -- http://mail.python.org/mailman/listinfo/python-list
Re: help with my first use of a class
Bruno Desthuilliers wrote: First, notice that you *don't* need a class here to avoid globals. Learning to use function as *functions* (ie: taking arguments and returning values) instead of procedure would help: def random_quote(cursor): c.execute (SELECT COUNT(Quote) FROM PythonQuoteQuery) make that cursor.execute (etc) /F -- http://mail.python.org/mailman/listinfo/python-list
Re: help with my first use of a class
Fredrik Lundh wrote: Bruno Desthuilliers wrote: First, notice that you *don't* need a class here to avoid globals. Learning to use function as *functions* (ie: taking arguments and returning values) instead of procedure would help: def random_quote(cursor): c.execute (SELECT COUNT(Quote) FROM PythonQuoteQuery) make that cursor.execute (etc) oops, sorry - not enough coffein, I guess. Thanks for the correction. -- bruno desthuilliers python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')]) -- http://mail.python.org/mailman/listinfo/python-list
Re: help with my first use of a class
Thanks, Bruno. Very educational. rd Bruno Desthuilliers wrote: Think of a class as both a blueprint for objects and a factory creating these objects. The class lets you define the attributes and behaviors of it's instances. First, notice that you *don't* need a class here to avoid globals. Learning to use function as *functions* (ie: taking arguments and returning values) instead of procedure would help: Now for an OO version - that won't buy you much IMHO: -- http://mail.python.org/mailman/listinfo/python-list
Re: help with my first use of a class
Thank you all! My main problem is going away from Python and programming for weeks or months at a time, then picking up where I left off. But Python is much better in this regard than Perl. I appreciate the help. rd - Dennis Lee Bieber wrote: If using a db-api compliant adapter, and using minimal common features, the main thing one would have to worry about is the different placeholders used by the adapter. I'd be more likely to do something like import pick-a-db-adapter as db and then have a class query the db connection for what type of placeholder it uses, then modify any queries the class uses. You might make a class for each database /table/, and each instance of that class would be one record in the table. The class would have the methods for retrieval/update/delete/insert, when given the key value, perhaps. -- WulfraedDennis Lee Bieber KD6MOG [EMAIL PROTECTED] [EMAIL PROTECTED] HTTP://wlfraed.home.netcom.com/ (Bestiaria Support Staff: [EMAIL PROTECTED]) HTTP://www.bestiaria.com/ -- http://mail.python.org/mailman/listinfo/python-list
Re: help with my first use of a class
*** Your mail has been scanned by InterScan MSS. *** On Friday 20 October 2006 14:34, James Stroud wrote: You really don't need classes for this I'm in that matter too. Doesn't classes make the main program neater? Fundamentally OOP is the way to assemble ready objects to get a thing working, rather than worry about any single code line. Is this a concept of python? F -- http://mail.python.org/mailman/listinfo/python-list
Re: help with my first use of a class
Fulvio wrote: *** Your mail has been scanned by InterScan MSS. *** On Friday 20 October 2006 14:34, James Stroud wrote: You really don't need classes for this I'm in that matter too. Doesn't classes make the main program neater? Depends on the program. Fundamentally OOP is the way to assemble ready objects to get a thing working, rather than worry about any single code line. This is more a wishful dream than reality. While it can effectively be pretty powerful - specially with dynamic languages like Python or Ruby - OO is by no mean magical. Is this a concept of python? If you mean a concept specific to Python, well, not really - OO first reared it's head with Simula in the sixties and matured in the seventies with Smalltalk (which is still the reference IMHO). And it's (it-OO) more an evolution/systematisation of concepts that already existed before... FWIW, I don't know if there's any truly Python-specific concept in Python (except perhaps for the descriptor protocol, which is a somewhat advanced topic if you're new to programming and OO...). -- bruno desthuilliers python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')]) -- http://mail.python.org/mailman/listinfo/python-list
Re: help with my first use of a class
Fulvio wrote: *** Your mail has been scanned by InterScan MSS. *** On Friday 20 October 2006 14:34, James Stroud wrote: You really don't need classes for this I'm in that matter too. Doesn't classes make the main program neater? Fundamentally OOP is the way to assemble ready objects to get a thing working, rather than worry about any single code line. Is this a concept of python? I don't really have formal programming training, but it is increasingly becoming my experience that OOP is but one ingredient in a good program. It can be left out or it can be mixed with other ingredients for a nice effect. Take for example the file and open built-ins. Calling both creates a file object, but the latter, which is the preferred to open a file, is actually a function rather than a class. So even the python designers did not constrain themselves to any single style. I think the trick is to identify when a class would make more sense than a collection of subroutines, etc. James -- http://mail.python.org/mailman/listinfo/python-list
Re: help with my first use of a class
On 10/20/06, James Stroud [EMAIL PROTECTED] wrote: I don't really have formal programming training, but it is increasingly becoming my experience that OOP is but one ingredient in a good program. It can be left out or it can be mixed with other ingredients for a nice effect. Indeed. Python is a multi-paradigm programing language. If the best solution for a problem is a class, you've got them. If on the other hand, you just need a function, you can have one of those too - none of this class full of static methods rubbish like you have in Java. If a functional approach is better, Python does that. -- Cheers, Simon B [EMAIL PROTECTED] http://www.brunningonline.net/simon/blog/ -- http://mail.python.org/mailman/listinfo/python-list