Search code examples
pythonloopsiteratorpython-itertools

Problem with Itertools - next function (beginner-level Python user)


I am messing around with while and for loops in pycharm to understand them better, and I created a mockup game of operating a music player which involves some functions and loops I've been learning and researching. Ex. You'd input a command such as "shuffle" and a random song from the list of songs would play.

The problem is the "next" command isn't working. I'm having trouble getting the "next" song from the list to play. Essentially I want the command to cycle through the list of songs every time it's inputted. But no matter how any times I use the "next" function, it still only returns the first song from the list.

I tried instead moving the next() function to other parts of the code, but it still didn't work. What do you recommend I alter in my code to get the "next" command to work?

import random
import itertools
command = ""
player_on = False
paused = False
songs = iter([
    "Baby One More Time",
    "Hands Up",
    "I Believe in a Thing Called Love",
    "Unchained Melody",
    "Come On Eileen",
    "I Want It That Way"
])
next_song = next(songs, "end of playlist")

while True:
    command = input("What do you want to do?: ").lower()
    if command == "play":
        if player_on and not paused:
            print("Player is already on.")
            paused = False
        elif player_on and paused:
            paused = False
            print("un-paused")
        else:
            player_on = True
            paused = False
            print("Playing.")
    elif command == "pause":
        if paused and player_on:
            paused = True
            print("player already paused.")
        elif player_on and not paused:
            print(". . .")
            paused = True
        else:
            print("Turn player on first.")
    elif command == "shuffle":
        if player_on:
            print("Shuffles . . .")
            print(random.choice(songs))
        else:
            print("Turn player on first")
    elif command == "next":
        if player_on:
            paused = False
            print(f"Next song: {next_song}")
        else:
            print("Turn player on first.")
    elif command == "quit":
        if not player_on:
            print("Player is already off.")
        else:
            player_on = False
            break
    else:
        print("I don't understand that command.")


Solution

  • Use an index current_song_index to track the current song, initialize it with 0 before the loop and advance it every "next" command.

    import random
    import itertools
    command = ""
    player_on = False
    paused = False
    songs = [
        "Baby One More Time",
        "Hands Up",
        "I Believe in a Thing Called Love",
        "Unchained Melody",
        "Come On Eileen",
        "I Want It That Way"
    ]
    
    current_song_index = 0
    
    while True:
        command = input("What do you want to do?: ").lower()
        if command == "play":
            if player_on and not paused:
                print("Player is already on.")
                paused = False
            elif player_on and paused:
                paused = False
                print("un-paused")
            else:
                player_on = True
                paused = False
                print("Playing.")
        elif command == "pause":
            if paused and player_on:
                paused = True
                print("player already paused.")
            elif player_on and not paused:
                print(". . .")
                paused = True
            else:
                print("Turn player on first.")
        elif command == "shuffle":
            if player_on:
                print("Shuffles . . .")
                print(random.choice(songs))
            else:
                print("Turn player on first")
        elif command == "next":
            if player_on:
                paused = False
                current_song_index += 1
                if current_song_index < len(songs):                
                    print(f"Next song: {songs[current_song_index]}")
                else:
                    print('End of playlist')
                    current_song_index = 0
            else:
                print("Turn player on first.")
        elif command == "quit":
            if not player_on:
                print("Player is already off.")
            else:
                player_on = False
                break
        else:
            print("I don't understand that command.")