Skip to content

Commit

Permalink
Merge model for airline's country and name
Browse files Browse the repository at this point in the history
  • Loading branch information
xavierguihot committed Apr 10, 2018
1 parent f14d3e4 commit 6c6804e
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 95 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ script: "sbt clean coverage test"
after_success: "sbt coverageReport coveralls"
notifications:
email:
- x.guihot@gmail.com
- x.guihot@gmail.com
- chemseddine.ouaari@amadeus.com
12 changes: 5 additions & 7 deletions src/main/scala/com/geobase/GeoBase.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.geobase
import com.geobase.load.Loader
import com.geobase.error.GeoBaseException
import com.geobase.model.{Duration, HOURS}
import com.geobase.model.{Airline, AirlineName, AirportOrCity, Country}
import com.geobase.model.{Airline, AirportOrCity, Country}
import com.geobase.model.{GeoType, DOMESTIC, CONTINENTAL, INTER_CONTINENTAL}

import scala.util.{Try, Success, Failure}
Expand Down Expand Up @@ -69,8 +69,6 @@ class GeoBase() extends Serializable {
Loader.loadAirportsAndCities()
private lazy val countries: Map[String, Country] = Loader.loadCountries()
private lazy val airlines: Map[String, Airline] = Loader.loadAirlines()
private lazy val airlineNames: Map[String, AirlineName] =
Loader.loadAirlineNames()

/** Returns the city associated to the given airport.
*
Expand Down Expand Up @@ -255,17 +253,17 @@ class GeoBase() extends Serializable {
/** Returns the name associated to the given airline.
*
* {{{
* assert(geoBase.nameForAirline("AF") == Success("Air France"))
* assert(geoBase.nameForAirline("#?") == Failure(GeoBaseException: Unknown airline "#?"))
* assert(geoBase.nameOfAirline("AF") == Success("Air France"))
* assert(geoBase.nameOfAirline("#?") == Failure(GeoBaseException: Unknown airline "#?"))
* }}}
*
* @param airline the airline IATA code (for instance AF) for which to get
* the associated country.
* the associated airline name.
* @return the name corresponding to the given airline (for instance
* Air France).
*/
def nameOfAirline(airline: String): Try[String] =
airlineNames
airlines
.get(airline)
.map(_.name)
.getOrElse(
Expand Down
50 changes: 31 additions & 19 deletions src/main/scala/com/geobase/load/Loader.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.geobase.load

import com.geobase.model.{Airline, AirlineName, AirportOrCity, Country}
import com.geobase.model.{Airline, AirportOrCity, Country}

import scala.io.Source

Expand Down Expand Up @@ -86,37 +86,49 @@ private[geobase] object Loader {
/** Loads the airline dataset */
def loadAirlines(): Map[String, Airline] = {

Source
.fromURL(getClass.getResource("/airlines.csv"))
// Airline code to airline name:
val airlineNames = Source
.fromURL(getClass.getResource("/optd_airlines.csv"))
.getLines()
.filter(!_.startsWith("#")) // Remove the header
.filter(!_.startsWith("pk^")) // Remove the header
.map(line => {

val splitLine = line.split("\\^", -1)

val airlineCode = splitLine(0)
val countryCode = splitLine(1)
val airlineCode = splitLine(5)
val airlineName = splitLine(7)

(airlineCode, Airline(airlineCode, countryCode))
Airline(airlineCode, "", airlineName)
})
.toMap
}

/** Loads the airline names dataset */
def loadAirlineNames(): Map[String, AirlineName] = {
.toList

Source
.fromURL(getClass.getResource("/optd_airlines.csv"))
// Airline code to country:
val airlineCountries = Source
.fromURL(getClass.getResource("/airlines.csv"))
.getLines()
.filter(!_.startsWith("pk")) // Remove the header
.filter(!_.startsWith("#")) // Remove the header
.map(line => {

val splitLine = line.split("\\^", -1)
val airlineCode = splitLine(5)
val airlineName = splitLine(7)

(airlineCode, AirlineName(airlineCode, airlineName))
val airlineCode = splitLine(0)
val countryCode = splitLine(1)

Airline(airlineCode, countryCode, "")
})
.toMap
.toList

(airlineNames ::: airlineCountries).groupBy {
case Airline(code, _, _) => code
}.map {
// Only airline name or country available:
case (code, List(airline)) => (code, airline)
// Both country and at least one name available (when an airline has
// several names, we take the first one):
case (code, (Airline(_, "", name) :: _) :+ Airline(_, country, "")) =>
(code, Airline(code, country, name))
// No information on the country, but several names available:
case (code, Airline(_, "", name) :: _) => (code, Airline(code, "", name))
}.toMap
}
}
13 changes: 11 additions & 2 deletions src/main/scala/com/geobase/model/Airline.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import scala.util.{Try, Success, Failure}

/** An airline.
*
* @author Xavier Guihot
* @author Xavier Guihot, Chems-Eddine Ouaari
* @since 2017-04
*/
private[geobase] final case class Airline(
airlineCode: String,
countryCode: String
countryCode: String,
airlineName: String
) {

def country(): Try[String] = countryCode match {
Expand All @@ -21,4 +22,12 @@ private[geobase] final case class Airline(
"No country available for airline \"" + airlineCode + "\""))
case _ => Success(countryCode)
}

def name(): Try[String] = airlineName match {
case "" =>
Failure(
GeoBaseException(
"No name available for airline \"" + airlineCode + "\""))
case _ => Success(airlineName)
}
}
24 changes: 0 additions & 24 deletions src/main/scala/com/geobase/model/AirlineName.scala

This file was deleted.

6 changes: 4 additions & 2 deletions src/test/scala/com/geobase/GeoBaseTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ class GeoBaseTest extends FunSuite {
geoBase.city("ORY")
geoBase.continent("FR")
geoBase.countryForAirline("BA")
geoBase.nameOfAirline("AH")

test("Airport to city") {

Expand Down Expand Up @@ -153,14 +152,17 @@ class GeoBaseTest extends FunSuite {
assert(exceptionThrown.getMessage === "Unknown airline \"..\"")
}

test("Airline to name") {
test("Airline to airline name") {

assert(geoBase.nameOfAirline("BA") === Success("British Airways"))
assert(geoBase.nameOfAirline("AF") === Success("Air France"))
assert(geoBase.nameOfAirline("AA") === Success("American Airlines"))
assert(geoBase.nameOfAirline("LH") === Success("Lufthansa"))
assert(geoBase.nameOfAirline("AH") === Success("Air Algerie"))

// Several names for this airline code:
assert(geoBase.nameOfAirline("5K") === Success("Hi Fly"))

// Unknown airline:
val exceptionThrown = intercept[GeoBaseException] {
geoBase.nameOfAirline("..").get
Expand Down
15 changes: 5 additions & 10 deletions src/test/scala/com/geobase/load/LoaderTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,12 @@ class LoaderTest extends FunSuite {

test("Airline loading") {

val airlineToCountryMap = Loader.loadAirlines()
val airlines = Loader.loadAirlines()

assert(airlineToCountryMap("AF").country === Success("FR"))
assert(airlineToCountryMap("AA").country === Success("US"))
}

test("AirlineNames loading") {

val airlineToNameMap = Loader.loadAirlineNames()
assert(airlines("AF").country === Success("FR"))
assert(airlines("AA").country === Success("US"))

assert(airlineToNameMap("AF").name === Success("Air France"))
assert(airlineToNameMap("AH").name === Success("Air Algerie"))
assert(airlines("AF").name === Success("Air France"))
assert(airlines("AH").name === Success("Air Algerie"))
}
}
27 changes: 0 additions & 27 deletions src/test/scala/com/geobase/model/AirlineNameTest.scala

This file was deleted.

18 changes: 15 additions & 3 deletions src/test/scala/com/geobase/model/AirlineTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,32 @@ import org.scalatest.FunSuite

/** Testing facility for Airline.
*
* @author Xavier Guihot
* @author Xavier Guihot, Chems-Eddine Ouaari
* @since 2018-01
*/
class AirlineTest extends FunSuite {

test("Airline to country") {

assert(Airline("AF", "FR").country === Success("FR"))
assert(Airline("AF", "FR", "Air France").country === Success("FR"))

// Empty country field:
val exceptionThrown = intercept[GeoBaseException] {
Airline("AF", "").country.get
Airline("AF", "", "Air France").country.get
}
assert(
exceptionThrown.getMessage === "No country available for airline \"AF\"")
}

test("Airline to name") {

assert(Airline("AH", "DZ", "Air Algerie").name === Success("Air Algerie"))

// Empty country field:
val exceptionThrown = intercept[GeoBaseException] {
Airline("AH", "DZ", "").name.get
}
assert(
exceptionThrown.getMessage === "No name available for airline \"AH\"")
}
}

0 comments on commit 6c6804e

Please sign in to comment.