Stafarugl

Umstöfun (e. anagram)

Þetta verkefni gengur út á að skrifa fall sem ...

  • tekur inn tvo strengi (e. strings),

  • athugar hvort strengirnir innihaldi sömu stafi

  • og skilar annað hvort True eða False

Í þessu verkefni koma fyrir eftirfarandi þættir:

  • Strengir

  • tvíundabreytur

  • if-setning

  • innbyggð föll

Hvað er umstöfun?

Þegar við segjum að orð (eða strengur) sé umstöfun af öðru orði, þá þýðir það að bæði orðin innihalda sömu stafina í mismunandi röð. Dæmi um það gætu verið:

  • Lás - Sál

  • 1234321 - 3132142

  • Tom Marvolo Riddle - I am Lord Voldemort

Hverju stefnum við að?

Virkni einfaldrar útgáfu þessa forrits gæti litið svona út:

>>> ath_stafarugl('Lás','Sál')
Lás og Sál
True
>>> ath_stafarugl(str(1234321), str(3132142))
1234321 og 3132142
True
>>> ath_stafarugl('Tom Marvolo Riddle','I am Lord Voldemort')
Tom Marvolo Riddle og Tom Marvolo Riddle
True

Hvernig leysum við verkefnið?

Þegar við viljum bera saman tvo hluti, hvort sem þeir eru strengir eða tölur, í Python þá notum við samanburðarvirkjana '=='.

>>> 'aa' == 'aa'
True
>>> 'aa' == 'ab'
False
>>> 123==123
True
>>> 123==321
False

Vandamálið er að samanburðarvirkinn skoðar eingöngu hvort að strengir eða tölur séu nákvæmlega eins en ekki hvort að þeir innihaldi sömu stafina:

>>> 'ab' == 'ba'
False

Byrjum því forritið okkar á að skilgreina hvað það heitir og láta það taka inn tvo strengi til þess að bera saman. Bætum einnig við prentskipun í upphafi til þess að sjá strengina fyrir samanburð.

def ath_stafarugl(tilraun, upphafs_texti):
    print(tilraun, 'og', upphafs_texti)

Næst þurfum við að nota samanburðarvirkjann og skila jákvæðu ef strengirnir reynast eins annars neikvæði. Við þurfum því að nota if-else setningu.

def ath_stafarugl(tilraun, upphafs_texti):
    print(tilraun, 'og', upphafs_texti)
    if tilraun == upphafs_texti:
      return true
    else:
      return false

Gerum nokkrar tilraunir með fallið okkar.

>>> ath_stafarugl('lás','lás')
lás og lás
True
>>> ath_stafarugl('lás','sál')
lás og sál
False

Forritið okkar virkar ef strengirnir eru alveg eins en ef þeir innihalda sömu stafina í annarri röð þá virkar forritið okkar. En þar sem við höfum bara áhuga á að athuga hvort að tveir strengir innihalda sömu stafina þá skiptir okkur engu máli í hvaða röð þeir eru þegar við berum þá saman. Þetta einfaldar líf okkar til muna því þá getum við líka leikið okkur aðeins með strengina.

Sorted fallið er innbyggt fall í Python og það gerir okkur kleift að endurraða hlutum. Fallið tekur inn streng og skilar af sér röðuðum lista. Skoðum aðeins hvernig það virkar :

>>> sorted('lás')
['l', 's', 'á']
>>> sorted('slá')
['l', 's', 'á']
>>> sorted('sál')
['l', 's', 'á']

Við þurfum því að breyta samanburðinum í fallinu okkar þannig að við erum að bera saman afrakstur sorteringarinnar en ekki sjálf inntaksskilyrðin. Það myndi líta svona út :

def ath_stafarugl(tilraun, upphafs_texti):
    print(tilraun, 'og', upphafs_texti)
    if sorted(tilraun) == sorted(upphafs_texti):
        return True
    else:
        return False

Prófum aftur að bera saman lás og slá og sjáum hvað gerist :

>>> ath_stafarugl('lás','sál')
lás og sál
True

Núna virðist forritið okkar virka ... NEMA hvað gerist ef við reynum að bera saman orðin þegar fyrsti stafurinn í hverju orði er stór (Lás og Slá):

>>> ath_stafarugl('Lás','Sál')
Lás og Sál
False

Þar sem að við viljum bara vita hvort sömu stafirnir eru í orðunum þá skiptir það okkur engu máli hvort orðin innihalda há- eða lágstafi. Við getum því annað hvort stækkað alla stafina í orðunum áður en við berum þau saman eða við getum minnkað alla stafina. Til þess að gera það getum við notað föllin upper() og lower(). Skoðum aðeins hvernig þau virka:

>>> 'Lás'.upper()
'LÁS'
>>> 'Lás'.lower()
'lás'

Við sjáum að við þurfum að skeyta þessu falli aftan við orðin eða strengina sem við erum að vinna með. Forritið okkar lítur þá svona út :

def ath_stafarugl(tilraun, upphafs_texti):
    print(tilraun, 'og', upphafs_texti)
    if sorted(tilraun.lower()) == sorted(upphafs_texti.lower()):
        return True
    else:
        return False

Prófum aftur að kalla á það með orðunum Lás og Slá og sjáum hvað gerist :

>>> ath_stafarugl('Lás','Sál')
Lás og Sál
True

Í upphafi verkefnisins skilgreindum við nokkrar umstafanir sem við skulum prófa á fallið. Við erum þegar búin að prófa Lás og Sál. Prófum næst tölurnar 1234321 og 3132142.

>>> ath_stafarugl(1234321, 3132142)
1234321 og 3132142
Traceback (most recent call last):
  File "<pyshell#45>", line 1, in <module>
    ath_stafarugl(1234321, 3132142)
  File "<pyshell#41>", line 3, in ath_stafarugl
    if sorted(tilraun.lower()) == sorted(upphafs_texti.lower()):
AttributeError: 'int' object has no attribute 'lower'

Fallið okkar virkar ekki ef við setjum tölur inn í það. Við þurfum því að byrja á að passa að umbreyta alltaf inntakinu okkar yfir í streng áður en við höldum áfram. Til þess að gera það notum við fallið str().

def ath_stafarugl(tilraun, upphafs_texti):
    tilraun = str(tilraun)
    upphafs_texti = str(tilraun)
    print(tilraun, 'og', upphafs_texti)
    if sorted(tilraun.lower()) == sorted(upphafs_texti.lower()):
        return True
    else:
        return False

Núna getum við aftur prófað tölurnar okkar og fullvissað okkur um að forritið okkar virkar fyrir þessar tvær tölur :

>>> ath_stafarugl(1234321, 3132142)
1234321 og 1234321
True

Prófum núna síðasta tilraunainntakið okkar - strengina Tom Marvolo Riddle og I am Lord Voldemort.

>>> ath_stafarugl('Tom Marvolo Riddle','I am Lord Voldemort')
Tom Marvolo Riddle og Tom Marvolo Riddle
True

Þetta skilar okkur líka jákvæðri niðurstöðu og forritið okkar er farið að virka fyrir þau dæmi sem við lögðum upp með í upphafi.

Last updated