feat: add ex3
add parametrized type, union, enum, alias
This commit is contained in:
		@@ -6,10 +6,33 @@ trait Person {
 | 
				
			|||||||
  val name: String
 | 
					  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 Writer(name: String) extends Person
 | 
				
			||||||
 | 
					
 | 
				
			||||||
case class Producer(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) {
 | 
					class Streak(val s: String) {
 | 
				
			||||||
  val streak: Option[Int] = {
 | 
					  val streak: Option[Int] = {
 | 
				
			||||||
    val regex = "\\d+".r
 | 
					    val regex = "\\d+".r
 | 
				
			||||||
@@ -23,8 +46,9 @@ class Streak(val s: String) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Position(val p: String) {
 | 
					class Position(val p: String) {
 | 
				
			||||||
  val position: Option[Int] = {
 | 
					  val pos: Option[Int] = {
 | 
				
			||||||
    val regex = "\\d+".r
 | 
					    val regex = "\\d+".r
 | 
				
			||||||
    regex.findFirstIn(p) match {
 | 
					    regex.findFirstIn(p) match {
 | 
				
			||||||
      case Some(value) => Some(Integer.parseInt(value))
 | 
					      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(
 | 
					class Song(
 | 
				
			||||||
  val title: String,
 | 
					  val title: String,
 | 
				
			||||||
  val description: Option[String],
 | 
					  val description: Option[String],
 | 
				
			||||||
  val artist: List[Artist],
 | 
					  val singer: List[Artist[Singer]],
 | 
				
			||||||
  val writer: List[Writer],
 | 
					  val writer: List[Artist[Writer]],
 | 
				
			||||||
  val producer: List[Producer],
 | 
					  val producer: List[Artist[Producer]],
 | 
				
			||||||
  val album: Option[Album],
 | 
					  val album: Option[Album],
 | 
				
			||||||
  val streak: Streak,
 | 
					  val rank: Rank
 | 
				
			||||||
  val position: Position
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -50,12 +83,27 @@ case class TopSongs(songs: List[Song] = List()) {
 | 
				
			|||||||
    TopSongs(song :: songs)
 | 
					    TopSongs(song :: songs)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  def printSongs(): Unit = {
 | 
					  def printSongs(): Unit = {
 | 
				
			||||||
    songs.foreach(song => println(
 | 
					    songs.foreach(song => {
 | 
				
			||||||
      s"${song.title} by ${song.artist.map(_.name).mkString(", ")} " +
 | 
					      val title = song.title
 | 
				
			||||||
        s"produced by ${song.producer.map(_.name).mkString(", ")} " +
 | 
					      val singer = song.singer
 | 
				
			||||||
        s"spent ${song.streak.streak.getOrElse("no")} weeks " +
 | 
					      val producers = song.producer.map(_.create()).mkString(", ")
 | 
				
			||||||
        s"on the charts on Pos. ${song.position.position.getOrElse("NA")}"
 | 
					      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 reader = CSVReader.open(new File("src/main/resources/songs.csv"))
 | 
				
			||||||
  val allRows = reader.allWithHeaders()
 | 
					  val allRows = reader.allWithHeaders()
 | 
				
			||||||
  for (row <- allRows) {
 | 
					  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(
 | 
					    val s = Song(
 | 
				
			||||||
      title = row("title"),
 | 
					      title = title,
 | 
				
			||||||
      description = Some(row("description")),
 | 
					      description = Some(description),
 | 
				
			||||||
      artist = List(Artist(row("artist"))),
 | 
					      singer = singer,
 | 
				
			||||||
      writer = List(Writer(row("writers"))),
 | 
					      writer = writers,
 | 
				
			||||||
      producer = List(Producer(row("producer"))),
 | 
					      producer = producers,
 | 
				
			||||||
      album = Some(Album(row("appears on"), "NA")),
 | 
					      album = album,
 | 
				
			||||||
      streak = Streak(row("streak")),
 | 
					      rank = rank
 | 
				
			||||||
      position = Position(row("position"))
 | 
					 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // add the song to the TopSongs object
 | 
					    // add the song to the TopSongs object
 | 
				
			||||||
@@ -82,5 +137,7 @@ case class TopSongs(songs: List[Song] = List()) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  reader.close()
 | 
					  reader.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val foo: Boolean = topSongs.songs.exists(s => s.rank._1.streak.contains(1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // print the songs
 | 
					  // print the songs
 | 
				
			||||||
  topSongs.printSongs()
 | 
					  topSongs.printSongs()
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user