Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Python: Pythonilla merkkien tarkastus

Sivun loppuun

jogi [26.08.2014 18:54:28]

#

tiedosto = open("merkkijonoja.txt", "r")
for salasana in tiedosto:
	if salasana.isalnum():
		print(salasana[:-1],"kelpaa salasanaksi.")
	else:
		print(salasana[:-1],"sisältää virheellisiä merkkejä.")




tiedosto.close()

Eli saan koodin muuten printtaamaan haluttavan lopputuloksen, mutta tehtävänannossa vaaditaan, että kaikki erikoismerkkejä sisältävät salasanat antavat viestin "sisältää virheellisiä merkkejä" ja pelkkiä numeroita ja kirjaimia sisältävät salasanat taas "kelpaa salasanaksi". En ymmärrä, että miksi kaikki pelkkiä numeroita ja kirjaimia sisältävät menevät kondition else läpi eikä if-osion.

Onko kohdassa:

if salasana.isalnum():

jotain väärää?

kuva

Osaisiko joku auttaa ongelmani kanssa? Olen tapellut kyseisen verkkokurssin tehtävän kanssa kohta 5 tuntia ja kaikki muu tällä hetkellä toimii paitsi if-else konditioiden toiminta. Koulua varten pitää saada tehtyä monta muutakin kurssia ens jaksoon mennessä ja on vähän heikoilla avunsaanti tällä hetkellä kun en pysty fyysisesti koulussa käymään.

Kiitos jo etukäteen

Edit: Olen lukenut kurssimateriaalin läpi tähän kappaleeseen asti kokonaan ja en löydä mitään mikä valaisisi minua asiasta tai mitä tekisin väärin.

Sami [26.08.2014 19:24:31]

#

Python jättää myös rivinvaihtomerkin luetun rivin (salasanan) loppuun.
Esimerkiksi jos merkkijonoja.txt näyttää tältä:

salakala
toinensalakala

Niin silloin tutkitaankin, että onko "salakala\n".isalnum() (missä "\n" on rivinvaihtomerkki) tosi, jota se ei tietenkään tuon rivinvaihdon takia ole.
Ylimääräisistä rivinvaihdoista pääset eroon esimerkiksi strip-metodilla.

jogi [26.08.2014 20:39:05]

#

Sami kirjoitti:

Python jättää myös rivinvaihtomerkin luetun rivin (salasanan) loppuun.
Esimerkiksi jos merkkijonoja.txt näyttää tältä:

salakala
toinensalakala

Niin silloin tutkitaankin, että onko "salakala\n".isalnum() (missä "\n" on rivinvaihtomerkki) tosi, jota se ei tietenkään tuon rivinvaihdon takia ole.
Ylimääräisistä rivinvaihdoista pääset eroon esimerkiksi strip-metodilla.

Jännää tässä on se, että internetsejä selaamalla löysin jotain tuohon liittyvää, mutta erikoista on, että kurssin materiaalista ei löytynyt mitään tuohon strippiin liittyvää tietoa.

Osaisitko neuvoa miten lisäisin sen käytön jo olemassaolevaan koodiini? koitin äsken pähkäillä, mutta koska tuota ei löydy opiskeltavasta materiaalista on hieman vaikeaa soveltaa sitä tuohon tehtävään. Olettaisin, että jotenkin tuohon

for salasana in tiedosto:

koska jos lisään sen if- tai else-osion print komentoon oletetustihan se on jo käynyt nämä konditiot läpi ja huomio edelleenkin "\n" luetussa rivissä.

Vai tarvitseeko minun muuttaa koodiani ihan eri muotoon tai käyttää esimerkiksi while:a eikä for:ia?

Edit: Pitäisikö minun tehdä uusi muuttuja tai muuttaa muuttujaa "salasana" jollain tavalla? Ymmärrän mitä tuo strip-metodi tekee, mutta en jotenkin osaa nyt soveltaa sitä jo olemassa olevaan koodiini. Oletan kuitenkin, että yhdellä rivillä saisin koodini toimimaan.

Grez [26.08.2014 20:50:06]

#

varmaan voisit ihan stripin tuloksen antaa suoraan isalnumille.

jogi [26.08.2014 21:12:13]

#

Grez kirjoitti:

varmaan voisit ihan stripin tuloksen antaa suoraan isalnumille.

En nyt täysin ymmärtänyt. Sori, että mulle täytyy vääntää vähän rautalangasta, mutta nää on aika uusia asioita mulle.

for salasana in tiedosto:
	if salasana.isalnum(rstrip('\n')):
for salasana in tiedosto:
	if salasana.isalnum.rstrip('\n'):
for salasana in tiedosto:
	if salasana.rstrip(isalnum('\n')):
for salasana in tiedosto:
	if salasana.rstrip.isalnum('\n'):

Koitin tälläisiä vaihtoehtoja ja tietenkään mikään niistä ei toiminut. Mainitsit, että tulisi antaa "stripin tulos" isalnumille. Oletin, että se olisi jotain äskeisiä koodinpätkien kaltaista, mutta mikään niistä ei toiminut. Eli epäselvyys tässä on nyt se, että miten annan sen siihen?

Metabolix [26.08.2014 21:22:21]

#

Hieman ihmetyttää, miten olet päätynyt (erään ongelman seurauksena?) tulostusvaiheessa ottamaan yhden merkin pois (salasana[:-1]) mutta silti et ole keksinyt, että tekisit myös isalnum-tarkistuksen samalle lyhennetylle merkkijonolle. Näin ainakin koodisi olisi toiminut loogisesti. Tietenkin tämä ratkaisu on idealtaan väärä siksi, että tiedoston viimeisellä rivillä ei välttämättä ole rivinvaihtomerkkiä, jolloin lyhennys syökin salasanasta yhden oikean merkin.

Oikeammin silmukan pitäisi näyttää tältä:

for rivi in tiedosto:
	salasana = rivi.strip("\n")
	# jne.

Huomaa myös täsmälliset nimet muuttujilla: tiedoston yksi rivi on rivi, ja siitä saadaan salasana vasta rivinvaihtomerkin poiston jälkeen. Omassa koodissasi taas on harhaanjohtavaa, että muuttujan nimi ei tarkkaan vastaa sen sisältöä.

jogi kirjoitti:

Koitin tälläisiä vaihtoehtoja ja tietenkään mikään niistä ei toiminut.

Tietenkin funktiota pitää kutsua:

rivi.strip("\n").isalnum()

Tässä stripin tulos ”annetaan isalnumille”, koska isalnum ”ottaa” sen pistettä edeltävän tekstin (str-olion), joka tässä koodissa on kutsun rivi.strip("\n") palauttama teksti.

Suosittelen kuitenkin aiemmin kuvaamaani tapaa, jossa salasana saadaan yhteen muuttujaan eikä tarvita ylimääräisiä kikkailuja.

jogi [26.08.2014 21:40:07]

#

Metabolix kirjoitti:

Tietenkin funktiota pitää kutsua:

rivi.strip("\n").isalnum()

Kiitos sain tämän toimimaan.

tiedosto = open("merkkijonoja.txt", "r")

for salasana in tiedosto:
	if salasana.strip("\n").isalnum():
		print(salasana[:-1],"kelpaa salasanaksi.")
	else:
		print(salasana[:-1],"sisältää virheellisiä merkkejä.")




tiedosto.close()

Eli ongelma oli nimenomaan siinä, että kurssimateriaalissa ensinnäkin vain kerrottiin, että .isalnum():lla voit testata onko merkkijono pelkkiä kirjaimia ja numeroita, mutta ei näytetty miten sitä sovelletaan tilanteeseen, jossa ei vain haluta tietää onko vastaus "True" vai "False". Kurssimateriaalissa ei opetettu mitään "rivi.strip("\n").isalnum()" funktiota vastaavaa yhdistelmää joten olin aika pihalla siitä, että mitä olisi pitänyt tehdä. Olin koodin kanssa ollut jumissa jo pitkään ja asiat jota huomasin muualla saattoi mennä toisessa kohtaa vain jotenkin ohi, koska mietin miten saisin koodin toimimaan ja etin muualta kuin kurssimateriaalista apua.

Long story short jos fiksasin jotain koodissa joku toinen asia ei toiminut ja minulla oli paljon ongelmia toteuttaa kyseinen tehtävä.

Kiitos kaikille avusta. Voi olla, että joudun tulla kysymään jatkossa apua jos en omin nokkineni pärjää.

Grez [26.08.2014 22:36:19]

#

jogi kirjoitti:

mutta ei näytetty miten sitä sovelletaan tilanteeseen, jossa ei vain haluta tietää onko vastaus "True" vai "False".

No edelleenhän sinä halusit tietää nimen omaan tuon. Eli tulokseksi saat joka tapauksessa tosi/epätosi. Mahdolliset tulokset ei muuttuneet, mutta se muuttui mitä annoit isalnumille syötteeksi.

jogi [27.08.2014 00:06:34]

#

Grez kirjoitti:

jogi kirjoitti:

mutta ei näytetty miten sitä sovelletaan tilanteeseen, jossa ei vain haluta tietää onko vastaus "True" vai "False".

No edelleenhän sinä halusit tietää nimen omaan tuon. Eli tulokseksi saat joka tapauksessa tosi/epätosi. Mahdolliset tulokset ei muuttuneet, mutta se muuttui mitä annoit isalnumille syötteeksi.

Ainut esimerkki .isalnumin käytöstä oli

01  # -*- coding: cp1252 -*-
02
03  merkkijono = "Sininen"
04
05  merkkijono_isolla = merkkijono.upper()
06  merkkijono_pienella = merkkijono.lower()
07
08  sijainti = merkkijono.find("nin")
09  muutettu = merkkijono.replace("i","o")
10  testi_1 = merkkijono.isalpha()
11  testi_2 = merkkijono.isdigit()
12  testi_3 = merkkijono.endswith("nen")
13
14  print(merkkijono_isolla, merkkijono_pienella, muutettu)
15  print("Merkkijono 'ini' on paikasta",sijainti,"eteenpäin.")
16  print(testi_1,": merkkijono sisältää pelkästään kirjaimia.")
17  print(testi_2,": jono ei ole numeroarvo.")
18  print(testi_3,": merkkijono loppuu merkkeihin 'nen'")

mikä ei mielestäni hirveästi valaise tilannetta. if sala.isalnum():in osasin päätellä, mutta if salasana.strip("\n").isalnum(): kaltaista letkaa ei ole edes esitelty. Ainoastaan formaatissa if salasana = rstrip(isalnum('\n')): on esitetty yhdistettyjä funktioita. Siksi tuotti paljon vaikeuksia saada tuota toimimaan.

Metabolix [27.08.2014 17:39:54]

#

jogi kirjoitti:

mutta if salasana.strip("\n").isalnum(): kaltaista letkaa ei ole edes esitelty

Ohjelmoinnin eräs pääasia on jakaa ongelma osiin ja ratkaista osat erikseen. Jos jokainen erilainen ”letka” pitää erikseen opettaa, ohjelmoinnista ei tule ikinä mitään. Sitä paitsi – jos luit edellisen viestini – tuo letka ei ole viisas ratkaisu ongelmaan, koska tarvitset salasanaa kahdessa muussakin kohdassa (vaikka et korjannutkaan niitä varoituksestani huolimatta) ja oikea salasana on siis selvintä tallentaa muuttujaan.

Ongelmien selvittelyssä auttaa mm. funktio repr, jolla näkee muuttujan sisällön Python-koodina. Nytkin olisit voinut selvittää tilanteen pala kerrallaan näin:

  1. Miten luetaan tiedosto? Tämä on kai opetettu. Kokeeksi tulostetaan rivit.

    tiedosto = open("merkkijonoja.txt", "r")
    for rivi in tiedosto:
    	print(repr(rivi))
  2. Miten rivistä saadaan salasana? Yllä selviää, että rivi on muotoa 'teksti\n'. Selvästi '\n' pitää poistaa.

    salasana = rivi.strip("\n")
    print(repr(salasana))
  3. Miten salasanan sisältö tarkistetaan? Suoraan vanhan tietosi mukaan isalnum-funktiolla.

    kelpaa = salasana.isalnum()
    print(kelpaa)
  4. Miten tehdään ehtolause kelpaa-muuttujan suhteen? Helppo!

    if kelpaa:
    	print(salasana, "kelpaa")
    else:
    	print(salasana, "ei kelpaa")

Yllä edetään loogisesti asia kerrallaan ja jokaisen välivaiheen voi suoraan testata. Ainoa sinulle tuntematon asia oli strip-funktio, ja sillekin olit jo itse kehittänyt korvikkeen, joka olisi tapauksessasi toiminut.

Kokonaisuus:

tiedosto = open("merkkijonoja.txt", "r")
for rivi in tiedosto:
	salasana = rivi.strip("\n")
	kelpaa = salasana.isalnum()
	if kelpaa:
		print(salasana, "kelpaa")
	else:
		print(salasana, "ei kelpaa")

Lopuksi täytyy vielä huomauttaa, että vaadittu tarkistus on salasanoille äärimmäisen typerä: nyt esimerkiksi ”1” ja ”大きな木” kelpaavat mutta ”1+1” ja ”iso puu” eivät, eli tarkistus ei estä outojen merkkien käyttöä mutta estää kuitenkin monia järkeviä merkkejä.


Sivun alkuun

Vastaus

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

Tietoa sivustosta