1

I'm currently doing an if then else statement in python but I have 30 conditions for symbolUpper:

if symbolUpper == "CAT":
    growth = (((listOfRecords[2][5]-listOfRecords[2][4])/listOfRecords[2][4])*100)
    peRatio = (listOfRecords[2][5]/listOfRecords[2][6])
    print("Company: " + listOfRecords[2][0])
    print("Industry: " + listOfRecords[2][3])
    print("Exchange: " + listOfRecords[2][2])
    print("Growth in 2013: {0:,.2f}%".format(growth))
    print("Price/Earning ratio in 2013: {0:,.2f}".format(peRatio))

Is there an easier way to code in python without listing all the 30 conditions? I also included my whole code.

infile = open("Dow.txt", 'r')
listOfRecords = [line.rstrip() for line in infile]
infile.close()
for i in range(len(listOfRecords)):
    listOfRecords[i]=listOfRecords[i].split(",")
    listOfRecords[i][4] = eval(listOfRecords[i][4])     # price at the end of trading on 12/31/2012
    listOfRecords[i][5] = eval(listOfRecords[i][5])     # price at the end of trading on 12/31/2013
    listOfRecords[i][6] = eval(listOfRecords[i][6])     # 2013 earnings per share

print("Symbols for the Thirty DOW Stocks")
print(listOfRecords[0][1] + "\t" + listOfRecords[1][1] + "\t" +
      listOfRecords[2][1] + "\t" + listOfRecords[3][1] + "\t" +
      listOfRecords[4][1] + "\t" + listOfRecords[5][1] + "\t" +
      listOfRecords[6][1] + "\t" + listOfRecords[7][1] + "\t" +
      listOfRecords[8][1] + "\t" + listOfRecords[9][1] + "\n" +
      listOfRecords[10][1] + "\t" + listOfRecords[11][1] + "\t" +
      listOfRecords[12][1] + "\t" + listOfRecords[13][1] + "\t" +
      listOfRecords[14][1] + "\t" + listOfRecords[15][1] + "\t" +
      listOfRecords[16][1] + "\t" + listOfRecords[17][1] + "\t" +
      listOfRecords[18][1] + "\t" + listOfRecords[19][1] + "\n" +
      listOfRecords[20][1] + "\t" + listOfRecords[21][1] + "\t" +
      listOfRecords[22][1] + "\t" + listOfRecords[23][1] + "\t" +
      listOfRecords[24][1] + "\t" + listOfRecords[25][1] + "\t" +
      listOfRecords[26][1] + "\t" + listOfRecords[27][1] + "\t" +
      listOfRecords[28][1] + "\t" + listOfRecords[29][1] + "\t")
print()
symbol = input("Enter a symbol: ")
symbolUpper = symbol.upper()

if symbolUpper == "AXP":
    growth = (((listOfRecords[0][5]-listOfRecords[0][4])/listOfRecords[0][4])*100)
    peRatio = (listOfRecords[0][5]/listOfRecords[0][6])
    print("Company: " + listOfRecords[0][0])
    print("Industry: " + listOfRecords[0][3])
    print("Exchange: " + listOfRecords[0][2])
    print("Growth in 2013: {0:,.2f}%".format(growth))
    print("Price/Earning ratio in 2013: {0:,.2f}".format(peRatio))

if symbolUpper == "BA":
    growth = (((listOfRecords[1][5]-listOfRecords[1][4])/listOfRecords[1][4])*100)
    peRatio = (listOfRecords[1][5]/listOfRecords[1][6])
    print("Company: " + listOfRecords[1][0])
    print("Industry: " + listOfRecords[1][3])
    print("Exchange: " + listOfRecords[1][2])
    print("Growth in 2013: {0:,.2f}%".format(growth))
    print("Price/Earning ratio in 2013: {0:,.2f}".format(peRatio))

if symbolUpper == "CAT":
    growth = (((listOfRecords[2][5]-listOfRecords[2][4])/listOfRecords[2][4])*100)
    peRatio = (listOfRecords[2][5]/listOfRecords[2][6])
    print("Company: " + listOfRecords[2][0])
    print("Industry: " + listOfRecords[2][3])
    print("Exchange: " + listOfRecords[2][2])
    print("Growth in 2013: {0:,.2f}%".format(growth))
    print("Price/Earning ratio in 2013: {0:,.2f}".format(peRatio))

if symbolUpper == "CSCO":
    growth = (((listOfRecords[3][5]-listOfRecords[3][4])/listOfRecords[3][4])*100)
    peRatio = (listOfRecords[3][5]/listOfRecords[3][6])
    print("Company: " + listOfRecords[3][0])
    print("Industry: " + listOfRecords[3][3])
    print("Exchange: " + listOfRecords[3][2])
    print("Growth in 2013: {0:,.2f}%".format(growth))
    print("Price/Earning ratio in 2013: {0:,.2f}".format(peRatio))

5 Answers 5

1

Yes. There is. Maintain a lookup for your symbols using a dict:

lookup_dict = {'AXP': 0, 'BA': 1, ...}
try:
    i = lookup_dict[symbolUpper]
    growth = (((listOfRecords[i][5]-listOfRecords[i][4])/listOfRecords[i][4])*100)
    peRatio = (listOfRecords[i][5]/listOfRecords[i][6])
    print("Company: " + listOfRecords[i][0])
    print("Industry: " + listOfRecords[i][3])
    print("Exchange: " + listOfRecords[i][2])
    print("Growth in 2013: {0:,.2f}%".format(growth))
    print("Price/Earning ratio in 2013: {0:,.2f}".format(peRatio))
except KeyError:
    ... # symbolUpper not in dict
Sign up to request clarification or add additional context in comments.

3 Comments

Why not use a dict?
I agree with @PeterWood. A dict would further improve the solution. lookup_dict = {'AXP': 0, 'BA': 1, ...} and then use lookup_dict[symbolUpper] to get the i
Good idea. Didn't think of that. Thanks guys.
1

When you have duplication, look at what's the same and what's different.

Separate the two.

The only thing different is the index. There are many parts the same.

If you've copied and pasted more than once or twice you need to rethink. As they say, three strikes and you refactor.

Your code is also very verbose. For example listOfRecords would be better as just records. You can also iterate directly over data instead of iterating over a range and indexing into the data:

print("Symbols for the Thirty DOW Stocks")
print('\t'.join(record[1] for record in records)

When you open a file, it's best to close it afterwards. Python will do this for you automatically if you use a with statement. Also, the mode is r by default so you don't need to specify it:

with open("Dow.txt") as infile:
    records = [line.rstrip() for line in infile]
# file will be closed here

You shouldn't use eval, really. If, for example, the input contained a command to delete all your files it could wreak havoc. If you've just got literal numbers you can use literal_eval safely:

from ast import literal_eval

records = [records.split(',') for record in records]
for record in records:
    record[4] = literal_eval(record[4])  # price at the end of trading on 12/31/2012
    record[5] = literal_eval(record[5])  # price at the end of trading on 12/31/2013
    record[6] = literal_eval(record[6])  # 2013 earnings per share

Addressing the issue of the duplication and the index. The records contain the symbol for the stock so you can build a lookup table using the records. In Python a lookup table is best represented using dict:

lookup = {record[1]: record
          for record in records}

Aside: now we have a lookup table based on the DOW symbol, we can use it when printing the symbols, as iterating a dictionary gives you the keys (which are the DOW symbols):

print("Symbols for the Thirty DOW Stocks")
print('\t'.join(symbol for symbol in records) 

You can replace the rest of your code with a function:

def report(dow):
    growth = 100 * (dow[5] - dow[4]) / dow[4]
    peRatio = dow[5] / dow[6]
    print("Company: " + dow[0])
    print("Industry: " + dow[3])
    print("Exchange: " + dow[2])
    print("Growth in 2013: {0:,.2f}%".format(growth))
    print("Price/Earning ratio in 2013: {0:,.2f}".format(peRatio))

You would call it as:

report(lookup[symbol])

Further improvements would include using the csv module, as you perform split(',') manually, it can do that for you. Also, it handles quoted fields properly, so if any of your company names had commas in them, e.g. Google, Inc, if it was quoted as "Google, Inc" csv will handle it and not split on the comma:

import csv

with open("Dow.txt") as infile:
    records = list(csv.reader(infile))

Also, namedtuple works nicely with csv records.

Dow = namedtuple('Dow', 'company symbol exchange industry previous price earning')

records = [Dow(*[literal_eval(value) for value in record])
           for record in records]

Then your calculations can be easier to read:

growth = 100 * (dow.price - dow.previous) / dow.previous
pe_ratio = dow.price / dow.earning

Finally, your report should be separated from print, as you might want to use it somewhere else, e.g. logging, writing to a file, etc. Using format fields also makes it more readable.

report_format = ('Company: {dow.company}\n'
                 'Industry: {dow.industry}\n'
                 'Exchange: {dow.exchange}\n'
                 'Growth in 2013: {growth:,.2f}%\n'
                 'Price/Earning ratio in 2013@ {pe_ratio:,.2f}\n')

report = report_format.format(dow=record,
                              growth=growth,
                              pe_ratio=pe_ratio)

print(report)

Comments

0

Save in List all the strings you want to make comparisons to, then get the index for the string you want and execute your tasks using that index.

symbolUpperList = ["AXP", "BA", "CAT", ...]

i = symbolUpperList.index(symbolUpper)
growth = (((listOfRecords[i][5]-listOfRecords[i][4])/listOfRecords[i][4])*100)
peRatio = (listOfRecords[i][5]/listOfRecords[i][6])
print("Company: " + listOfRecords[i][0])
print("Industry: " + listOfRecords[i][3])
print("Exchange: " + listOfRecords[i][2])
print("Growth in 2013: {0:,.2f}%".format(growth))
print("Price/Earning ratio in 2013: {0:,.2f}".format(peRatio))

Comments

0
  • Prepare your symbolUpper db with key and values.
  • move your actual code to function.
  • call it with the symbolUpper's id

Code can be as follows:

infile = open("Dow.txt", 'r')
listOfRecords = [line.rstrip() for line in infile]

symbolUpper_db = {"AXP": 1, "BA" : 2, "CAT":3, "CSCO":4 }

def compute( symbol_idx ):
    growth = (((listOfRecords[symbol_idx][5]-listOfRecords[symbol_idx][4])/listOfRecords[symbol_idx][4])*100)
    peRatio = (listOfRecords[symbol_idx][5]/listOfRecords[symbol_idx][6])
    print("Company: " + listOfRecords[symbol_idx][0])
    print("Industry: " + listOfRecords[symbol_idx][3])
    print("Exchange: " + listOfRecords[symbol_idx][2])
    print("Growth in 2013: {0:,.2f}%".format(growth))
    print("Price/Earning ratio in 2013: {0:,.2f}".format(peRatio))

compute(symbolUpper_db[symbolUpper])

Comments

0

You have changes only in your index . so specify index for each of your symbolUpper

here is the simple if condition,

i = 2 if symbolUpper == "CAT" else 1 if symbolUpper == "BA" else 0 if symbolUpper == "AXP" else False

if i:
    growth = (((listOfRecords[i][5]-listOfRecords[i][4])/listOfRecords[i][4])*100)
    peRatio = (listOfRecords[i][5]/listOfRecords[i][6])
    print("Company: " + listOfRecords[i][0])
    print("Industry: " + listOfRecords[i][3])
    print("Exchange: " + listOfRecords[i][2])
    print("Growth in 2013: {0:,.2f}%".format(growth))
    print("Price/Earning ratio in 2013: {0:,.2f}".format(peRatio))

or you can try using Dictionary lookup,

sym = {"AXP": 1, "BA" : 2, "CAT":3, "CSCO":4 } 
growth = (((listOfRecords[sym[symbolUpper]][5]-listOfRecords[sym[symbolUpper]][4])/listOfRecords[sym[symbolUpper]][4])*100)
peRatio = (listOfRecords[sym[symbolUpper]][5]/listOfRecords[sym[symbolUpper]][6])
print("Company: " + listOfRecords[sym[symbolUpper]][0])
print("Industry: " + listOfRecords[sym[symbolUpper]][3])
print("Exchange: " + listOfRecords[sym[symbolUpper]][2])
print("Growth in 2013: {0:,.2f}%".format(growth))
print("Price/Earning ratio in 2013: {0:,.2f}".format(peRatio))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.