Compare commits
	
		
			2 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 4a8e87f444 | |||
| 780eab521b | 
| @@ -1,15 +1,38 @@ | ||||
| package TopSongs | ||||
| import scala.io.Source | ||||
| import java.io.File | ||||
| import com.github.tototoshi.csv._ | ||||
|  | ||||
| trait Person: | ||||
| trait Person { | ||||
|   val name: String | ||||
| } | ||||
|  | ||||
| case class Singer(name: String) extends Person | ||||
|  | ||||
| case class Artist(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,55 +57,87 @@ 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 | ||||
| ) | ||||
|  | ||||
|  | ||||
| object TopSongs { | ||||
|   var songs: List[Song] = List() | ||||
|   def addSong(song: Song): Unit = { | ||||
|     songs = song :: songs | ||||
| case class TopSongs(songs: List[Song] = List()) { | ||||
|   def addSong(song: Song): TopSongs = { | ||||
|     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" | ||||
|         ) | ||||
|       } | ||||
|  | ||||
|     }) | ||||
|   } | ||||
| } | ||||
|  | ||||
| @main def main(): Unit = | ||||
|   // create a new TopSongs object | ||||
|   val topSongs = TopSongs | ||||
|   var topSongs = TopSongs() | ||||
|  | ||||
|   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 | ||||
|     topSongs.addSong(s) | ||||
|     topSongs = topSongs.addSong(s) | ||||
|   } | ||||
|   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