2

I'm having trouble finishing this program. The goal of the program is to read a file that contains the abbreviation of a stock and a number that stands for the amount of shares. I am then going to put the full company name, price of the stock, number of shares, and total investments in an html file in a table. I am having trouble separating the abbreviation of the company from the number of shares in the text file. This is what I have so far:

from string import *
import urllib2

class getURLinfo:

    def __init__( self ):
        """Constructor, creates the object and assigns "None" to the
        instance variables."""
        self.url         = None
        self.begMarker = None
        self.endMarker   = None

    def setURL( self, u ):
        """Mutator: assign value to the instance variable, URL"""   
        self.url = u

    def setMarkers( self, begin, end ):
        """Mutator: assign values to the instance variables begMarker
        and endMarker"""   
        self.begMarker = begin
        self.endMarker = end

    def getInfo( self, identifier ):
        """Return the text between the two markers for the specific URL
        indicated by the 'identifier' parameter."""

        # Create the exact URL string and retrieve the indicated html text 
        f = urllib2.urlopen( self.url % identifier )
        html = f.read()

        # Locate the markers in the htmlText string 
        begIndex = html.find( self.begMarker )
        endIndex = html.find( self.endMarker, begIndex )

        # Include some simple error checking if the markers are not found 
        if begIndex== -1 or endIndex== -1:
            return None

        # Advance the starting index to the actual beginning of the desired text
        begIndex = begIndex + len( self.begMarker )

        # Slice out and return the desired text 
        return html[ begIndex : endIndex ]


# ---------------------------------------------------------
#   Testing Area
# ---------------------------------------------------------
"""
if __name__=="__main__":

    # Create an object of type getURLinfo
    zodSite = getURLinfo()

    # Initialize the instance variables
    zodSite.setURL("http://my.horoscope.com/astrology/free-daily-horoscope-%s.html")
    zodSite.setMarkers('id="textline">',"</div>")

    # Retrieve the horoscope and display it
    horos = zodSite.getInfo("capricorn")
    print "Your horoscope is: \n",horos
"""

"""
Class definition for a list of stocks.
Instance variables:  name and price
"""

class STOCKINFO:
    def __init__(self):

        #This is the constructor for class FriendInfo

        self.abbrev = None
        self.share = None
        self.name = None
        self.price = None

    def otherInfo(self, ab, sh):

        self.abbrev = ab
        self.share = sh


    def newInfo(self, nm, pr):

        #Enters the stock information

        self.name = nm
        self.price = pr

    def updateAbbrev(self, newAb):
        self.abbrev = newAb

    def updateShare(self, newSh):
        self.share = newSh

    def updateName(self, newNm):
        self.name = newNm

    def updatePrice(self, newPr):
        self.price = newPr

    def getAbbrev(self):
        return self.abbrev

    def getShare(self):
        return self.share

    def getName(self):
        return self.name

    def getPrice(self):
        return self.price

    def showInfo(self):
        print "This stock's info is:\n\t%s\n\t%s\n\t%s\n\t%s" \
              % (self.name, self.price)

#---------------------------------------------------------
# Testing Area
"""
if __name__ == "__main__":

    print "\n\nCreating new information entries..."
    f1 = STOCKINFO()
    f2 = STOCKINFO()

    print "\nFilling in data"
    f1.newInfo('GOOG', '75', 'Google', '544.26')
    f2.newInfo('GM', '12','General Motors', '32.09')

    print "\nPrinting information in datatbase"
    f1.showInfo()
    f2.showInfo()

    print "\nUpdating the information"
    f1.updateAbbrev('GE')
    f2.updateShare('500')
    f1.updateName('Google')
    f2.updatePrice('544.10')

    print "\nShowing the updated info \n"
    f1.showInfo()
    f2.showInfo()

    print
    print "Using the getXX() methods..."
    print "getAbbrev = ", f1.getAbbrev()
    print "getShare = ", f1.getShare()
    print "getName = ", f1.getName()
    print "getPrice = ", f1.getPrice()
"""

def openHTML():
    """
    This function creates and opens the HTML called "stock.html"
    and returns the variable file1 at the end. 
    """

    file1 = open("stock.html", 'w')
    file1.write("""\n<center><FONT COLOR="#00FF00"><html>\n<head><title>Stock \
    Portfolio</title></head>""")

    return file1

def Title(file1):
    """
    This function creates a title on the webpage.
    """

    file1.write("""<body bgcolor="#151B8D">                                                                          
<h1>Stock Portfolio</h1>                                     
<p>My total portfolio value is:  </p>""")

def closeHTML(file1):
    """
    This function will close the html file.
    """

    file1.close()

def getStocks():

    file2= open("stock.txt", 'r')

    slist = []

    for word in file2:
        stock = word[:-1]
        slist.append(stock)

    print "The stocks you have are:"
    print slist

    return slist, file2

def getStocksURL(slist):

    stockInfo = STOCKINFO()

    sURL = getURLinfo()
    sURL.setURL("http://finance.yahoo.com/q?s=%s")

    sURL.setMarkers("""</b></span>&nbsp;&nbsp;</div><h1>""", "<span>")
    name = sURL.getInfo(slist)
    print "Company name: ", name

    sURL.setMarkers("""</small><big><b><span id="yfs_l10_""", "</span></b>")
    price = sURL.getInfo(slist)
    print "Stock price is: ", price

    stockInfo.newInfo(name, price)

    return stockInfo

def stockInformation(slist):

    stocklist = []

    for stock2 in slist:
        stockInfo = getStocksURL(stock2)
        stocklist.append(stockInfo)

    #print stocklist
    return stocklist

def createTable (file1, Stocks):

    file1.write("""<p>
<table border="1">
<tr>
    <td>Company Name</td>
    <td>Stock Price</td>
    <td>Number of Shares</td>
    <td>Total Investment</td>
</tr>""")

    for stock in Stocks:
        file1.write("""<tr>
        <td>""" + str (stock.getAbbrev()) +"""</td>
        <td>""" + str (stock.getShare()) + """</td>
        <td>""" + str (stock.getName()) + """</td>
        <td>""" + str (stock.getPrice()) + """</td>""")

def main():

    f = openHTML()
    Title(f)
    slist = getStocks()
    stocks = stockInformation(slist)
    createTable(f, stocks)
    closeHTML(f)

main()

Thank you!!

jonsca
  • 10,218
  • 26
  • 54
  • 62
  • 4
    Two suggestions to help us answer this question. First, limit the code to just the relevant part, since pretty much no one will read through all your code to find the part you need help with. Second, can you show us a sample input file, since without it there's not much we can recommend on how to read it. – Gordon Seidoh Worley May 03 '11 at 02:21
  • Also the formatting is a little off, someone with more reputation (or you) need to fix the formatting. Note that four spaces starts a code block, so you probably you need to indent everything by four spaces (better to do that in an offline editor in my opinion) – Henry May 03 '11 at 03:04
  • 1
    What's the relevance of the *horoscope* guff in the code??? – John Machin May 03 '11 at 03:20
  • 1
    Use either [Scrapy](http://doc.scrapy.org/intro/tutorial.html) or [Beautiful Soup](http://www.crummy.com/software/BeautifulSoup/documentation.html) to properly parse the HTML and give you back useful/structured results, which you can then read directly to make `STOCKINFO` objects out of – inspectorG4dget May 03 '11 at 03:59
  • The input file would look like this:GOOG 75 HOG 16 (each abbreviation would be on its own line with a space between the abbreviation and the number of shares.) The getURL class was originally used for a program that dealt with horoscopes. It was just a line for testing to make sure the class worked. – Matt Fincher May 03 '11 at 15:16

1 Answers1

0

You said you are "having trouble separating the abbreviation of the company from the number of shares in the text file." What trouble, exactly? To read in 2 columns of whitespace-separated data from a textfile, just do:

import fileinput
for line in fileinput.input(yourinputfile):
    (abbrev,shares) = line.split() # if you want 2 fixed columns
    #... lookup name, price...
    slist.append(STOCKINFO(name,price,abbrev,shares)) # or whatever processing

Sounds like what you want, I can't see any problem? (As the others said, delete all your code except for the parts that show the problem.)

(Or if you wanted 4 fixed columns: (name,price,abbrev,shares) = line.split(maxsplit=4)) (Or if you want 2-4 variable columns (with the last 2 being optional), you could use re.match, as below.) If none of this is what you want, explain why it is not!, show sample input, and explain the error/problem you see.

import re
stocklist_pat = re.compile('(\S+)\s+(\S+)\s+(\S*)\s*(\S*)\s*')
(name,price,abbrev,shares) = stocklist_pat.match(line).groups()

Not directly related to your specific question, a couple of other stylistic comments, to make your code more Pythonic:

STOCKINFO has a 0-arg constructor, as well as two other 2-arg constructor-like methods newInfo() and otherInfo(). A 0-arg constructor doesn't make much sense since we know we're always going to immediately supply nm, pr, so define a 4-arg constructor and make ab,sh optional:

def __init__(self,nm,pr,ab=None,sh=None):
    self.name = nm
    self.price = pr
    self.abbrev = ab
    self.share = sh

Read about Python properties, it's easier than writing all those getters/setters (updateAbbrev/Share/Name/Price, getAbbrev/Share/Name/Price). "Python Is Not Java", for general style migration see the links at Programming in Python vs. programming in Java.

Community
  • 1
  • 1
smci
  • 32,567
  • 20
  • 113
  • 146