Java Java Data Structures Efficiency! Implement Chooser UI

Exception in thread "main" java.util.UnknownFormatConversionException: Conversion = 'N'

After responding to the prompt to enter the URL, I get the following message:


Exception in thread "main" java.util.UnknownFormatConversionException: Conversion = 'N'
at java.util.Formatter$FormatSpecifier.conversion(Formatter.java:2691)
at java.util.Formatter$FormatSpecifier.<init>(Formatter.java:2720)
at java.util.Formatter.parse(Formatter.java:2560)
at java.util.Formatter.format(Formatter.java:2501)
at java.io.PrintStream.format(PrintStream.java:970)
at java.io.PrintStream.printf(PrintStream.java:871)
at com.teamtreehouse.KaraokeMachine.run(KaraokeMachine.java:51)
at Karaoke.main(Karaoke.java:10)


I don't know how to fix this error. It would be helpful if someone might point out the problem, or (better yet), help me understand how to figure this message out myself.

Here is my code:

For Karaoke.java:


import com.teamtreehouse.KaraokeMachine;
import com.teamtreehouse.model.Song;
import com.teamtreehouse.model.SongBook;

public class Karaoke {

  public static void main(String[] args) {
    SongBook songBook = new SongBook();
    KaraokeMachine machine = new KaraokeMachine(songBook);
    machine.run();
  }
}

For KaraokeMachine.java:


package com.teamtreehouse;

import com.teamtreehouse.model.Song;
import com.teamtreehouse.model.SongBook;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class KaraokeMachine {
  private SongBook mSongBook;
  private BufferedReader mReader;
  private Map<String, String> mMenu;  

  public KaraokeMachine(SongBook songBook) {
    mSongBook = songBook;
    mReader = new BufferedReader(new InputStreamReader(System.in));
    mMenu = new HashMap<String, String>();
    mMenu.put("add", "Add a new song to the song book");
    mMenu.put("choose", "Choose a song to sing!");
    mMenu.put("quit", "Give up. Exit the program");
  }

  private String promptAction() throws IOException {
    System.out.printf("There are %d songs available. Your options are: %n",
                      mSongBook.getSongCount());
    for (Map.Entry<String, String> option : mMenu.entrySet()) {
      System.out.printf("%s - %s %n",
                        option.getKey(),
                        option.getValue());
    }
    System.out.print("What do you want to do: ");
    String choice = mReader.readLine();
    return choice.trim().toLowerCase();
  }

  public void run() {
    String choice = "";
    do {
      try {
        choice = promptAction();
        switch(choice) {
          case "add":
          Song song = promptNewSong();
          mSongBook.addSong(song);
          System.out.printf("%s added!   %N%N", song);
            break;
          case "choose":
            String artist = promptArtist();
            Song artistSong = promptSongForArtist(artist);
          // TODO: Add to a song queue
          System.out.printf("You chose: %s %n", artistSong);
            break;
          case "quit":
            System.out.println("Thanks for playing!");
            break;
          default: 
            System.out.printf("Unknown choice: %s'. Try again. %n%n%n", 
                              choice);
        }
      } catch (IOException ioe) {
        System.out.println("Problem with input");
        ioe.printStackTrace();
      }
    } while(!choice.equals("quit"));
  } 

    private Song promptNewSong() throws IOException {
      System.out.print("Enter the artist's name: ");
      String artist = mReader.readLine();
      System.out.print("Enter the title: ");
      String title = mReader.readLine();
      System.out.print("Enter the video URL: ");
      String videoUrl = mReader.readLine();
      return new Song(artist, title, videoUrl);
    }

  private String promptArtist() throws IOException {
    System.out.println("Available artists: ");
    List<String> artists = new ArrayList<>(mSongBook.getArtists());
    int index = promptForIndex(artists);
    return artists.get(index);    
  }

  private Song promptSongForArtist(String artist) throws IOException {
    List<Song> songs = mSongBook.getSongsForArtist(artist);
    List<String> songTitles = new ArrayList<>();
    for (Song song : songs) {
      songTitles.add(song.getTitle());
    }
    int index = promptForIndex(songTitles);
    return songs.get(index);
  }  

  private int promptForIndex(List<String> options) throws IOException {
    int counter = 1;
    for (String option : options) {
      System.out.printf("%d.) %s %n", counter, option);
      counter++;
    }
    String optionAsString = mReader.readLine();
    int choice = Integer.parseInt(optionAsString.trim());
    System.out.print("Your choice:  ");
    return choice -1;
  }
  }

For Song.java: _________________________________________________-

package com.teamtreehouse.model;

public class Song {
  private String mArtist;
  private String mTitle;
  private String mVideoUrl;

  public Song(String artist, String title, String videoUrl) {
    mArtist = artist;
    mTitle = title;
    mVideoUrl = videoUrl;
  }

  public String getTitle() {
    return mTitle;
  }

  public String getArtist() {
    return mArtist;
  }

  public String getVideoUrl() {
    return mVideoUrl;
  }


  @Override
  public String toString() {
    return String.format("Song: %s by %s", mTitle, mArtist);
  }
}

For SongBook.Java:


package com.teamtreehouse.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class SongBook {
  private List<Song> mSongs;

  public SongBook() {
  mSongs = new ArrayList<Song>();
}

  public void addSong(Song song) {
    mSongs.add(song);
  }

  public int getSongCount() {
    return mSongs.size();
  }

  // FIXME: This should be cashed!
  private Map<String, List<Song>> byArtist() {
    Map<String, List<Song>> byArtist = new HashMap<>();
    for (Song song : mSongs) {
      List<Song> artistSongs = byArtist.get(song.getArtist());
      if (artistSongs == null) {
        artistSongs = new ArrayList<>();
        byArtist.put(song.getArtist(), artistSongs);
      }
      artistSongs.add(song);
    }
    return byArtist;
  }

  public Set<String> getArtists() {
    return byArtist().keySet();
  }

  public List<Song> getSongsForArtist(String artistName) {
    return byArtist().get(artistName);
  }

}

1 Answer

D mk
D mk
13,225 Points

Try %n%n for line breaks in code below.

      System.out.printf("%s added!   %N%N", song);