Created
January 18, 2021 18:12
-
-
Save Oceantidote/471eeb1b10e259e3b820a2a22a9dbedc to your computer and use it in GitHub Desktop.
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
'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 |
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
require "date" | |
require "yaml" | |
def french_ssn_info(number) | |
pattern = /^(?<gender>[12])\s?(?<year>\d{2})\s?(?<month>1[0-2]|0[1-9])\s?(?<region>\d{2})\s?\d{3}\s?\d{3}\s?(?<key>\d{2})$/ | |
result = number.match(pattern) | |
if result && valid?(result) | |
gender = gender(result) | |
month = month(result) | |
year = year(result) | |
region = region(result) | |
return "a #{gender}, born in #{month}, #{year} in #{region}." | |
else | |
return "The number is invalid" | |
end | |
end | |
def gender(matchdata) | |
if matchdata[:gender] == "1" | |
"man" | |
else | |
"woman" | |
end | |
end | |
def month(matchdata) | |
Date::MONTHNAMES[matchdata[:month].to_i] | |
end | |
def year(matchdata) | |
if matchdata[:year].to_i < 21 | |
"20#{matchdata[:year]}" | |
else | |
"19#{matchdata[:year]}" | |
end | |
end | |
def region(matchdata) | |
regions = YAML.load_file('data/french_departments.yml') | |
regions[matchdata[:region]] | |
end | |
def valid?(matchdata) | |
number = matchdata[0].delete(' ')[0..-3].to_i | |
remainder = (97 - number) % 97 | |
remainder == matchdata[:key].to_i | |
end | |
# A 2 digits key (46, equal to the remainder of the division of (97 - ssn_without_key) by 97.) | |
# 46 = remainder of (97 - 1041276451089) / 97 | |
french_ssn_info("1 84 12 76 451 089 46") |
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
require_relative "../french_ssn" | |
describe "#french_ssn_info" do | |
it "returns 'The number is invalid' when passed an empty string" do | |
actual = french_ssn_info("") | |
expected = "The number is invalid" | |
expect(actual).to eq(expected) | |
end | |
it "returns 'a man, born in December, 1984 in Seine-Maritime.' when passed '1 84 12 76 451 089 46'" do | |
actual = french_ssn_info("1 84 12 76 451 089 46") | |
expected = "a man, born in December, 1984 in Seine-Maritime." | |
expect(actual).to eq(expected) | |
end | |
it "should reject numbers that do not match key constraints" do | |
actual = french_ssn_info("1 84 12 76 451 086 46") | |
expected = "The number is invalid" | |
expect(actual).to eq(expected) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment