Home > other >  searching a file for a line and starting a second search from there
searching a file for a line and starting a second search from there

Time:08-29

I have a file with a bunch of albums and the list of songs of each album after it. Names of albums start with # and names of songs start with *. I'm trying to make a script that will give me all the songs in a specific album but it keeps printing all the songs in the entire file. Here is the code I wrote

def song_list(album):
    albumDB = open('Pink_Floyd_DB.txt','r')
    song_list = []
    i = 0
    lines = albumDB.readlines()    
    for line in lines:
        if album in line:
            for song_name in lines:
                if '*' in song_name:
                    song = song_name.split('::', 1)[0]
                    song_list.insert(i,song)
                    i  = 1
    for song in song_list:
        print(song)

CodePudding user response:

Your code explicitly loops over all the lines, and prints all of the songs from all albums each time it sees a matching album (with double newlines, because print adds one of its own). You are also reinventing list.append() for no good reason.

If I'm guessing correctly that your file looks something like

# The Wall
* Another Brick in the Wall Pt 1
* Comfortably Numb
* Vera
# Wish You Were Here
* Shine On You Crazy Diamond
* Wish You Were Here

then you will simply want to read up to the next # line.

with open(file) as songs:
    found = False
    for line in songs:
        line = line.rstrip("\n")
        if line == "# "   album:
            found = True
            continue
        if line.startswith("#"):
            if found:
                break
        if line.startswith("*") and found:
            print(line.lstrip("* "))

A better approach for a more complex program would be to open and parse the file just once, then manipulate the resulting structure in memory. But then, a better solution still is to ditch this ad-hoc format, and save your database in a standard machine-readable format like JSON or YAML. Here's a simple YAML stucture of the data above:

---
The Wall:
- Another Brick in the Wall Pt 1
- Comfortably Numb
- Vera
Wish You Were Here:
- Shine On You Crazy Diamond
- Wish You Were Here

and you'd read it with

import yaml

with open(yamlfile) as data:
    albums = yaml.safe_load(data)

Now, albums["The Wall"] returns the list of songs from that album.

CodePudding user response:

You can create a <key, values> dictionary in which the keys are the album names and the values the list of corresponding songs dict_song: <albums, songs>.

dict_album = {}
with open(r'album.txt') as text:
    album = ''
    song = ''
    for line in text:
        #line = line.rstrip("\n")
        line = line.strip()
        if line.startswith('#'):
            album = line.replace("#", "", 1).strip() # remove only first occurency 
            dict_album[album] = []
        elif line.startswith('*'):
            song = line.replace("*", "", 1).strip() # remove only first occurency 
            dict_album[album].append(song)
        else:
            # should never occur
            continue

To access the dictionary you only need to access it directly by key, or by using the .get() function, which takes as its first parameter the key (album name) and optionally you can put as a second parameter a value that will be returned when the key is not found in the dictionary (eg. "Album not found")

query_album = "The Wall"
print(dict_album.get("The Wall", "Album not found"))

and you get the list of songs:

['Another Brick in the Wall Pt 1', 
 'Comfortably Numb', 
 'Vera'] 
  • Related