Eli tosiaan pienenpieni ongelma Python-kieltä käyttäessä.
Yritän luoda ohjelmaa, joka laskee sille annetuista syntymäpäivä ajoista uuden henkilötunnuksen väestörekisterikeskuksen sivujen mukaan:
http://www.vaestorekisterikeskus.fi/vrk/home.
Pääsin tuohon kohtaan, jossa otetaan henkilötunnuksen loppuosan kolme ensimmäistä numeroa.
Miten tämän kohdan saisi järkevästi toteutettua? Pitäisi olla kolme numeroa, jotka sekoitetaan ja niistä on muodostuttava miehillä pariton ja naisilla parillinen luku.
Jos joku osaa neuvoa, antaa sen ilmi :)
Oletko siis tekemässä ohjelmaa, joka muodostaa syntymäajan perusteella jonkin oikeamuotoisen henkilötunnuksen?
Mitä ohjelman pitäisi tuottaa tulokseksi, jos sille annetaan esim. päivämäärä 25.11.2007? En aivan ymmärtänyt tuota kohtaa, jossa mainitset kolmen numeron sekoittamisesta.
Otat kaksi ensimmäistä numeroa randint:llä siten, että luku on väliltä 0-9.
digit = rand.randint(0, 9)
Viimeistä lukua valitset uudestaan niin kauan, että se on parillinen naiselle ja pariton miehelle. Luku on parillinen jos sen viimeinen numero on parillinen. Parillisuus todetaan mm. jakojäännösoperaattorilla.
if (sukupuoli == "nainen") and (digit % 2 == 0)
#luku on ok
...
#edit:
randrange-funktio voisi myös antaa parittoman tai parillisen.
#parillinen
random.randrange(0,8,2)
#pariton
random.randrange(1,9,2)
@Antti Laaksonen
Ohjelma muodostaa satunnaisesti mahdollisia henkilötunnuksia, jotka ovat auki tuona päivänä syntyneille. Painotan, että se ei kykene laskemaan henkilötunnusta, jota pystyisi käyttämään esim. Pankissa. Kuitenkin henkilötunnuksen laskeminen on mahdollista, mutta harvinaista.
@anttipanda
Kiitos tuosta, testaan sitä myöhemmin ja kerron toimiko se :)
Kyllä tuo toimi, mitä anttipanda kertoi, kiitos siitä :)
Nyt iski uusi ongelma. Onko Pythonilla mahdollista laskea suoraan jakojäännös?
Eli kun pitäisi laskea syntymäaika ja henkilökohtainen numero yhteen ja jakaa se 31, jonka jako jäännös määrittää viimeisen numeron.
Tuo jo mainittu %-operaattorihan se. Eli 5%2=1, 3%3=0 jne.
Jep jep, tuokin toimi, mutta viimeinen kysymys on vielä kysymättä:
Kuinka voin käyttää muuttujia pelkästään ilman niiden lisäämistä yhteen?
Eli yksinkertaisesti pitäisi saada syötetetyt arvot "yhteen" ilman plus-laskua.
Esim.
Syntymäaika: 5.12.1963
Henk. Numero: 624
Jakojäännös pitäisi ottaa luvusta 51263624, eikä summista 5+12+63+624
Kuinka onnistuisi?
Ainakin näin pitäisi onnistua:
p = 5 kk = 12 v = 1963 hnum = 624 # int(x) muuntaa merkkijonon kokonaisluvuksi # str(x) toisinpäin # ensin luodaan numeroista merkkijono ja muutetaan luvuksi # str(v)[2:4] tekee v:stä merkkijonon '1963' ja ottaa siitä kaksi viimeistä # merkkiä eli '63' jakojaannos = int( str(p) + str(kk) + str(v)[2:4] + str(hnum) ) % 31
#Isopaha, 26.11.2006 #Suuret kiitokset TsaTsaTsaa:lle ja anttipandalle, joita ilman ohjelma ei olisi valmistunut. #Ohjelma laskee mahdollisen henkilötunnuksen sille annettuna päivä syntyneille. #Ilmoita virheistä osoitteeseen isopaha[at]gmail.com import random #Lisää modulin random print "---------------------------------------" print print "Ohjelman tarkoitus on laskea mahdollinen henkilötunnus sille annetuista tiedoista" print "Syötä kysytyt tiedot (M = Mies, N = Nainen" print "---------------------------------------" print print print "Mahdollinen henkilötunnus:" paiva = input("Anna päivä, jolloin synnyit: ") kuukausi = input("Anna kuukausi, jolloin synnyit: ") vuosi = input("Anna syntymävuotesi: ") supu = raw_input("Anna sukupuolesi: ") if paiva == 1: #Varmistaa, että luvut ovat oikeassa muodossa. print "01", elif paiva == 2: print "02", elif paiva == 3: print "03", elif paiva == 4: print "04", elif paiva == 5: print "05", elif paiva == 6: print "06", elif paiva == 7: print "07", elif paiva == 8: print "08", elif paiva == 9: print "09", elif paiva > 31: print "Kuukaudessa ei ole enemmän kuin 31 päivää!" else: print paiva, if kuukausi == 1: print "01", elif kuukausi == 2: print "02", elif kuukausi == 3: #Varmistaa, että luvut ovat oikeassa muodossa. print "03", elif kuukausi == 4: print "04", elif kuukausi == 5: print "05", elif kuukausi == 6: print "06", elif kuukausi == 7: print "07", elif kuukausi == 8: print "08", elif kuukausi == 9: print "09", elif kuukausi > 12: print "Vuodessa ei ole enempää kuin 12 kuukautta!" print paiva else: print kuukausi, if vuosi < 1900: #Varmistaa, että luvut ovat oikeassa muodossa. vuosi2 = vuosi-1800 print vuosi2, elif vuosi < 2000: vuosi2 = vuosi-1900 print vuosi2, elif vuosi > 2000: vuosi2 = vuosi-2000 print vuosi2, elif vuosi == 2000: vuosi2 = "00" print "00", elif vuosi == 1900: vuosi2 = "00" print "00", elif vuosi == 1800: vuosi2 = "00" print "00", if vuosi < 1900: #Laskee välimerkin vuosilukujen perusteella print "+", elif vuosi < 2000: print "-", elif vuosi > 2000: print "A", if supu == "M": yksilo1 = random.randrange(1,9,2) #Luo random lukuja yksilo2 = random.randrange(1,9,2) yksilo3 = random.randrange(1,9,2) print yksilo1, yksilo2, yksilo3, elif supu == "N": yksilo1 = random.randrange(0,8,2) #Luo random lukuja yksilo2 = random.randrange(0,8,2) yksilo3 = random.randrange(0,8,2) print yksilo1, yksilo2, yksilo3, tunnus = int( str(paiva) + str(kuukausi) + str(vuosi2) + str(yksilo1) + str(yksilo2) + str(yksilo3) ) % 31 #Laskee jakojäännöksen if tunnus == 1: print "1" elif tunnus == 2: print "2" elif tunnus == 3: print "3" elif tunnus == 4: print "4" elif tunnus == 5: print "5" elif tunnus == 6: print "6" elif tunnus == 7: print "7" elif tunnus == 8: print "8" elif tunnus == 9: print "9" elif tunnus == 10: print "A" elif tunnus == 11: print "B" elif tunnus == 12: print "C" elif tunnus == 13: print "D" elif tunnus == 14: print "E" elif tunnus == 15: print "F" elif tunnus == 16: print "H" elif tunnus == 17: print "J" elif tunnus == 18: print "K" elif tunnus == 19: print "L" elif tunnus == 20: print "M" elif tunnus == 21: print "N" elif tunnus == 22: print "P" elif tunnus == 23: print "R" elif tunnus == 24: print "S" elif tunnus == 25: print "T" elif tunnus == 26: print "U" elif tunnus == 27: print "V" elif tunnus == 28: print "W" elif tunnus == 29: print "X" elif tunnus == 30: print "Y"
Tuossa olisi nyt valmis versio. Nautiskelkaa :)
Hmm, ainakin henkilön tunnusnumero antaa nyt aika suppean osajoukon mahdollisista luvuista. Helpointa varmaan olisi ollut arpoa luku väliltä 1-499, kertoa se kahdella ja jos kyse on naisesta lisätä lukuun yksi. Nyt arvot myös noi pari ensimmäistä numeroa parillisina ja väärältä väliltä, joten yli puolet sallituista luvuista jää pois.
Muutenkin koodissa on paljon turhaa.
Edit. Antti, myös koodipy-tagi tuhoaa tabulaattorit! Voisiko tuon korjata kaikista kooditageista saman tien?
#!/usr/bin/python # -*- coding: UTF-8 -*- import random # Funktio, joka muuttaa luvun vähintään määrätyn pituiseksi tekstiksi def tekstiksi(i, pituus): s = str(i) if len(s) < pituus: s = ((pituus - len(s)) * '0') + s return s def mahdollinen_henkilotunnus(paiva, kuukausi, vuosi, poika): numero = 2 * random.randrange(1, 500) if poika: numero = numero - 1 numero = tekstiksi(numero, 3) if vuosi < 1800 or vuosi >= 2100: return "Virhe! Vuosi ei kelpaa! Anna jotain väliltä 1800 - 2099." if kuukausi > 12 or kuukausi < 1: return "Virhe! Kuukausi ei kelpaa! Anna jotain väliltä 1 - 12." if kuukausi == 2: paivia = 28 if (vuosi % 4 == 0) and ((vuosi % 100 <> 0) or (vuosi % 400 == 0)): paivia = 29 else: paivia = 30 | (kuukausi ^ (kuukausi >> 3)) if paiva > paivia or paiva < 1: return "Virhe! Päivä ei kelpaa! Antamassasi kuussa on vain " + str(paivia) + " päivää." vuosisata = (vuosi - 1800) / 100 valimerkit = '+-A' vali = valimerkit[vuosisata] vuosi = tekstiksi(vuosi % 100, 2) kuukausi = tekstiksi(kuukausi, 2) paiva = tekstiksi(paiva, 2) jakojaannos = int(paiva + kuukausi + vuosi + numero) % 31 tarkistusmerkit = "0123456789ABCDEFHJKLMNPRSTUVWXY" tarkistus = tarkistusmerkit[jakojaannos] return paiva + kuukausi + vuosi + vali + numero + tarkistus print "Mahdollinen henkilötunnus:" paiva = input("Anna päivä: ") kuukausi = input("Anna kuukausi: ") vuosi = input("Anna syntymävuosi: ") supu = raw_input("Anna sukupuoli (M/N): ") poika = supu[0] == 'M' or supu[0] == 'm' print mahdollinen_henkilotunnus(paiva, kuukausi, vuosi, poika)
Joo, onhan tuo huomattavasti selkeempi, mutta en edes siihen pyrkinyt. Pääasia, että sain ohjelman toimimaan :D
Aihe on jo aika vanha, joten et voi enää vastata siihen.