1
def retrieveSong(): # Function that retrieves a random song from the file.
    file = open("Songs.csv", "r")
    count = 0

    for line in file:   # Finds out how many lines (and therefore songs) there are.
        count += 1

    length = count
    print(length)

    randomIndex = randint(0, length) # Picks a random line. 
    print(randomIndex)
    count = 0
    print(count)
     
    for line in file:   # Loops through the file until it finds the right line.
        if count == randomIndex:
            song = line.split(",")
        count += 1

    for item in song: # Gets rid of the \n at the end of each line.
        item = str.strip(item)
    file.close()
    return song    # Returns the song name and artist, in a list where song[0] is the name and song[1] is the artist.

The program is supposed to retrieve a random song from a CSV file. The song is retrieved into a list, split at each comma, so that it will be ['song name', 'artist']. Most of it works fine - the only parts that don't seem to work are the final two 'paragraphs':

for line in file:   # Loops through the file until it finds the right line.
    if count == randomIndex:
        song = line.split(",")
    count += 1

for item in song: # Gets rid of the \n at the end of each line.
    item = str.strip(item)
file.close()
return song    # Returns the song name and artist, in a list where song[0] is the name and song[1] is the artist.

I keep getting an error telling me that the line that says return song is trying to return a variable that has never been assigned, which leads me to believe that something is wrong with the following lines.

for line in file:   # Iterates through the file until it finds the right line.
    if count == randomIndex:
        song = line.split(",")
    count += 1

I'm fairly certain that, for some reason, the program doesn't ever recognise count == randomIndex as True, even though it's supposed to. I've added print statements everywhere to (attempt to) work out what parts aren't working as expected, but I have no idea why. I'm not a Python expert, so I don't really know what to do.

2 Answers2

3

You need to seek back to the beginning of the file if you want to iterate over it twice:

def retrieveSong(): # Function that retrieves a random song from the file.
    file = open("Songs.csv", "r")
    count = 0

    # Iterates once
    for line in file:   
        count += 1

    # file is now empty
    # so go back to the beginning
    _ = file.seek(0)

    # now you can iterate over it again
    for line in file:
        if count == randomIndex:
           song = [item.strip() for item in line.split(',')]
           break # break out of the loop
        count += 1

While we're here though, it's better to use with when opening files:

with open(path) as fh:
    for line in fh:
        # do things

And when counting, use enumerate:

length = sum(1 for _ in file)

for i, line in enumerate(file):
    if i == randomIndex:
        # do things
C.Nivs
  • 12,353
  • 2
  • 19
  • 44
  • You should also recommend the use of the `csv` module. –  Sep 29 '21 at 11:39
  • @EmpressSvetlana while `csv` is good for OPs use case, I'm not trying to do a full code review here. There are a lot of fixes, really this whole thing could be boiled down to `random.choice(fh).split(',')` to grab a random line – C.Nivs Sep 29 '21 at 11:40
  • @PCM- That's true! I assumed because the OP was new, they were unaware of the `pandas` module. –  Sep 29 '21 at 11:41
  • 1
    @EmpressSvetlana and it's not necessary to "use" `csv` module, sometimes, it takes time to learn. – PCM Sep 29 '21 at 11:42
  • @PCM suggesting `pandas` unfortunately doesn't do anything to fix the misconception here. A fundamental concept is that the file handle is exhausted when iterated over, `pandas.read_csv` might do nicely to read the csv, but it also introduces a wildly different data structure – C.Nivs Sep 29 '21 at 11:43
  • @C.Nivs, I know, I never suggested it, but I merely wanted to say that here `csv` might be irrelevant, I guess I should have added my other comment to it. – PCM Sep 29 '21 at 11:44
0

Your code with minute changes should work fine

def retrieveSong():  # Function that retrieves a random song from the file.
    filename = "tmp.txt"
    # Finds out how many lines (and therefore songs) there are.
    with open(filename) as f:
        length = sum(1 for line in f)

    randomIndex = randint(0, length)  # Picks a random line.
    count = 0
    file = open(filename, "r")
    for line in file:  # Loops through the file until it finds the right line.
        print(line)
        if count == randomIndex:
            song = line.split(",")
        count += 1

    for item in song:  # Gets rid of the \n at the end of each line.
        item = str.strip(item)
    file.close()
    return song  # Returns the song name and artist, in a list where song[0] is the name and song[1] is the artist.
abhira0
  • 280
  • 1
  • 11