vandræðum með lógík villu

19 views
Skip to first unread message

Sigurður Jónsson

unread,
Apr 30, 2011, 6:26:46 PM4/30/11
to Reykjavik Python User Group
Sælir,
Er nýr að reyna að læra Python og er í vandræðum með eitt verkefnið í
bókinni. Hún ætti að hætta eftir 7 tilraunir og segja niðrandi orð um
notandann en ég fæ ekki elif statementið til að virka. While virkar
með þvi að hætta eftir 7 tilraunir en þetta er ekki rétt. Ef ég set
while True þá kemur infinite loopa.

#!/usr/bin/env python3.1
#
# Guess my number game

import random

randomint = random.randint(1,100)
tries = 1

while tries <= 7:
guess = int(input("Guess a number between 1 and 100: "))
if guess < randomint:
print("Higher...")
tries += 1
continue
elif guess > randomint:
print("Lower...")
tries += 1
continue
elif tries > 7:
print("You suck!")
break
else:
print("Correct answer!")
print("You only needed", tries, "tries!")
break

Tómas Árni Jónasson

unread,
Apr 30, 2011, 6:50:30 PM4/30/11
to rp...@googlegroups.com
S�lir!

Well... til a� breyta k��anum sem minnst, �� v�ri l�klega best � a� nota bara
"True" sem skilyr�i fyrir while lykkjuna, og f�ra "elif tries > 7:" hlutann efst
� lykkjuna og fjarl�gja "el"-i�.... �.e.

#!/usr/bin/env python3.1
#
# Guess my number game

import random

randomint = random.randint(1,100)
tries = 1

while True:


if tries > 7:
print("You suck!")
break

guess = int(input("Guess a number between 1 and 100: "))
if guess < randomint:
print("Higher...")
tries += 1
continue
elif guess > randomint:
print("Lower...")
tries += 1
continue

else:
print("Correct answer!")
print("You only needed", tries, "tries!")
break

kv. T�mas �rni

On 04/30/2011 10:26 PM, Sigur�ur J�nsson wrote:
> S�lir,
> Er n�r a� reyna a� l�ra Python og er � vandr��um me� eitt verkefni� �
> b�kinni. H�n �tti a� h�tta eftir 7 tilraunir og segja ni�randi or� um
> notandann en �g f� ekki elif statementi� til a� virka. While virkar
> me� �vi a� h�tta eftir 7 tilraunir en �etta er ekki r�tt. Ef �g set
> while True �� kemur infinite loopa.

Bjarni Ragnarsson

unread,
Apr 30, 2011, 6:54:16 PM4/30/11
to rp...@googlegroups.com
Blessaður Sigurður

Fyrst er athugað hvort guess sé minni en randomint og svo hvort hún er
stærri en randomint þannig að ekki reynir á " elif tries > 7: " nema
guess sé akkúrat rétt tala. Ekki alveg rétt lógík í þessu.

kv.Bjarni

2011/4/30 Sigurður Jónsson <sigg...@gmail.com>:

> --
> You received this message because you are subscribed to "Reykjavik Python User Group" group.
> To unsubscribe, send an email to rpug-uns...@googlegroups.com

Baldur Þór Emilsson

unread,
Apr 30, 2011, 7:08:58 PM4/30/11
to rp...@googlegroups.com
Það er alls ekki augljóst en bæði for og while lykkjur geta haft else-hluta í Python. Hann er alltaf keyrður eftir að lykkjan lýkur sér af, nema hún endi í break setningu.
Það er þá hægt að gera þetta svona líka:


import random

randomint = random.randint(1,100)

for i in range(1,8):

    guess = int(input("Guess a number between 1 and 100: "))
    if guess < randomint:
        print("Higher...")
    elif guess > randomint:
        print("Lower...")
    else:
        print("Correct answer!")
        if i == 1:
            print("You only needed %d try!" % i)
        else:
            print("You only needed %d tries!" % i)
        break
else:
    print("The number is %d" % randomint)


2011/4/30 Bjarni Ragnarsson <bja...@gmail.com>

Sigurður Jónsson

unread,
Apr 30, 2011, 7:23:12 PM4/30/11
to Reykjavik Python User Group
Kúl takk Tómas og allir hiinir, var ekki að sjá lógíkina í þessu. Þið
þurfið ábyggilega ekki á þessari bók að halda en ef það eru einhverjir
byrjendur eins og ég þá er Python for the absolute beginner frábær
bók, kennir manni forritun á einfaldan hátt með að smíða leiki, frá
console uppí gui. Mjög frískandi miðað við hundleiðinlegar
forritunarbækur sem maður hefur reynt að lesa. Kannski get ég lært
forritun eftir allt.

Kjartan Kári Garðarsson Mýrdal

unread,
Apr 30, 2011, 6:57:40 PM4/30/11
to rp...@googlegroups.com
Sæll Sigurður, eins og þú setur þetta upp þá gerist bara eitt af
möguleikunum þínum, þeas

if satt/ósatt:
þetta getur gerst
elif satt/ósatt:
eða þetta getur gerst
else:
eða þetta

en það geta ekki tvö af þeim gerst eða fleiri. Þannig þegar þú gerir
fyrstu tvær athuganirnar og önnur hvor þeirra er rétt þá athugar
forritð ekki skilyrðin sem þú setur seinna og framkvæmir því ekki það
sem er þar þó að fullyrðingin sé rétt (tries > 7).

-Kjartan

2011/5/1 Sigurður Jónsson <sigg...@gmail.com>:

Sushanta Babason

unread,
May 2, 2011, 4:42:46 AM5/2/11
to rp...@googlegroups.com
Svona fyrst þú ert að læra þá ákvað ég að sitja ekki á mér.
Skilyrðið "elif tries > 7" er ekki athugað nema giskað sé á rétt (þegar geuss er hvorki minna né stærra en randomint) því væri heppilegra að athuga fyrst um fjölda tilrauna.
Og svo vísa ég í hann Bjarna með eigin orðum.
Setningin "while tries <= 7:" þýðir að lykkjan hættir að keyra ef tries er stærra en 7, þess vegna kemur aldrei til þess að "elif tries > 7" sé uppfyllt, lykkjan er jú hætt að keyra.

2011/4/30 Sigurður Jónsson <sigg...@gmail.com>
--
You received this message because you are subscribed to "Reykjavik Python User Group" group.
To unsubscribe, send an email to rpug-uns...@googlegroups.com



--
We used to laugh at Grandpa when he'd head off and go fishing. But we wouldn't be laughing that evening when he'd come back with some whore he picked up in town.

- Jack Handey (aka Jack Handy )

Aðalsteinn Rúnar Óttarsson

unread,
May 2, 2011, 8:59:38 AM5/2/11
to rp...@googlegroups.com

Arnar Birgisson

unread,
May 2, 2011, 10:03:24 AM5/2/11
to rp...@googlegroups.com
Hæ, hæ,

Það er ekki miklu við að bæta, en langar samt að benda á nokkra hluti
hvernig vanari forritari myndi skrifa.

Varðandi vandamálið sem þú spurðir um, þá er besta python lausnin að
mínu mati sú sem Baldur Þór benti á, að nota else-blokk á while. Else
blokkin er aðeins keyrð þegar skilyrðið í while hausnum verður ósatt,
en ekki þegar þú "breikar" út úr lykkjunni (virkar semsagt alveg eins
og else blokk í if-else).

Inn í if blokkunum ertu með kóða sem er endurtekinn, "tries += 1".
Þetta bendir til þess að kóðinn eigi frekar (lógískt) heima sem
óskilyrtur kóði í lykkjunni. Continue er einnig óþarft, því í báðum
tilfellum er það það síðasta sem lykkjan gerir. Stundum getur þó verið
gott að setja það inn fyrir lesanleika, ef um mörgt
if-elif-elif-elif-... er að ræða.

Hækkunina á tries myndi ég setja sem næst input skipuninni, því það er
í raun og veru það sem notandinn skynjar sem "try". Það er gott að
koma sér upp vana að raða kóðanum upp lógískt þannig, jafnvel þó
niðurstaðan yrði sú sama, því raunverulegur kóði mun breytast í
framtíðinni og þá er gott að hafa hluti sem lógískt eiga saman á sama
stað, t.d. svo ef öðrum er breytt að þá gleymist ekki að endurskoða
hinn.

Ég myndi því raða þessu þannig:

import random

randomint = random.randint(1,100)
tries = 0

while tries <= 7:
       guess = int(input("Guess a number between 1 and 100: "))

tries += 1


       if guess < randomint:
               print("Higher...")

       elif guess > randomint:
               print("Lower...")

       else:
               print("Correct answer!")
               print("You only needed", tries, "tries!")
               break

else:
print("You suck")

kv,
Arnar

2011/5/1 Sigurður Jónsson <sigg...@gmail.com>:

Arnar Birgisson

unread,
May 2, 2011, 10:07:48 AM5/2/11
to rp...@googlegroups.com
Ehrm.. ég "ákvað" að gefa sýnidæmi um hvað það er auðvelt að gera
one-off villur :)

2011/5/2 Arnar Birgisson <arn...@gmail.com>:
> while tries <= 7:

ætti að vera while tries < 7:

kv,
Arnar

Friðrik Már Jónsson

unread,
May 2, 2011, 10:22:11 AM5/2/11
to rp...@googlegroups.com
Af þessari ástæðu (off-by-one) væri ég jafnvel hrifnari af `xrange(7)` í þessu samhengi.  Þumalputtaregla sem auðvelt er að sjá með `range(...)` og `xrange(...)` er að ef þú hefur aðeins eina færibreytu eru jafn mörg stök í listanum eða generatornum sem myndast; þannig hefur `range(10)` einmitt 10 stök.  `for i in xrange(7):` ætti því að gefa mjög skýrt til kynna að lykkjan keyrir 7 sinnum, þar sem hvergi er samanburður sem ber með sér hættuna á off-by-one.

Þetta ber með sér annan kost, sem er sá að þetta er eini staðurinn sem sér um ákvörðun á hversu oft lykkjan keyrir; engin þörf er á `tries += 1` inni í lykkjunni eða `tries = 0` fyrir utan hana, sem væri þó stærra vandamál ef lykkjan væri stærri.  Þetta sparar auðvitað línur, en hefur líka þann kost að með því að skoða línuna `for i in xrange(7):` er ljóst að ekkert utanaðkomandi hefur áhrif á hversu oft lykkjan keyrir.  Þannig er öruggara er að gera breytingar og aðeins einn staður til að gera vitleysur sem hafa áhrif á lykkjuna, en ekki þrír.

Langur texti um lítil atriði.  Okkur finnast svona hlutir oft smáatriði af því að við trúum okkur ekki til að gera svona villur oft, en litlu varúðarráðstafanirnar minnka samt tíðnina og geta haft mikil áhrif þar sem villur eru illa liðnar.

Kveðja,
Friðrik Már

2011/5/2 Arnar Birgisson <arn...@gmail.com>

--
Reply all
Reply to author
Forward
0 new messages