3
\$\begingroup\$

The purpose of this program is to keep track of some stocks that we bought in a game and every week we must list the closing prices of each stock in a Google Sheet. I thought since I had a lot of different investments to keep track of I would write a quick script to do it for me. And I could have my friends in class send me their stocks as well to save them time.

I am just looking for any bad practices I might have in my code as well as any more efficient ways of carrying out some of the functions.

from yahoofinancials import YahooFinancials
import re
import pygsheets
import pandas as pd
import datetime

now = datetime.datetime.now()
time_now = (now.year, now.month, now.day)
time_now = str(time_now)

data = []
formatedData = []
shortData = []
everything = []
tickers = ['XOM', 'JNJ', 'TR', 'CRON', 'HSY', 'FL', 'PLNT', 'MCD', 'ARLP', 'LULU', 'RCII', 'DELL', 'DNKN', 'DIS']


def main(sheet, everything,place):
    gc = pygsheets.authorize(service_file='creds.json')

    # Create empty dataframe
    df = pd.DataFrame()

    # Create a column
    df['Closings: ' + time_now] = everything
    # open the google spreadsheet (where 'PY to Gsheet Test' is the name of my sheet)
    sh = gc.open('PY to Gsheet Test')

    # select the first sheet
    wks = sh[sheet]

    # update the first sheet with df, starting at cell A2.
    wks.set_dataframe(df, (1, place))  # up/down,left right


for i in tickers:
    tick = YahooFinancials(i)
    history = tick.get_historical_price_data('2019-03-07', '2019-03-08', 'daily')
    y = str(history)
    data.append(y)

for i in data:
    i = i[i.index('adjclose'):]
    i = re.findall("\d+\.-?\d*", i)
    i = str(i)
    if len(i) > 7:
        formatedData.append(i[2:9]) #the decimals were really long so this shortens them down a bit
    else:
        formatedData.append(i)

y = 0
for i in tickers:
    x = i
    x = x + " : " + formatedData[y]
    y = y + 1
    everything.append(x)


def get_name(person):
    if person == 'tommy':
        sheet = 0
    elif person == 'chad':
        sheet = 1
    elif person == 'kaya':
        sheet = 2
    elif person == 'twohey':
        sheet = 3
    elif person == 'majers':
        sheet = 4
    elif person == 'tori':
        sheet = 5
    elif person == 'kayla':
        sheet = 6
    place = input("What Week Is This? 1,2,3,4,5?: ") # This will move the entry one place over for each week
    place = int(place)
    main(sheet, everything,place)


print('DONT FORGET TO CHANGE TICKER')
person = input("Whos Data Is Going In: ")
get_name(person)
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

This looks very interesting. Well done!


Here is some nitpicking:

from yahoofinancials import YahooFinancials
import re
import pygsheets
import pandas as pd
import datetime
  • Organise these imports in following way: builtins, third-party then first-party.
 def main(sheet, everything,place):
  • Name of this function is sloppy. Use main function as an entry-point.
  • Name the function as a verb phrase or that explains what it is doing.
  • What is everything here? I can see that it is defined outside as well.
  • Avoid using everything as a name. It is very vague.
for i in tickers:
    tick = YahooFinancials(i)
  • What is i here? Reserve i for integer indexes. These are ticker_names.
  • for ticker_name in tickers is more readable.
tickers = ['XOM', 'JNJ', 'TR', 'CRON', 'HSY', 'FL', 'PLNT', 'MCD', 'ARLP', 'LULU', 'RCII', 'DELL', 'DNKN', 'DIS']
  • Load this from a JSON file.
def get_name(person):
  • This function doesn't get you anything. There is no return.
  • Why does this call main?
  • Name to sheet mapping can probably be loaded from a JSON as well.
adjclose, PY to Gsheet Test
  • Perform extract constant refactoring on strings like these and remove magic values.

A magic number is a direct usage of a number in the code.

For example, if you have (in Java):

public class Foo {
    public void setPassword(String password) {
         // don't do this
         if (password.length() > 7) {
              throw new InvalidArgumentException("password");
         }
    }
}

This should be refactored to:

public class Foo {
    public static final int MAX_PASSWORD_SIZE = 7;

    public void setPassword(String password) {
         if (password.length() > MAX_PASSWORD_SIZE) {
              throw new InvalidArgumentException("password");
         }
    }
}

From: https://stackoverflow.com/questions/47882/what-is-a-magic-number-and-why-is-it-bad


  • Summary - This code is very hard to understand. Functions do things that are completely different from function-name. Variable names are vague. Contains lot of hard-coded values that can be extracted to a JSON or some other kind of config. Contains magic values that should be converted to meaningful constants.
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.