Formatting Text in a Table in Python
Question: I'm having issues creating a table that is dynamic to adjust to various
results.

I've written a screen scraper to pull stocks from <http://finance.yahoo.com>
and print the company name, it's symbol, and it's current stock price.

However the output looks like this:

    
    
     Microsoft Corporation MSFT 29.76
    
     Apple Inc. AAPL 396.77
    
     SPDR S&P 500 SPY 155.25
    
     Google Inc. GOOG 787.76
    

I want it to look like

    
    
    Microsoft Corporation        MSFT      29.76
    
    Apple Inc.                   AAPL      396.77
    
    SPDR S&P 500                 SPY       155.25
    
    Google Inc.                  GOOG      787.76
    

I just started wokring with Python yesterday and am using 3.3.1

My current code is as follows:

    
    
    import re
    import urllib.request
    import cgi
    from bs4 import BeautifulSoup
    
    price = [0,0,0,0]
    namesList = ["string1", "string2", "string3", "string4"]
    stocksList = ["msft","aapl","spy","goog"]
    
    def HTML():
        i = 0
        while i < len(stocksList):
            htmlPull = urllib.request.urlopen("http://finance.yahoo.com/q?s="+stocksList[i]+"&ql=1")
            htmlPull = htmlPull.read().decode('utf-8')
            regex = '<span id="yfs_l84_'+stocksList[i]+'">(.+?)</span>'
            pattern = re.compile(regex)
            price[i] = re.findall(pattern,htmlPull)
            htmlParse = BeautifulSoup(htmlPull)
            title = htmlParse.title.contents
            namesList[i] = title        
            i+=1
    
    formatPrice(price)
    formatStock(namesList)
    formatOutput(namesList, stocksList, price)
    
    def formatPrice(price):
        k=0
        while k < len(price):
            cleaner = str(price[k])
            cleaner = cleaner.replace("[","")
            cleaner = cleaner.replace("]","")
            cleaner = cleaner.replace("'","")
            price[k] = float(cleaner)
            k+=1
    
    def formatStock(namesList):
        k = 0
        while k <len(namesList):
            capital = stocksList[k]
            capital = capital.upper()
            cleaner = str(namesList[k])
            cleaner = cleaner.replace("Summary for ", "")
            cleaner = cleaner.replace(":"," ")
            cleaner = cleaner.replace("- Yahoo! Finance'","")
            cleaner = cleaner.replace("['","")
            cleaner = cleaner.replace("]","")
            cleaner = cleaner.replace(";","")
            cleaner = cleaner.replace(capital, "")
            namesList[k] = cleaner;
            k+=1
    
        def formatOutput(namesList, stocksList, price):
            i = 0
            while i < len(price):
            capital = stocksList[i]
            capital = capital.upper()
            print(namesList[i],capital, price[i])
            print("")
            i+=1
    HTML()
    

Have tried print ({0},{1},{2}.format (namesList, capital, price[i])), various
types of {:<16} variations, etc. It seems to only affect one line and I'm
trying to get it to think in terms of columns, or a table, or maybe a certain
amount of space that the text and whitespace should fill. I'm not sure what
exactly the solution is here, so I'm asking you all :)

As you can tell by my code, I'm pretty new to programming, so if there is a
better way to do anything in this code, I'd be happy to listen to correction,
advice, and suggestions.

Thanks!


Answer: You want to set the width based on the longest item in the column.

In Python, you use `max` to find the largest of some group of things. So,
outside the loop, you can do:

    
    
    names_width = max(len(name) for name in namesList)
    stock_width = max(len(stock) for stock in stockList)
    

Then, format each line like you said you tried:

    
    
    print({0:{3}}  {1:{4}}  {2}.format(namesList[i],
                                       capital,
                                       price[i],
                                       names_width,
                                       stock_width))
    

