feat: add ex3
add parametrized type, union, enum, alias
This commit is contained in:
		@@ -6,10 +6,33 @@ trait Person {
 | 
			
		||||
  val name: String
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
case class Artist(name: String) extends Person
 | 
			
		||||
case class Singer(name: String) extends Person
 | 
			
		||||
 | 
			
		||||
case class Writer(name: String) extends Person
 | 
			
		||||
 | 
			
		||||
case class Producer(name: String) extends Person
 | 
			
		||||
class Album(title: String, label: String)
 | 
			
		||||
 | 
			
		||||
// The parametrized type Artist can be a Singer, a Writer or a Producer
 | 
			
		||||
// They do a different creation action
 | 
			
		||||
class Artist[A <: Person](val person: A) {
 | 
			
		||||
  def create(): String = {
 | 
			
		||||
    person match {
 | 
			
		||||
      case s: Singer => s"${s.name} sing"
 | 
			
		||||
      case w: Writer => s"${w.name} write"
 | 
			
		||||
      case p: Producer => s"${p.name} produce"
 | 
			
		||||
      case _ => s"${person.name} create"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Defined a MusicGender as en enum
 | 
			
		||||
enum MusicGenre:
 | 
			
		||||
  case Rock, Soul, Blues, Folk, Funk, Reggae, HipHop, NewWave, Electro, Metal
 | 
			
		||||
 | 
			
		||||
// Define an Album with a union between a String and a MusicGenre
 | 
			
		||||
class Album(title: String, label: String, genre: String|MusicGenre)
 | 
			
		||||
 | 
			
		||||
class Streak(val s: String) {
 | 
			
		||||
  val streak: Option[Int] = {
 | 
			
		||||
    val regex = "\\d+".r
 | 
			
		||||
@@ -23,8 +46,9 @@ class Streak(val s: String) {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Position(val p: String) {
 | 
			
		||||
  val position: Option[Int] = {
 | 
			
		||||
  val pos: Option[Int] = {
 | 
			
		||||
    val regex = "\\d+".r
 | 
			
		||||
    regex.findFirstIn(p) match {
 | 
			
		||||
      case Some(value) => Some(Integer.parseInt(value))
 | 
			
		||||
@@ -33,15 +57,24 @@ class Position(val p: String) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Defined a type alias Rank which is a tuple of Streak and Position
 | 
			
		||||
// Streak and Position are linked together, it's why there are regrouped in the Rank type alias
 | 
			
		||||
type Rank = (Streak, Position)
 | 
			
		||||
 | 
			
		||||
// Defined an intersection type of Artist & Writer & Producer
 | 
			
		||||
// Defined with an alias : God
 | 
			
		||||
// It's a way to define a type that is a combination of other types
 | 
			
		||||
// If an Artist is also a Writer and a Producer, it's basically a God of the music
 | 
			
		||||
type God = Singer & Writer & Producer
 | 
			
		||||
 | 
			
		||||
class Song(
 | 
			
		||||
  val title: String,
 | 
			
		||||
  val description: Option[String],
 | 
			
		||||
  val artist: List[Artist],
 | 
			
		||||
  val writer: List[Writer],
 | 
			
		||||
  val producer: List[Producer],
 | 
			
		||||
  val singer: List[Artist[Singer]],
 | 
			
		||||
  val writer: List[Artist[Writer]],
 | 
			
		||||
  val producer: List[Artist[Producer]],
 | 
			
		||||
  val album: Option[Album],
 | 
			
		||||
  val streak: Streak,
 | 
			
		||||
  val position: Position
 | 
			
		||||
  val rank: Rank
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -50,12 +83,27 @@ case class TopSongs(songs: List[Song] = List()) {
 | 
			
		||||
    TopSongs(song :: songs)
 | 
			
		||||
  }
 | 
			
		||||
  def printSongs(): Unit = {
 | 
			
		||||
    songs.foreach(song => println(
 | 
			
		||||
      s"${song.title} by ${song.artist.map(_.name).mkString(", ")} " +
 | 
			
		||||
        s"produced by ${song.producer.map(_.name).mkString(", ")} " +
 | 
			
		||||
        s"spent ${song.streak.streak.getOrElse("no")} weeks " +
 | 
			
		||||
        s"on the charts on Pos. ${song.position.position.getOrElse("NA")}"
 | 
			
		||||
    ))
 | 
			
		||||
    songs.foreach(song => {
 | 
			
		||||
      val title = song.title
 | 
			
		||||
      val singer = song.singer
 | 
			
		||||
      val producers = song.producer.map(_.create()).mkString(", ")
 | 
			
		||||
      val streak = song.rank._1.streak.getOrElse("no")
 | 
			
		||||
      val pos = song.rank._2.pos.getOrElse("NA")
 | 
			
		||||
 | 
			
		||||
      if (singer.exists(a => {
 | 
			
		||||
        a.isInstanceOf[God]
 | 
			
		||||
      })) {
 | 
			
		||||
        println(s"$title by God ${singer.map(_.person.name).mkString(", ")} spent $streak weeks on the charts on Pos. $pos")
 | 
			
		||||
      } else {
 | 
			
		||||
        println(
 | 
			
		||||
          s"$title by ${singer.map(_.person.name).mkString(", ")}. " +
 | 
			
		||||
            s"$producers this song that " +
 | 
			
		||||
            s"spent $streak weeks " +
 | 
			
		||||
            s"on the charts on Pos. $pos"
 | 
			
		||||
        )
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -66,15 +114,22 @@ case class TopSongs(songs: List[Song] = List()) {
 | 
			
		||||
  val reader = CSVReader.open(new File("src/main/resources/songs.csv"))
 | 
			
		||||
  val allRows = reader.allWithHeaders()
 | 
			
		||||
  for (row <- allRows) {
 | 
			
		||||
    val title = row("title")
 | 
			
		||||
    val description = row("description")
 | 
			
		||||
    val singer = List(Artist[Singer](Singer(row("artist"))))
 | 
			
		||||
    val writers = List(Artist[Writer](Writer(row("writers"))))
 | 
			
		||||
    val producers = List(Artist[Producer](Producer(row("producer"))))
 | 
			
		||||
    val album = Some(Album(row("appears on"), "NA", null))
 | 
			
		||||
    val rank = (Streak(row("streak")), Position(row("position")))
 | 
			
		||||
 | 
			
		||||
    val s = Song(
 | 
			
		||||
      title = row("title"),
 | 
			
		||||
      description = Some(row("description")),
 | 
			
		||||
      artist = List(Artist(row("artist"))),
 | 
			
		||||
      writer = List(Writer(row("writers"))),
 | 
			
		||||
      producer = List(Producer(row("producer"))),
 | 
			
		||||
      album = Some(Album(row("appears on"), "NA")),
 | 
			
		||||
      streak = Streak(row("streak")),
 | 
			
		||||
      position = Position(row("position"))
 | 
			
		||||
      title = title,
 | 
			
		||||
      description = Some(description),
 | 
			
		||||
      singer = singer,
 | 
			
		||||
      writer = writers,
 | 
			
		||||
      producer = producers,
 | 
			
		||||
      album = album,
 | 
			
		||||
      rank = rank
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    // add the song to the TopSongs object
 | 
			
		||||
@@ -82,5 +137,7 @@ case class TopSongs(songs: List[Song] = List()) {
 | 
			
		||||
  }
 | 
			
		||||
  reader.close()
 | 
			
		||||
 | 
			
		||||
  val foo: Boolean = topSongs.songs.exists(s => s.rank._1.streak.contains(1))
 | 
			
		||||
 | 
			
		||||
  // print the songs
 | 
			
		||||
  topSongs.printSongs()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user