-4

I've got a program that takes information about a song's chart run on a user's personal charts from its chart page and inputs that data into a Google spreadsheet, and as part of that I use a bunch of if statements both to initialise a dictionary based on how long the user's charts are and to determine if the chart run was consecutive or not.

The code that I have works, but feels very inefficient and messy. Is there any way to do this in a loop instead? (And yes, I have seen this question, but I don't feel like its answers are particularly useful for my situation.)

length_of_charts = int(input("Enter how many songs you have in each of your weekly charts: "))

weeks_in_range = {"Weeks at #1": [0, "Consecutive"]}
if length_of_charts > 3:
    weeks_in_range["Weeks in Top 3"] = [0, "Consecutive"]
if length_of_charts > 5:
    weeks_in_range["Weeks in Top 5"] = [0, "Consecutive"]
if length_of_charts > 10:
    weeks_in_range["Weeks in Top 10"] = [0, "Consecutive"]
if length_of_charts > 20:
    weeks_in_range["Weeks in Top 20"] = [0, "Consecutive"]
if length_of_charts > 40:
    weeks_in_range["Weeks in Top 40"] = [0, "Consecutive"]
if length_of_charts > 75:
    weeks_in_range["Weeks in Top 75"] = [0, "Consecutive"]
if length_of_charts > 100:
    weeks_in_range["Weeks in Top 100"] = [0, "Consecutive"]
if length_of_charts != 1:
    weeks_in_range["Weeks in Top " + str(length_of_charts)] = [0, "Consecutive"]
song_charts = driver1.find_elements_by_xpath(song_charts_path)
#finds all of the charts that the song is on
song_chart_runs = [[None for i in range(2)] for j in range(len(song_charts))]
for i, song_chart in enumerate(song_charts):
    song_chart_runs[i][0] = int(song_chart.get_attribute("innerHTML").split("""<span class="history-position">""")[1].split("</span>")[0])
    #variable will be assigned as the song's chart position on that week
    song_chart_runs[i][1] = datetime.strptime(song_chart.get_attribute("innerHTML").split("</span></a></span>")[0].split(">")[-1], '%B %d, %Y')
    #variable will be assigned as the date of the chart
    if song_chart_runs[i][0] == 1:
        weeks_in_range["Weeks at #1"][0] = weeks_in_range["Weeks at #1"][0] + 1
        if i > 0 and weeks_in_range["Weeks at #1"][0] > 1 and (song_chart_runs[i-1][0] != 1 or song_chart_runs[i-1][1] + timedelta(days=7) != song_chart_runs[i][1]):
            weeks_in_range["Weeks at #1"][1] = "Non-Consecutive"
    if song_chart_runs[i][0] <= 3 and song_chart_runs[i][0] <= length_of_charts and length_of_charts > 3:
        weeks_in_range["Weeks in Top 3"][0] = weeks_in_range["Weeks in Top 3"][0] + 1
        if i > 0 and weeks_in_range["Weeks in Top 3"][0] > 1 and (song_chart_runs[i-1][0] > 3 or song_chart_runs[i-1][1] + timedelta(days=7) != song_chart_runs[i][1]):
            weeks_in_range["Weeks in Top 3"][1] = "Non-Consecutive"
    if song_chart_runs[i][0] <= 5 and song_chart_runs[i][0] <= length_of_charts and length_of_charts > 5:
        weeks_in_range["Weeks in Top 5"][0] = weeks_in_range["Weeks in Top 5"][0] + 1
        if i > 0 and weeks_in_range["Weeks in Top 5"][0] > 1 and (song_chart_runs[i-1][0] > 5 or song_chart_runs[i-1][1] + timedelta(days=7) != song_chart_runs[i][1]):
            weeks_in_range["Weeks in Top 5"][1] = "Non-Consecutive"
    if song_chart_runs[i][0] <= 10 and song_chart_runs[i][0] <= length_of_charts and length_of_charts > 10:
        weeks_in_range["Weeks in Top 10"][0] = weeks_in_range["Weeks in Top 10"][0] + 1
        if i > 0 and weeks_in_range["Weeks in Top 10"][0] > 1 and (song_chart_runs[i-1][0] > 10 or song_chart_runs[i-1][1] + timedelta(days=7) != song_chart_runs[i][1]):
            weeks_in_range["Weeks in Top 10"][1] = "Non-Consecutive"
    if song_chart_runs[i][0] <= 20 and song_chart_runs[i][0] <= length_of_charts and length_of_charts > 20:
        weeks_in_range["Weeks in Top 20"][0] = weeks_in_range["Weeks in Top 20"][0] + 1
        if i > 0 and weeks_in_range["Weeks in Top 20"][0] > 1 and (song_chart_runs[i-1][0] > 20 or song_chart_runs[i-1][1] + timedelta(days=7) != song_chart_runs[i][1]):
            weeks_in_range["Weeks in Top 20"][1] = "Non-Consecutive"
    if song_chart_runs[i][0] <= 40 and song_chart_runs[i][0] <= length_of_charts and length_of_charts > 40:
        weeks_in_range["Weeks in Top 40"][0] = weeks_in_range["Weeks in Top 40"][0] + 1
        if i > 0 and weeks_in_range["Weeks in Top 40"][0] > 1 and (song_chart_runs[i-1][0] > 40 or song_chart_runs[i-1][1] + timedelta(days=7) != song_chart_runs[i][1]):
            weeks_in_range["Weeks in Top 40"][1] = "Non-Consecutive"
    if song_chart_runs[i][0] <= 75 and song_chart_runs[i][0] <= length_of_charts and length_of_charts > 75:
        weeks_in_range["Weeks in Top 75"][0] = weeks_in_range["Weeks in Top 75"][0] + 1
        if i > 0 and weeks_in_range["Weeks in Top 75"][0] > 1 and (song_chart_runs[i-1][0] > 75 or song_chart_runs[i-1][1] + timedelta(days=7) != song_chart_runs[i][1]):
            weeks_in_range["Weeks in Top 75"][1] = "Non-Consecutive"
    if song_chart_runs[i][0] <= 100 and song_chart_runs[i][0] <= length_of_charts and length_of_charts > 100:
        weeks_in_range["Weeks in Top 100"][0] = weeks_in_range["Weeks in Top 100"][0] + 1
        if i > 0 and weeks_in_range["Weeks in Top 100"][0] > 1 and (song_chart_runs[i-1][0] > 100 or song_chart_runs[i-1][1] + timedelta(days=7) != song_chart_runs[i][1]):
            weeks_in_range["Weeks in Top 100"][1] = "Non-Consecutive"
    if song_chart_runs[i][0] <= length_of_charts and length_of_charts != 1:
        weeks_in_range["Weeks in Top " + str(length_of_charts)][0] = weeks_in_range["Weeks in Top " + str(length_of_charts)][0] + 1
        if i > 0 and weeks_in_range["Weeks in Top " + str(length_of_charts)][0] > 1 and (song_chart_runs[i-1][0] > length_of_charts or song_chart_runs[i-1][1] + timedelta(days=7) != song_chart_runs[i][1]):
            weeks_in_range["Weeks in Top " + str(length_of_charts)][1] = "Non-Consecutive"
martineau
  • 119,623
  • 25
  • 170
  • 301
Foxes
  • 1,137
  • 3
  • 10
  • 19
  • 1
    Can you provide a little bit more context about what the input is, so that it makes sense for somebody who's not looking at the website you're scraping – Boris Verkhovskiy May 23 '21 at 23:24
  • Please go through the [intro tour](https://stackoverflow.com/tour), the [help center](https://stackoverflow.com/help) and [how to ask a good question](https://stackoverflow.com/help/how-to-ask) to see how this site works and to help you improve your current and future questions, which can help you get better answers. "Teach me how to write a simple loop" is off-topic for Stack Overflow. You have to make an honest attempt at the solution, and then ask a *specific* question about your implementation. Stack Overflow is not intended to replace existing tutorials and documentation. – Prune May 23 '21 at 23:26
  • 5
    Your code is not particularly inefficient, but it is messy. You have to learn how to extract the parts that change, and make a loop using a variable for those parts. This is a basic programming skill, one you learn from tutorials -- not a Stack Overflow issue. – Prune May 23 '21 at 23:27
  • This spaghetti code is going to be hell to maintain. show us how does the data from user's personal charts look like. – Yoshikage Kira May 23 '21 at 23:38
  • @Boris I added the relevant input and a couple of comments to the code to hopefully make it a little clearer. – Foxes May 23 '21 at 23:39
  • @Prune Would be helpful if you could link me to some of those resources, maybe I'm searching for the wrong thing but searching "how to loop an if statement with different values in Python" and similar searches hasn't yielded anything useful to me. – Foxes May 23 '21 at 23:40
  • 1
    Asking for tutorial resources is off topic. Again, refer to the posting guidelines. Also see [How much research](https://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-expected-of-stack-overflow-users) and the [Question Checklist](https://meta.stackoverflow.com/questions/260648/stack-overflow-question-checklist). Since you haven't made an effort of your own, you're not yet ready to post here. – Prune May 23 '21 at 23:42
  • Why can't you do `weeks_in_range[f"Weeks in Top {length_of_charts}"] = [0, "Consecutive"]` If would pretty much eliminate the use of all if statements. There are quite a lot of things wrong with this code. Personally I wouldn't scrape it and re write from scratch. – Yoshikage Kira May 23 '21 at 23:42
  • @Goion Because I want to be able to see how long a song has spent in a certain range, i.e. how long it spent at #1, in the Top 10, etc, not just how long it's spent on the chart in total. – Foxes May 23 '21 at 23:45
  • Still the approach to the problem is very messy and you need to rethink from clean slate. You might end up wasting more time trying to fix this and not get anything out of it. – Yoshikage Kira May 23 '21 at 23:47
  • 1
    If you want your working code reviewed, I suggest posting it on Stackexchange's [Code Review](https://codereview.stackexchange.com/) website — not here. – martineau May 24 '21 at 01:30

1 Answers1

0

I was able to figure out something a little bit less messy by using an array, probably still not the best way of doing it but it's the best that I could come up with.

length_of_charts = int(input("Enter how many songs you have in each of your weekly charts: "))
lengths = [3, 5, 10, 20, 40, 75, 100]

i = 0
weeks_in_range = {"Weeks at #1": [0, "Consecutive"]}
while length_of_charts > lengths[i]:
    weeks_in_range["Weeks in Top " + str(lengths[i])] = [0, "Consecutive"]
    i = i + 1
if length_of_charts > 1:
    weeks_in_range["Weeks in Top " + str(length_of_charts)] = [0, "Consecutive"]
song_charts = driver1.find_elements_by_xpath(song_charts_path)
#finds all of the charts that the song is on
song_chart_runs = [[None for i in range(2)] for j in range(len(song_charts))]
for i, song_chart in enumerate(song_charts):
    j = 0
    song_chart_runs[i][0] = int(song_chart.get_attribute("innerHTML").split("""<span class="history-position">""")[1].split("</span>")[0])
    #variable will be assigned as the song's chart position on that week
    song_chart_runs[i][1] = datetime.strptime(song_chart.get_attribute("innerHTML").split("</span></a></span>")[0].split(">")[-1], '%B %d, %Y')
    #variable will be assigned as the date of the chart
    if song_chart_runs[i][0] == 1:
        weeks_in_range["Weeks at #1"][0] = weeks_in_range["Weeks at #1"][0] + 1
        if i > 0 and weeks_in_range["Weeks at #1"][0] > 1 and (song_chart_runs[i-1][0] != 1 or song_chart_runs[i-1][1] + timedelta(days=7) != song_chart_runs[i][1]):
            weeks_in_range["Weeks at #1"][1] = "Non-Consecutive"
    while length_of_charts > lengths[j]:
        if song_chart_runs[i][0] <= length_of_charts and song_chart_runs[i][0] <= lengths[j]:
            weeks_in_range["Weeks in Top " + str(lengths[j])][0] = weeks_in_range["Weeks in Top " + str(lengths[j])][0] + 1
            if i > 0 and weeks_in_range["Weeks in Top " + str(lengths[j])][0] > 1 and (song_chart_runs[i-1][0] > lengths[j] or song_chart_runs[i-1][1] + timedelta(days=7) != song_chart_runs[i][1]):
                weeks_in_range["Weeks in Top " + str(lengths[j])][1] = "Non-Consecutive"
        j = j + 1
    if song_chart_runs[i][0] <= length_of_charts and length_of_charts != 1:
        weeks_in_range["Weeks in Top " + str(length_of_charts)][0] = weeks_in_range["Weeks in Top " + str(length_of_charts)][0] + 1
        if i > 0 and weeks_in_range["Weeks in Top " + str(length_of_charts)][0] > 1 and (song_chart_runs[i-1][0] > length_of_charts or song_chart_runs[i-1][1] + timedelta(days=7) != song_chart_runs[i][1]):
            weeks_in_range["Weeks in Top " + str(length_of_charts)][1] = "Non-Consecutive"
Foxes
  • 1,137
  • 3
  • 10
  • 19