Initial commit

This commit is contained in:
Gabriel Augendre 2019-07-10 23:13:38 +02:00
commit e383d18152
8 changed files with 36350 additions and 0 deletions

424
.gitignore vendored Normal file
View file

@ -0,0 +1,424 @@
# Created by https://www.gitignore.io/api/pycharm,python
# Edit at https://www.gitignore.io/?templates=pycharm,python
### PyCharm ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### PyCharm Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
.idea/sonarlint
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# End of https://www.gitignore.io/api/pycharm,python
# Created by https://www.gitignore.io/api/pycharm,python
# Edit at https://www.gitignore.io/?templates=pycharm,python
### PyCharm ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### PyCharm Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
.idea/sonarlint
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# End of https://www.gitignore.io/api/pycharm,python

15
Pipfile Normal file
View file

@ -0,0 +1,15 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
black = "*"
[requires]
python_version = "3.7"
[pipenv]
allow_prereleases = true

57
Pipfile.lock generated Normal file
View file

@ -0,0 +1,57 @@
{
"_meta": {
"hash": {
"sha256": "b132de3bc6e041e3fa5ab7a0feb2ee862f488ae8903790188641b70b5e595abd"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.7"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"appdirs": {
"hashes": [
"sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92",
"sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"
],
"version": "==1.4.3"
},
"attrs": {
"hashes": [
"sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79",
"sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399"
],
"version": "==19.1.0"
},
"black": {
"hashes": [
"sha256:09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf",
"sha256:68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c"
],
"index": "pypi",
"version": "==19.3b0"
},
"click": {
"hashes": [
"sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
"sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"
],
"version": "==7.0"
},
"toml": {
"hashes": [
"sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c",
"sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"
],
"version": "==0.10.0"
}
},
"develop": {}
}

0
__init__.py Normal file
View file

35346
cities.py Normal file

File diff suppressed because it is too large Load diff

273
countries.py Normal file
View file

@ -0,0 +1,273 @@
CONTINENTS = {
"1": "Europe",
"2": "Asie",
"3": "Afrique",
"4": "Amérique",
"5": "Océanie",
}
COUNTRIES = {
"99125": ["ALBANIE"],
"99109": ["ALLEMAGNE"],
"99130": ["ANDORRE"],
"99110": ["AUTRICHE"],
"99131": ["BELGIQUE"],
"99148": ["BIELORUSSIE"],
"99118": ["BOSNIE-HERZEGOVINE"],
"99111": ["BULGARIE"],
"99119": ["CROATIE"],
"99101": ["DANEMARK", "FEROE (ILES)"],
"99134": ["ESPAGNE"],
"99106": ["ESTONIE"],
"99156": ["EX-REPUBLIQUE YOUGOSLAVE DE MACEDOINE"],
"99105": ["FINLANDE"],
"99133": ["GIBRALTAR"],
"99126": ["GRECE"],
"99132": ["ROYAUME-UNI", "GUERNESEY", "JERSEY", "MAN (ILE)"],
"99112": ["HONGRIE"],
"99136": ["IRLANDE, ou EIRE"],
"99102": ["ISLANDE"],
"99127": ["ITALIE"],
"99157": ["KOSOVO"],
"99107": ["LETTONIE"],
"99113": ["LIECHTENSTEIN"],
"99108": ["LITUANIE"],
"99137": ["LUXEMBOURG"],
"99144": ["MALTE"],
"99151": ["MOLDAVIE"],
"99138": ["MONACO"],
"99120": ["MONTENEGRO"],
"99103": ["NORVEGE", "BOUVET (ILE)", "SVALBARD et ILE JAN MAYEN"],
"99135": ["PAYS-BAS", "ARUBA"],
"99122": ["POLOGNE"],
"99139": ["PORTUGAL"],
"99141": ["REPUBLIQUE DEMOCRATIQUE ALLEMANDE"],
"99142": ["REPUBLIQUE FEDERALE D'ALLEMAGNE"],
"99114": ["ROUMANIE"],
"99123": ["RUSSIE"],
"99128": ["SAINT-MARIN"],
"99121": ["SERBIE"],
"99117": ["SLOVAQUIE"],
"99145": ["SLOVENIE"],
"99104": ["SUEDE"],
"99140": ["SUISSE"],
"99115": ["TCHECOSLOVAQUIE"],
"99116": ["TCHEQUE (REPUBLIQUE)"],
"99124": ["TURQUIE D'EUROPE"],
"99155": ["UKRAINE"],
"99129": ["VATICAN, ou SAINT-SIEGE"],
"99212": ["AFGHANISTAN"],
"99201": ["ARABIE SAOUDITE"],
"99252": ["ARMENIE"],
"99253": ["AZERBAIDJAN"],
"99249": ["BAHREIN"],
"99246": ["BANGLADESH"],
"99214": ["BHOUTAN"],
"99224": ["BIRMANIE"],
"99225": ["BRUNEI"],
"99234": ["CAMBODGE"],
"99216": ["CHINE"],
"99254": ["CHYPRE"],
"99237": ["COREE"],
"99239": ["COREE (REPUBLIQUE DE)"],
"99238": ["COREE (REPUBLIQUE POPULAIRE DEMOCRATIQUE DE)"],
"99247": ["EMIRATS ARABES UNIS"],
"99228": ["ETATS MALAIS NON FEDERES"],
"99255": ["GEORGIE"],
"99230": ["HONG-KONG"],
"99223": ["INDE", "GOA"],
"99231": ["INDONESIE"],
"99204": ["IRAN"],
"99203": ["IRAQ"],
"99207": ["ISRAEL"],
"99217": ["JAPON"],
"99222": ["JORDANIE"],
"99211": ["KAMTCHATKA"],
"99256": ["KAZAKHSTAN"],
"99257": ["KIRGHIZISTAN"],
"99240": ["KOWEIT"],
"99241": ["LAOS"],
"99205": ["LIBAN"],
"99232": ["MACAO"],
"99227": ["MALAISIE"],
"99229": ["MALDIVES"],
"99218": ["MANDCHOURIE"],
"99242": ["MONGOLIE"],
"99215": ["NEPAL"],
"99250": ["OMAN"],
"99258": ["OUZBEKISTAN"],
"99213": ["PAKISTAN"],
"99261": ["PALESTINE (Etat de)"],
"99220": ["PHILIPPINES"],
"99221": ["POSSESSIONS BRITANNIQUES AU PROCHE-ORIENT"],
"99248": ["QATAR"],
"99209": ["SIBERIE"],
"99226": ["SINGAPOUR"],
"99235": ["SRI LANKA"],
"99206": ["SYRIE"],
"99259": ["TADJIKISTAN"],
"99236": ["TAIWAN"],
"99219": ["THAILANDE"],
"99262": ["TIMOR ORIENTAL"],
"99210": ["TURKESTAN RUSSE"],
"99260": ["TURKMENISTAN"],
"99208": ["TURQUIE"],
"99243": ["VIET NAM"],
"99244": ["VIET NAM DU NORD"],
"99245": ["VIET NAM DU SUD"],
"99251": ["YEMEN"],
"99233": ["YEMEN DEMOCRATIQUE"],
"99202": ["YEMEN (REPUBLIQUE ARABE DU)"],
"99319": ["ACORES, MADERE"],
"99303": ["AFRIQUE DU SUD"],
"99352": ["ALGERIE"],
"99395": ["ANGOLA"],
"99327": ["BENIN"],
"99347": ["BOTSWANA"],
"99331": ["BURKINA"],
"99321": ["BURUNDI"],
"99322": ["CAMEROUN"],
"99305": ["CAMEROUN ET TOGO"],
"99396": ["CAP-VERT"],
"99323": ["CENTRAFRICAINE (REPUBLIQUE)"],
"99397": ["COMORES"],
"99324": ["CONGO"],
"99312": ["CONGO (REPUBLIQUE DEMOCRATIQUE)"],
"99326": ["COTE D'IVOIRE"],
"99399": ["DJIBOUTI"],
"99301": ["EGYPTE"],
"99317": ["ERYTHREE"],
"99391": ["ESWATINI"],
"99315": ["ETHIOPIE"],
"99328": ["GABON"],
"99304": ["GAMBIE"],
"99329": ["GHANA"],
"99330": ["GUINEE"],
"99314": ["GUINEE EQUATORIALE"],
"99392": ["GUINEE-BISSAU"],
"99320": ["ILES PORTUGAISES DE L'OCEAN INDIEN"],
"99332": ["KENYA"],
"99348": ["LESOTHO"],
"99302": ["LIBERIA"],
"99316": ["LIBYE"],
"99333": ["MADAGASCAR"],
"99334": ["MALAWI"],
"99335": ["MALI"],
"99350": ["MAROC"],
"99390": ["MAURICE"],
"99336": ["MAURITANIE"],
"99393": ["MOZAMBIQUE"],
"99311": ["NAMIBIE"],
"99337": ["NIGER"],
"99338": ["NIGERIA"],
"99339": ["OUGANDA"],
"99313": ["PROVINCES ESPAGNOLES D'AFRIQUE", "PRESIDES", "CANARIES (ILES)"],
"99340": ["RWANDA"],
"99389": ["SAHARA OCCIDENTAL"],
"99306": ["SAINTE HELENE, ASCENSION ET TRISTAN DA CUNHA"],
"99394": ["SAO TOME-ET-PRINCIPE"],
"99341": ["SENEGAL"],
"99398": ["SEYCHELLES"],
"99342": ["SIERRA LEONE"],
"99318": ["SOMALIE"],
"99343": ["SOUDAN"],
"99307": ["SOUDAN ANGLO-EGYPTIEN, KENYA, OUGANDA"],
"99349": ["SOUDAN DU SUD"],
"99325": ["TANGER"],
"99309": ["TANZANIE"],
"99344": ["TCHAD"],
"99345": ["TOGO"],
"99351": ["TUNISIE"],
"99346": ["ZAMBIE"],
"99308": ["ZANZIBAR", "OCEAN INDIEN (TERRITOIRE BRITANNIQUE DE L')"],
"99310": ["ZIMBABWE"],
"99441": ["ANTIGUA-ET-BARBUDA"],
"99431": ["ANTILLES NEERLANDAISES"],
"99415": ["ARGENTINE"],
"99436": ["BAHAMAS"],
"99434": ["BARBADE"],
"99429": ["BELIZE"],
"99425": [
"BERMUDES",
"ANGUILLA",
"CAIMANES (ILES)",
"MONTSERRAT",
"TURKS ET CAIQUES (ILES)",
"VIERGES BRITANNIQUES (ILES)",
"TERRITOIRES DU ROYAUME-UNI AUX ANTILLES",
],
"99418": ["BOLIVIE"],
"99443": ["BONAIRE, SAINT EUSTACHE ET SABA"],
"99416": ["BRESIL"],
"99401": ["CANADA"],
"99417": ["CHILI"],
"99419": ["COLOMBIE"],
"99406": ["COSTA RICA"],
"99407": ["CUBA"],
"99444": ["CURAÇAO"],
"99408": ["DOMINICAINE (REPUBLIQUE)"],
"99438": ["DOMINIQUE"],
"99414": ["EL SALVADOR"],
"99420": ["EQUATEUR"],
"99404": ["ETATS-UNIS", "ALASKA"],
"99435": ["GRENADE"],
"99430": ["GROENLAND"],
"99409": ["GUATEMALA"],
"99428": ["GUYANA"],
"99410": ["HAITI"],
"99411": ["HONDURAS"],
"99426": ["JAMAIQUE"],
"99403": ["LABRADOR"],
"99427": [
"MALOUINES, OU FALKLAND (ILES)",
"GEORGIE DU SUD ET LES ILES SANDWICH DU SUD",
"TERR. DU ROYAUME-UNI DANS L'ATLANTIQUE SUD",
],
"99405": ["MEXIQUE"],
"99412": ["NICARAGUA"],
"99413": ["PANAMA"],
"99421": ["PARAGUAY"],
"99422": ["PEROU"],
"99432": [
"PORTO RICO",
"VIERGES DES ETATS-UNIS (ILES)",
"TERR. DES ETATS-UNIS D'AMERIQUE EN AMERIQUE",
],
"99442": ["SAINT-CHRISTOPHE-ET-NIEVES"],
"99439": ["SAINTE-LUCIE"],
"99445": ["SAINT-MARTIN (PARTIE NEERLANDAISE)"],
"99440": ["SAINT-VINCENT-ET-LES GRENADINES"],
"99437": ["SURINAME"],
"99402": ["TERRE-NEUVE"],
"99433": ["TRINITE-ET-TOBAGO"],
"99423": ["URUGUAY"],
"99424": ["VENEZUELA"],
"99501": [
"AUSTRALIE",
"CHRISTMAS (ILE)",
"COCOS ou KEELING (ILES)",
"HEARD ET MACDONALD (ILES)",
"NORFOLK (ILE)",
],
"99508": ["FIDJI"],
"99504": ["HAWAII (ILES)"],
"99513": ["KIRIBATI"],
"99515": ["MARSHALL (ILES)"],
"99516": ["MICRONESIE (ETATS FEDERES DE)"],
"99507": ["NAURU"],
"99502": ["NOUVELLE-ZELANDE", "COOK (ILES)", "NIUE", "TOKELAU"],
"99517": ["PALAOS (ILES)"],
"99510": ["PAPOUASIE-NOUVELLE-GUINEE"],
"99503": ["PITCAIRN (ILE)"],
"99512": ["SALOMON (ILES)"],
"99506": ["SAMOA OCCIDENTALES"],
"99505": [
"GUAM",
"SAMOA AMERICAINES",
"MARIANNES DU NORD (ILES)",
"TERR. DES ETATS-UNIS D'AMERIQUE EN OCEANIE",
],
"99509": ["TONGA"],
"99511": ["TUVALU"],
"99514": ["VANUATU"],
}

111
departments.py Normal file
View file

@ -0,0 +1,111 @@
DEPARTMENTS = {
"01": "Ain",
"02": "Aisne",
"03": "Allier",
"04": "Alpes-de-Haute-Provence",
"05": "Hautes-Alpes",
"06": "Alpes-Maritimes",
"07": "Ardèche",
"08": "Ardennes",
"09": "Ariège",
"10": "Aube",
"11": "Aude",
"12": "Aveyron",
"13": "Bouches-du-Rhône",
"14": "Calvados",
"15": "Cantal",
"16": "Charente",
"17": "Charente-Maritime",
"18": "Cher",
"19": "Corrèze",
"2A": "Corse-du-Sud",
"2B": "Haute-Corse",
"21": "Côte-d'Or",
"22": "Côtes-d'Armor",
"23": "Creuse",
"24": "Dordogne",
"25": "Doubs",
"26": "Drôme",
"27": "Eure",
"28": "Eure-et-Loir",
"29": "Finistère",
"30": "Gard",
"31": "Haute-Garonne",
"32": "Gers",
"33": "Gironde",
"34": "Hérault",
"35": "Ille-et-Vilaine",
"36": "Indre",
"37": "Indre-et-Loire",
"38": "Isère",
"39": "Jura",
"40": "Landes",
"41": "Loir-et-Cher",
"42": "Loire",
"43": "Haute-Loire",
"44": "Loire-Atlantique",
"45": "Loiret",
"46": "Lot",
"47": "Lot-et-Garonne",
"48": "Lozère",
"49": "Maine-et-Loire",
"50": "Manche",
"51": "Marne",
"52": "Haute-Marne",
"53": "Mayenne",
"54": "Meurthe-et-Moselle",
"55": "Meuse",
"56": "Morbihan",
"57": "Moselle",
"58": "Nièvre",
"59": "Nord",
"60": "Oise",
"61": "Orne",
"62": "Pas-de-Calais",
"63": "Puy-de-Dôme",
"64": "Pyrénées-Atlantiques",
"65": "Hautes-Pyrénées",
"66": "Pyrénées-Orientales",
"67": "Bas-Rhin",
"68": "Haut-Rhin",
"69": "Rhône",
"70": "Haute-Saône",
"71": "Saône-et-Loire",
"72": "Sarthe",
"73": "Savoie",
"74": "Haute-Savoie",
"75": "Paris",
"76": "Seine-Maritime",
"77": "Seine-et-Marne",
"78": "Yvelines",
"79": "Deux-Sèvres",
"80": "Somme",
"81": "Tarn",
"82": "Tarn-et-Garonne",
"83": "Var",
"84": "Vaucluse",
"85": "Vendée",
"86": "Vienne",
"87": "Haute-Vienne",
"88": "Vosges",
"89": "Yonne",
"90": "Territoire de Belfort",
"91": "Essonne",
"92": "Hauts-de-Seine",
"93": "Seine-Saint-Denis",
"94": "Val-de-Marne",
"95": "Val-d'Oise",
"971": "Guadeloupe",
"972": "Martinique",
"973": "Guyane",
"974": "La Réunion",
"975": "Saint-Pierre-et-Miquelon",
"976": "Mayotte",
"977": "Saint-Barthélemy",
"978": "Saint-Martin",
"984": "Terres australes et antarctiques françaises",
"986": "Wallis et Futuna",
"987": "Polynésie française",
"988": "Nouvelle-Calédonie",
"989": "Île de Clipperton",
}

124
main.py Normal file
View file

@ -0,0 +1,124 @@
import calendar
import datetime
from departments import DEPARTMENTS
from cities import CITIES
from countries import COUNTRIES, CONTINENTS
class InseeData:
def __init__(self, insee_number: str):
self.insee_number = insee_number
if len(insee_number) != 15:
raise ValueError("insee number must be 15 characters")
self._gender = insee_number[0]
self._year = insee_number[1:3]
self.month = int(insee_number[3:5])
department = insee_number[5:7]
city = insee_number[7:10]
if department in ["97", "98"]:
department = insee_number[5:8]
city = insee_number[8:10]
self.foreign = False
if department == "99":
self.foreign = True
self._country = city
else:
self._department = department
self._city = city
self.order_of_birth = int(insee_number[10:13])
self.control_key = int(insee_number[13:])
@property
def is_valid(self):
code = 97 - (
int(self.insee_number.replace("2A", "19").replace("2B", "18")[:-2]) % 97
)
return code == self.control_key
@property
def year(self):
year = int("20" + self._year)
date = datetime.date(year, self.month, 1)
if date < datetime.date.today():
return year
return year - 100
@property
def gender(self):
if self._gender == "1":
return "Male"
return "Female"
@property
def city(self):
if self.foreign:
return "unknown"
return self._city
@property
def country(self):
if self.foreign:
return self._country
return "FR"
@property
def department(self):
if self.foreign:
return "unknown"
return self._department
def __str__(self):
message = []
if self.is_valid:
message.append("The number is valid")
else:
message.append("The number is invalid")
message.append(
f"You're a {self.gender}, born in {calendar.month_name[self.month]}, probably in {self.year}."
)
if self.foreign:
word = "country"
line = "You're born outside France, "
country = COUNTRIES.get("99" + self.country, [])
continent = CONTINENTS.get(self.country[0])
if len(country) > 1:
line += f"probably in one of these countries/territories: {', '.join(country)} ({continent})"
elif len(country) == 1:
line += f"in {country[0]} ({continent})"
else:
line += f"in an unknown country numbered {self.country}"
message.append(line)
else:
word = "city"
city = CITIES.get(self.department + self.city)
department_nice = DEPARTMENTS[self.department]
if city:
message.append(
f"You're born in {city['name']}, {city['zip_code']} ({department_nice}), France."
)
else:
message.append(
f"You're born in a unknown city numbered {self.city}, which is located in {department_nice}, in France."
)
message.append(
f"You're the {self.order_of_birth}th to be born in this {word} on this month."
)
return "\n".join(message)
def main():
# insee_number = "168127982980507"
insee_number = "269059913116714"
data = InseeData(insee_number)
print(data)
main()