I have made a Python App(really script) that will check a stocks current values from a website & save that data to a SQLite 3 database.
I am looking for any suggestions & criticisms on what I should do better or anything at all but mainly in these areas: [QUOTE] - Correct Python Layout of code - Correct error checking: Am I catching all my errors or are my exceptions not specific enough? Should I be using more try excepts inside my functions? - Are there any areas where huge errors, bugs etc could occur that I have not compensated for? - I am also looking for suggestions on how to write a function better, so if you think that function is really bad & should be rewritten completely or something I would really like to hear it. - Anything else that you see - Is python meant to be used in the way I have used it? To make a 'semi detailed' app?[/QUOTE] Any advice criticism would be really helpful. App: [CODE]""" *Stock Data Builder* Algorithm: - Search website for stock - Get website HTML source code - Search code for target stock data(price,dividends,etc..) - Add data to text file """ import sys import os import sqlite3 import datetime import time import urllib2 ### Global Variables ### menu = "***Stock Program*** \n\n1. Add a Stock to track \n2. Get Todays Tracking Data \n3. Exit \nEnter decision: " target = '<th scope="row" class="row"><a href="/asx/research/ companyInfo.do?by=asxCode&asxCode=%s">%s</a>' ASXurl = 'http://www.asx.com.au/asx/markets/priceLookup.do? by=asxCodes&asxCodes=' class stock: code = "" purchasePrice = 0 purchaseQuantity = 0 price = [] # list of recent prices recentBid = [] # list of recent bids for stock recentOffer = [] # list of recent offers for stock stockVol = [] # list of stock quantity available on market def __init__(self): """ Default Constructor """ self.code = "" self.purchasePrice = 0 self.purchaseQuantity = 0 def constructor(self, stockCode, purPrice, purQuant): """ Constructor """ self.code = stockCode self.purchasePrice = purPrice self.purchaseQuantity = purQuant def setData(self, stockCode, purPrice, purQuant, priceList, reBidList, reOffList, popList): """ Defines & implements the objects' public variables """ self.code = stockCode self.purchasePrice = purPrice self.purchaseQuantity = purQuant self.price = priceList self.recentBid = reBidList self.recentOffer = reOffList self.stockVol = popList self.printStats() def updateData(self, priceEle, bidEle, offerEle, populEle): """ Adds data to stock object's lists """ self.price.append(priceEle) self.recentBid.append(bidEle) self.recentOffer.append(offerEle) self.stockVol.append(populEle) def printStats(self): """ Output Stock attributes """ print("Stock Code: "+self.code) print("Stock Purchase Price: "+str(self.purchasePrice)) print("Stock Quantity Owned: "+str(self.purchaseQuantity)) print("***Initial Investment Value: "+str(self.purchasePrice*self.purchaseQuantity)) if not(len(self.price) <= 0): print("Stock Current Price: "+str(self.price[-1])) print("Recent Bid: "+str(self.recentBid[-1])) print("Recent Offer: "+str(self.recentOffer[-1])) print("Total Stock Volume in market: "+str(self.stockVol[-1])) print("***Present Investment Value: "+str(self.price[-1]*self.purchaseQuantity)) print("\n") ### Functions ### def connectDatabase(dbLocation, dbName, tableName): """ Establish & Return connection to SQLite Database """ try: if not (os.path.exists(dbLocation)): os.mkdir(dbLocation) # create folder/dir os.chdir(dbLocation) # change directory focus to dbLocation conn = sqlite3.connect(dbLocation+dbName) cur = conn.cursor() try: createTableQ = "CREATE TABLE IF NOT EXISTS "+tableName +" (code varchar PRIMARY KEY, purchase_price float, purchase_quantity float, purchase_date varchar);" cur.execute(createTableQ) conn.commit() except: pass return conn except IOError or OSError: print "Connection to database failed" return False def retrieveStockDatabase(conn, tableName): """ Read SQLite3 database & extract stock data into StockList """ stockList = [] stockQuery = "select recent_price, recent_offer, recent_bid, stock_volume from ? ;" cur = conn.cursor() cur.execute("select code, purchase_price, purchase_quantity from "+tableName+";") for row in cur.fetchall(): newStock = stock() newStock.code = row[0] newStock.purchasePrice = row[1] newStock.purchaseQuantity = row[2] cur.execute(stockQuery,[newStock.code]) for rw in cur.fetchall(): newStock.price.append(rw[0]) newStock.recentOffer.append(rw[1]) newStock.recentBid.append(rw[2]) newStock.stockVol.append(rw[3]) stockList.append(newStock) return stockList def getDate(): """ Return todays date in format DD:MM:YYYY """ time = datetime.datetime.now() date = time.strftime("%d:%m:%Y") # string format time (%y) return date def newStockDatabase(conn, stockTable, stock): """ Add a new stock to SQLite database if not already there We save the stocks code, purchase price, quantity purchased & date of purchase. """ cur = conn.cursor() try: createTableQ = "create table "+stock.code+" (date varchar PRIMARY KEY, recent_price float, recent_offer float, recent_bid float, stock_volume double);" stockQuery = "insert into "+stockTable+" values(?, ?, ?, ?);" cur.execute(createTableQ) cur.execute(stockQuery, [stock.code,stock.purchasePrice,stock.purchaseQuant,getDate()]) conn.commit() except IOError or OSError: print "Table may already exist or bad SQLite connection." return False def webFormat(URL): if (URL.startswith("http://")==False): URL = "http://"+URL return URL def getSource(URL): """ Retrieve HTML source code from website URL & save in sourceBuffer """ try: URL = webFormat(URL) # make sure URL contains essential "http://" sourceBuffer = urllib2.urlopen(URL) print '\nResponse code = ',sourceBuffer.code print 'Response headers = ',sourceBuffer.info() print 'Actual URL = ',sourceBuffer.geturl() sourceCode = sourceBuffer.read() sourceBuffer.close() return sourceCode except IOError: # URLError print "Function Failed: Reasons could be invalid URL name \nOR \nHTML protocol message transfer failure." return False # function failed def getTargetText(targetStrtData, targetEndData, dataBuffer): """ Grabs target text that lies inside 'dataBuffer' string between targetStrtData & targetEndData """ try: result = dataBuffer.split(targetStrtData) result.pop(0) result = result[0].split(targetEndData) result.pop(1) print result return result except IOError: print "Function Failed: Reasons could be targetStrtData and/or targetEndData is not present in dataBuffer." def getStockData(htmlText, selectedStock): """ Extract stock data(stock code,price,etc) from htmlText """ try: # Here I extract my number data from HTML text tempList = [] for string in htmlText: for i in string.split('>'): for e in i.split(): if ('.' in e and e[0].isdigit()): tempList.append(float(e)) elif (',' in e and e[0].isdigit() ): # remove ',' chars e = e.replace(',','') tempList.append(float(e)) selectedStock.updateData(tempList[0],tempList[2],tempList[3],tempList[7]) except IOError: # is this the correct error I should be trying to catch here?? print "Function Failed: Reasons could be: sites HTML data has changed. Consult author of program." return False def createStockTracker(stockCode,stockPrice,stockQuant, stockList): """ Add a new stock to the database to track """ newStock = stock() newStock.constructor(stockCode,stockPrice,stockQuant) stockList.append(newStock) return stockList def writeStockToDatabase(conn, stock): """ Write ONLY this Stock's attributes to SQLite Database """ cur = conn.cursor() date = getDate() tableName = stock.code stockquery = "insert into "+tableName+" values(?, ?, ?, ?, ?);" cur.execute(query,[date,stock.price[-1], stock.recentOffer[-1], stock.recentBid[-1], stock.stockVol[-1]]) conn.commit() def writeAllToDatabase(conn, stockList): """ Enter recent Stock attributes into SQLite Database """ cur = conn.cursor() date = getDate() for stock in stockList: tableName = stock.code stockquery = "insert into "+tableName+" values(?, ?, ?, ?, ?);" cur.execute(query,[date,stock.price[-1], stock.recentOffer[-1], stock.recentBid[-1], stock.stockVol[-1]]) conn.commit() ### Input Functions ### def inputNewStock(): """ """ print "*Please note only an Australian Securities Exchange(ASX) listed stock can be tracked in Version 1.0." badInput = True while (badInput == True): try: code = raw_input("Please enter the ASX code for the stock you wish to track: ") price = input("Please enter the individual stock value for "+code+": ") quantity = input("Please enter the number/quantity of stocks purchased: ") if (len(code)>3): badInput = True else : badInput = False return True except IOError: if (raw_input("Incorrect input. Note: ASX code cannot be more than 3 chars. Press 'x' to exit or anything else to try again")=='x'): return False badInput = True # this I am not sure if necessary to loop correctly ### Main program loop ### def main(): programEnd = False; dbLocation = "C:\Users\Sam\Desktop\StockApp/" dbName = "stockData.db" stockTable = "stocks" conn = connectDatabase(dbLocation,dbName,stockTable) stockList = retrieveStockDatabase(conn,stockTable) for s in stockList: s.printStats() while (programEnd == False): decision = input(menu) # Print Menu if (decision==1): if not(inputNewStock()==False): stockList = createStockTracker(acode,price,quantity,stockList) newStockDatabase(conn,stockTable,stockList[-1]) print("\n** New Stock **") stockList[-1].printStats() print "The stock "+code+" was successfully added to our database. \nNow every time the program runs it will automatically track this stock & obtain its stock attributes\n\n" # TO DO: # get new stock recent Data from internet etc. # add stock data to data base; elif (decision==2): if (len(stockList)>0): for Stock in stockList: URL = ASXurl+Stock.code sourceCode = getSource(URL) targetData = getTargetText(target % (Stock.code,Stock.code),"</tr>",sourceCode) getStockData(targetData,Stock) Stock.printStats() #writeStockToDatabase(conn,Stock) else: print "You must first identify a stock to follow. \nPlease select option 1." elif (decision==3): print "Thank you for using Stock Program. Goodbye.\n" programEnd = True; # Exit program conn.close() return 0 # End program main()[/CODE] -- http://mail.python.org/mailman/listinfo/python-list