Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Python Random

Sivun loppuun

Isopaha [25.11.2007 20:20:06]

#

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.nsf/pages/32C708B9CA6C5824C2256CB70038D048

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 :)

Antti Laaksonen [25.11.2007 20:34:09]

#

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.

anttipanda [26.11.2007 11:21:38]

#

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)

Isopaha [26.11.2007 11:49:24]

#

@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 :)

Isopaha [26.11.2007 15:02:36]

#

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.

TsaTsaTsaa [26.11.2007 15:20:04]

#

Tuo jo mainittu %-operaattorihan se. Eli 5%2=1, 3%3=0 jne.

Isopaha [26.11.2007 15:31:25]

#

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?

TsaTsaTsaa [26.11.2007 16:18:38]

#

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.2007 21:18:20]

#

#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 :)

FooBat [26.11.2007 21:34:07]

#

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.

Metabolix [26.11.2007 22:48:34]

#

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)

Isopaha [27.11.2007 15:01:24]

#

Joo, onhan tuo huomattavasti selkeempi, mutta en edes siihen pyrkinyt. Pääasia, että sain ohjelman toimimaan :D


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta