Last active
April 2, 2023 10:12
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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