Skip to content

Instantly share code, notes, and snippets.

@dacr
Last active April 2, 2023 10:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dacr/0943af77e448644b5cf6a4917b04df26 to your computer and use it in GitHub Desktop.
Save dacr/0943af77e448644b5cf6a4917b04df26 to your computer and use it in GitHub Desktop.
postal code opendata data sources. / published by https://github.com/dacr/code-examples-manager #095ffa72-b4d9-4f3d-85b2-b3e69a302ac4/e7bbc4649a8dfe6129e20c9be9a626fba0200f77
// summary : postal code opendata data sources.
// keywords : scala, opendata, data-analysis, requests, postal-codes, @testable
// publish : gist
// authors : David Crosson
// license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2)
// id : 095ffa72-b4d9-4f3d-85b2-b3e69a302ac4
// created-on : 2020-10-10T16:21:18Z
// managed-by : https://github.com/dacr/code-examples-manager
// run-with : scala-cli $file
// ---------------------
//> using scala "3.2.1"
//> using dep "com.lihaoyi::requests:0.8.0"
// ---------------------
case class GPS(latitude:Double, longitude:Double)
case class PostalCode(
townCode: String,
townName: String,
postalCode: String,
secondaryTownName: Option[String],
deliveryLabel: String,
gps: Option[GPS]
) {
val countyCode = townCode.take(if (townCode.startsWith("97")) 3 else 2)
}
def stringToGPS(input:String):Option[GPS] = {
input.split(",").map(_.trim) match {
case Array(latitude, longitude) =>
for {
lat <- latitude.toDoubleOption
lon <- longitude.toDoubleOption
} yield GPS(lat,lon)
case _ => None
}
}
def stringToPostalCode(input:String):Option[PostalCode] = {
input.trim.split(";") match {
case Array(townCode, townName, postalCode, "", deliveryLabel, position) =>
Option(PostalCode(townCode, townName, postalCode, None, deliveryLabel, stringToGPS(position)))
case Array(townCode, townName, postalCode, secondaryTownName, deliveryLabel, position) =>
Option(PostalCode(townCode, townName, postalCode, Some(secondaryTownName), deliveryLabel, stringToGPS(position)))
case Array(townCode, townName, postalCode, "", deliveryLabel) =>
Option(PostalCode(townCode, townName, postalCode, None, deliveryLabel, None))
case Array(townCode, townName, postalCode, secondaryTownName, deliveryLabel) =>
Option(PostalCode(townCode, townName, postalCode, Some(secondaryTownName), deliveryLabel, None))
case data =>
println("Unmanaged input : "+data.mkString(";"))
None
}
}
// code postaux https://www.data.gouv.fr/fr/datasets/base-officielle-des-codes-postaux/
val response = requests.get("https://www.data.gouv.fr/fr/datasets/r/554590ab-ae62-40ac-8353-ee75162c05ee")
val postalCodes = {
response
.lines()
.drop(1) // first line == the CSV labels
.flatMap(stringToPostalCode)
}
val townByCounty = postalCodes.toList.groupMap(_.countyCode)(_.townName)
val longestTownName = postalCodes.maxByOption(_.townName.count(_.isLetter))
val shortestTownName = postalCodes.minByOption(_.townName.count(_.isLetter))
val countyWithMostTowns = townByCounty.maxByOption { case (countyCode, towns) => towns.size }.map{ case (countyCode, towns) => countyCode -> towns.size}
postalCodes
.sortBy(_.postalCode)
.foreach(println)
println(
s"""postalCodeCount : ${postalCodes.size}
|longestTownName : ${longestTownName}
|shortestTownName : ${shortestTownName}
|countyWithMostTowns : ${countyWithMostTowns}
|""".stripMargin
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment