Python beginnersvraag: vergelijken in een list

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • ralph t
  • Registratie: Juli 2009
  • Laatst online: 05-10 10:51
Beste tweakers,

Ten eerste hoop ik dat ik deze vraag op de juiste plek stel, zo niet, excuses.
Ik ben een volledige leek op het gebied van programmeren, de enige ervaring die ik heb, heb ik opgedaan met TI-basic op mijn grafische rekenmachine. Dit voor iteratieve doeleinden op school. Puur hobbymatig wil ik leren programmeren, dit doe ik met de app sololearn en tegelijkertijd probeer ik de opgedane kennis te gebruiken om wat (nutteloze) programma's te maken. Ik heb gekozen voor python.

Op dit moment ben ik een boter, kaas en eieren spelletje aan het maken en loop ergens tegenaan. Ik wil een controlestap inbouwen waardoor de invoer van de speler (X of O) wordt vergeleken met de waarde in de lijst waar deze in geplaatst moet worden, dit om te voorkomen dat een vak meer dan 1 keer ingevuld kan worden. Dit doe ik als volgt: (complete code volgt onderaan)

if str(veld[ui]) == "X" or "O":
print("dit veld is reeds gebruikt")
continue

dit lijkt altijd waar te zijn want dit wordt altijd uitgevoerd.

Ik hoop dat iemand me wil uitleggen wat ik verkeerd doe, bij voorbaat dank!

ps: ik realiseer me dat dit programma natuurlijk veeeel efficienter geschreven zou kunnen worden en dat hoop ik ook te leren, echter stap voor stap. Commentaar is uiteraard wel welkom maar dan graag in de vorm van hints zodat ik zelf weer iets kan uitvogelen.

het programma:

#maakt een lijst met waarden welke het veld voorstelt
veld = ["1","2","3","4","5","6","7","8","9"]

#defineer een functie om het veld te maken
def mkvld():
#verdeel de lijst in drie rijen
rij1 = [veld[0],veld[1],veld[2]]
rij2 = [veld[3],veld[4],veld[5]]
rij3 = [veld[6],veld[7],veld[8]]
#geef de rijen weer
print(rij1)
print(rij2)
print(rij3)

#hoofdprogramma

#bepaal welke speler aan de beurt is
a = 0

#loop
while True:
#geef het veld weer
mkvld()

#bepaal welke speler aan de beurt is.
if a == 0:
print("speler X is aan de beurt")
teken = "X"
elif a == 1:
print("speler O is aan de beurt")
teken = "O"

#vraag de speler om input
ui = int(input(("voer het nummer van het veld in om een teken te plaatsen, typ 10 om te stoppen:"))) - 1

#stop het spel (wanneer de speler 10 heeft ingevoerd)
if ui == 9:
print("programma wordt gesloten")
break

#controleer of het veld nog beschikbaar is !!waarom werkt dit niet??!!
#print(veld[ui])
if str(veld[ui]) == "X" or "O":
print("dit veld is reeds gebruikt")
continue

#plaats het teken op de juiste plaats
veld[ui] = teken

#controleer of er een winnaar is en sluit af
#to do

#controleer of het veld vol is en sluit af
#to do

#wissel van speler
if a == 0:
a =+ 1
elif a == 1:
a = a - 1

Beste antwoord (via ralph t op 17-05-2018 23:07)


  • Dogooder
  • Registratie: April 2004
  • Laatst online: 12:31

Dogooder

dus...

je if statement is niet helemaal goed.
je voert nu eigenlijk uit:
if str(veld[ui]) == "X" OR if "O":
if '<string>': is altijd waar.

probeer is if str(veld[ui]) == "X" or str(veld[ui]) == "O":
of
if str(veld[ui]) == ("X" or "O"):

[ Voor 31% gewijzigd door Dogooder op 17-05-2018 23:05 ]

Alle reacties


Acties:
  • Beste antwoord
  • +1 Henk 'm!

  • Dogooder
  • Registratie: April 2004
  • Laatst online: 12:31

Dogooder

dus...

je if statement is niet helemaal goed.
je voert nu eigenlijk uit:
if str(veld[ui]) == "X" OR if "O":
if '<string>': is altijd waar.

probeer is if str(veld[ui]) == "X" or str(veld[ui]) == "O":
of
if str(veld[ui]) == ("X" or "O"):

[ Voor 31% gewijzigd door Dogooder op 17-05-2018 23:05 ]


Acties:
  • +1 Henk 'm!

  • Klaasvaak
  • Registratie: Maart 2010
  • Laatst online: 05-10 13:10
Beide vergelijkingen moeten volledig worden uitgewerkt.
code:
1
if str(veld[ui]) == "X" or str(veld[ui]) == "O":

Acties:
  • 0 Henk 'm!

  • ralph t
  • Registratie: Juli 2009
  • Laatst online: 05-10 10:51
Dogooder en Klaasvaak bedankt! Nu ik het zo zie, valt het kwartje!

Acties:
  • +2 Henk 'm!

  • Elfjes
  • Registratie: Januari 2007
  • Niet online
of anders:
code:
1
if str(veld[ui]) in ["O", "X" ]


En volgens mij is de str cast ook niet per se nodig

Bla bla bla...


Acties:
  • +1 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
"A good programmer is someone who looks both ways before crossing a one-way street." - Doug Linder
Aangenomen dat een leeg vakje gerepresenteerd wordt door een lege string kun je je logica veel beter herschrijven:

pseudocode:
code:
1
2
3
4
if veld(coord) == "X" or veld(coord) == "Y" then
  Bezet
else
  Vrij

Is veel makkelijker te schrijven als:
code:
1
2
3
4
if veld(coord) == "" then
  Vrij
else
  Bezet


Want de eigenlijke vraag die je je stelt is niet: is het vakje bezet (en mag ik er dus geen zet doen) maar is het vakje vrij (en mag ik er dus een zet doen) :)

Dan vang je meteen "x", "X", "o", "O", "P", "A", "Duikboot" en "Appelflap" ;) Dan ben je meteen klaar voor "Boter, Kaas, Nutella en Eieren" en als bijkomstigheid hoef je niet voor elke mogelijke (al-dan-niet toekomstige) waarde nog een keer str() te invoken (niet dat die nodig is overigens, maar was 't een andere ("dure") functie geweest gaat hetzelfde op en kun je potentieel een boel performance winnen ;) ).

[ Voor 36% gewijzigd door RobIII op 18-05-2018 08:33 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • +1 Henk 'm!

  • Elfjes
  • Registratie: Januari 2007
  • Niet online
RobIII schreef op vrijdag 18 mei 2018 @ 08:28:
[...]

Aangenomen dat een leeg vakje gerepresenteerd wordt door een lege string kun je je logica veel beter herschrijven:

pseudocode:
code:
1
2
3
4
if veld(coord) == "X" or veld(coord) == "Y" then
  Bezet
else
  Vrij

Is veel makkelijker te schrijven als:
code:
1
2
3
4
if veld(coord) == "" then
  Vrij
else
  Bezet


Want de eigenlijke vraag die je je stelt is niet: is het vakje bezet (en mag ik er dus geen zet doen) maar is het vakje vrij (en mag ik er dus een zet doen) :)

Dan vang je meteen "x", "X", "o", "O", "P", "A", "Duikboot" en "Appelflap" ;) Dan ben je meteen klaar voor "Boter, Kaas, Nutella en Eieren" en als bijkomstigheid hoef je niet voor elke mogelijke (al-dan-niet toekomstige) waarde nog een keer str() te invoken (niet dat die nodig is overigens, maar was 't een andere ("dure") functie geweest gaat hetzelfde op en kun je potentieel een boel performance winnen ;) ).
Waarbij het dan weer handiger is om wel eerst een verkeerde move te herkennen en daarna pas verder te gaan

code:
1
2
3
4
if veld(coord) !="" then 
  Bezet
  continue
Vrij


overigens werkt dat alleen als de array in het begin leeg is. Op dit moment is ie altijd gevuld

Bla bla bla...


Acties:
  • +1 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Dogooder schreef op donderdag 17 mei 2018 @ 23:02:
if str(veld[ui]) == ("X" or "O"):
code:
1
2
3
4
>>> "a" == ("a" or "b")
True
>>> "b" == ("a" or "b")
False

Elfjes heeft de juiste code.

[ Voor 6% gewijzigd door GlowMouse op 18-05-2018 09:36 ]


Acties:
  • +1 Henk 'm!

  • Morrar
  • Registratie: Juni 2002
  • Laatst online: 11:06
Je kan ook doen:

Python:
1
2
if veld[ui] in ['X', 'O']:
  ...


Korter en vaak beter leesbaar.


Edit: Spuit elf... stond er al tussen.

[ Voor 16% gewijzigd door Morrar op 18-05-2018 10:00 ]


Acties:
  • 0 Henk 'm!

  • ralph t
  • Registratie: Juli 2009
  • Laatst online: 05-10 10:51
Elfjes schreef op vrijdag 18 mei 2018 @ 08:19:
of anders:
code:
1
if str(veld[ui]) in ["O", "X" ]


En volgens mij is de str cast ook niet per se nodig
geprobeerd zonder str en inderdaad niet nodig.

ik heb je code getest en deze werkt, ik snap alleen nog niet zo goed wat deze doet.

Acties:
  • 0 Henk 'm!

  • ralph t
  • Registratie: Juli 2009
  • Laatst online: 05-10 10:51
RobIII schreef op vrijdag 18 mei 2018 @ 08:28:
[...]

Aangenomen dat een leeg vakje gerepresenteerd wordt door een lege string kun je je logica veel beter herschrijven:

pseudocode:
code:
1
2
3
4
if veld(coord) == "X" or veld(coord) == "Y" then
  Bezet
else
  Vrij

Is veel makkelijker te schrijven als:
code:
1
2
3
4
if veld(coord) == "" then
  Vrij
else
  Bezet


Want de eigenlijke vraag die je je stelt is niet: is het vakje bezet (en mag ik er dus geen zet doen) maar is het vakje vrij (en mag ik er dus een zet doen) :)

Dan vang je meteen "x", "X", "o", "O", "P", "A", "Duikboot" en "Appelflap" ;) Dan ben je meteen klaar voor "Boter, Kaas, Nutella en Eieren" en als bijkomstigheid hoef je niet voor elke mogelijke (al-dan-niet toekomstige) waarde nog een keer str() te invoken (niet dat die nodig is overigens, maar was 't een andere ("dure") functie geweest gaat hetzelfde op en kun je potentieel een boel performance winnen ;) ).
mijn velden zijn niet leeg, het opvangen van verkeerde input ben ik inmiddels al anders aan het oplossen, ik neem je goede raad mee voor een volgend probeersel.

Acties:
  • +1 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Dat is besides the point; ongeacht of je een veld waar geen "X" of "O" in staat staat nou representeert met "" of "-" of "." of null of whatever; je hebt een state "bezet" (of het nou X, O of appelflap is) en een state "vrij". En je wil (op een makkelijke, "goedkope", "efficiente") manier bepalen of een veld bezet of vrij is; dan kun je "een heleboel" voorwaarden checken (zoals je deed) om te kijken of een veld bezet is of een enkele voorwaarde checken om te kijken of een veld vrij is.
ralph t schreef op vrijdag 18 mei 2018 @ 21:03:
het opvangen van verkeerde input ben ik inmiddels al anders aan het oplossen
Wederom besides the point. Je kunt prima alleen een X of O input toestaan en alle andere input afschieten en dat zal méér dan voldoen voor je opdracht maar "in the real world" krijg je straks te maken met allerlei andere manieren waarop je datamodel aangepast wordt (door derden, andere services, iemand die buiten de software om gewoon in de database zit te rommelen, etc. etc.) en dan kom je er dus niet alleen met input afvangen; who knows hoe/waardoor je datamodel (in een groter systeem, ooit, in de toekomst) wordt aangepast. En daar slaat die quote op waarmee ik opende. Je zult, never, ever, nooit alle mogelijke toekomstige zaken kunnen voorzien en ergens moet je een lijn trekken waar nog meer 'beveiliging' inbouwen de tijd/investering gewoonweg niet waard is. Maar in een dergelijk simpel geval als wat ik hier aankaartte loont 't zich, zoals je zag, al vrij gauw om soms even nét wat langer stil te staan bij een regel code. Als je daar een 'tweede natuur' van maakt is die extra tijd over een poosje verwaarloosbaar en profiteer je er in de toekomst gegarandeerd van ;)
ralph t schreef op vrijdag 18 mei 2018 @ 21:03:
ik neem je goede raad mee voor een volgend probeersel.
Mission accomplished d:)b

[ Voor 6% gewijzigd door RobIII op 19-05-2018 00:16 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • +1 Henk 'm!

  • MdBruin
  • Registratie: Maart 2011
  • Laatst online: 12-05-2024
[message=55242871,noline]ralph t schreef op vrijdag 18 mei 2018

ik heb je code getest en deze werkt, ik snap alleen nog niet zo goed wat deze doet.
Ik weet niet of je er al achter bent wat de "in" vergelijker doet, maar hierbij een uitleg van ook een beginner in Python.

De in vergelijker kan je zien als een ==, het verschil is alleen dat de == 1 waarde accepteert en de in meerdere. De in verwacht een list met 1 of meerdere waarden waar tegen gecontroleerd moeten worden.

Edit: maar wel in or mode en niet in and.

[ Voor 4% gewijzigd door MdBruin op 23-05-2018 12:18 . Reden: Toevoeging ]

Pagina: 1