I’ve coded a program which helps me to quickly toggle between lyrics of songs. It reads the lyrics from .lyr file and prints them out to me.
Here’s a simplified version, without any additional features like edit_line(). The problem still appears with this code.
import os
class Lyrics:
def __init__(self, file):
'''Initialize new Lyrics object'''
self.file = file.replace("/", "\\")
self.path = self.file.rsplit("\\", 1)[0] + "\\"
self.suffix = "." + self.file.rsplit(".")[-2]
self.name = self.file\
.replace(self.path, "")\
.replace(".lyr", "")\
.replace(self.suffix, "")
def draw(self):
'''Draw lyrics on user's screen'''
maxlen = len(str(len(self.content)))
print("[[ %s ]]"%self.name)
for i,line in enumerate(self.content):
print("%i %s"%(i+1, line), end="")
def play(self):
'''View lyrics'''
with open(self.file, "r") as f:
self.content = f.readlines()
#os.system("cls")
self.draw()
input("[[ Press enter to quit ... ]]")
def main(directory):
# Get lyric files from directory
lyric_files = []
for file in os.listdir(directory):
if file.endswith(".lyr"):
lyric_files.append(Lyrics(directory + file))
# Create variable for showing messages to user
msg = ""
# Main loop
while True:
# Print lyric files
#os.system("cls")
for i, file in enumerate(lyric_files):
print("%i :: %s"%(i+1, file.name))
# Handle input
cmd = input("%s>"%msg)
if cmd == "bye":
break
try:
lyric_files[int(cmd)-1].play()
msg = ""
except ValueError:
msg = "ValueError: Input must be an integer\n"
except IndexError:
msg = "IndexError: Integer must be between 1 and %i\n"%len(lyric_files)
if __name__ == "__main__":
main("E:\\documents\\lyrics\\")
Files in E:\documents\lyrics\ are named with following format:
Artist - Song.format.lyr`
For example:
E:\documents\lyrics\Adele - Set Fire to the Rain.mp3.lyr
When I open the program, it lists all the files as it’s supposed to, asking me for an input after:
1 :: Adele - Set Fire to the Rain
2 :: Eminem - Not Afraid
3 :: Nicki Minaj - Starships
>
When I open up lyrics for Set Fire to the Rain with index 1, they open up just perfectly. However, when I try to open lyrics for Not Afraid, I can see around 50 lines of the lyrics on the output, when the lyric file is actually around 120 lines long. It then asks me for an input from the main() function with ValueError like so:
1 first_line_in_lyrics
2 second_line_in_lyrics
i ...
42 fourty_second_line_in_lyrics
43 fourty_third_line_in_lyrics
1 :: Adele - Set Fire to the Rain
2 :: Eminem - Not Afraid
3 :: Nicki Minaj - Starships
ValueError: Input must be an integer
>
The files are pretty much identical to each other (well of course the lyrics are different). The program works just fine on IDLE, but not on python command line.
This problem seems pretty weird, but not impossible. Here’s what we got at the moment:
draw()method.If you are CERTAIN that your draw function looks EXACTLY like this (took me a while to figure out the
maxlenthing):We’re only left with the fact that there’s something wrong with
self.contentand/or the file content itself.Simply put: I’m 99% sure there are some characters in your file which can be printed by IDLE but not by python command line. Such characters could be anything:
%,',",´,|,#, or even some invisible characters which you can’t see without scrolling through them with your arrow keys.If you could post the content of your lyrics, I could try helping more. Especially the lines which get printed last, and the first lines which don’t get printed at all.