Re: [Tutor] Crazy craps problem

2011-10-09 Thread col speed
<-->  snip
>> if point(one+two) == "win":
>>
>
> Here you go into the function "point" the first time. Inside the function
> you are in an infinite while-loop where you only exit if the sum is either 7
> ("lose") or equal the given parameter ("win"). Then you compare the return
> value. In the case of "lose" you continue to the next elif-statement:
>
>
>  stake += bet*2
>> print winmsg
>> elif  point(one+two) == "lose":
>>
>
> Now you go into the function "point" a *second* time, in other words you
> have to throw another 7 to leave the function with the return value "lose".
> But just now you will print out the message for loosing the game:
>
>
>  print losemsg
>> player = changePlayer(player)
>>
>
> What you probably want is to go into "point" only once, save the result
> value and check if it's "win" or "lose".
>
> HTH,
>
> Andreas
>
>
Amazing as always. I will act upon all suggestions.
Thanks again
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Crazy craps problem

2011-10-08 Thread Andreas Perstinger

On 2011-10-09 08:25, col speed wrote:

Thanks for your prompt reply! Here's the whole thing:

import random

message = """Welcome to craps Place your bet
  and roll the dice.
  7 or 11 wins.
  2, 3 or 12 loses.
  Others are "point"."""
player = "Your"
dice = range(1, 7)
stake = 100
bet = 5
winmsg = "You have won!You have ${0} left.".format(stake)
losemsg = "You have lost! You have ${0} left.".format(stake)
players = ["Your", "My"]

def win(num):
 if num in [7,11]:
 return "win"
 elif num in [2,3,12]:
 return "lose"
 else:
 return "point"

def changePlayer(player):
 if player == "Your":
 return "My"
 else:
 return "Your"

def point(num):
 while True:
 raw_input("Roll")
 uno, dos = random.choice(dice), random.choice(dice)
 three = uno+dos
 print "{0} + {1} = {2}".format(uno, dos, three)
 print "Point is {0}. You scored {1}.".format(num, three)
 if three == num:
 return "win"
 if three == 7:
 return "lose"
 else:
 print "Try again."

print message
while stake:
 print "{0} throw! You have ${1}. How much do you bet?".format(player,
stake)
 bet = int(raw_input("$"))
 stake -= bet
 one, two = random.choice(dice), random.choice(dice)
 print "{0} + {1} = {2}".format(one, two, one+two)
 if win(one+two) == "win":
 stake += bet*2
 print winmsg
 elif win(one+two) == "lose":

 print losemsg
 else:
 if point(one+two) == "win":


Here you go into the function "point" the first time. Inside the 
function you are in an infinite while-loop where you only exit if the 
sum is either 7 ("lose") or equal the given parameter ("win"). Then you 
compare the return value. In the case of "lose" you continue to the next 
elif-statement:



 stake += bet*2
 print winmsg
 elif  point(one+two) == "lose":


Now you go into the function "point" a *second* time, in other words you 
have to throw another 7 to leave the function with the return value 
"lose". But just now you will print out the message for loosing the game:



 print losemsg
 player = changePlayer(player)


What you probably want is to go into "point" only once, save the result 
value and check if it's "win" or "lose".


HTH,
Andreas


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Crazy craps problem

2011-10-08 Thread Steven D'Aprano

col speed wrote:

Hi again, Once more I've come up with a problem I can't explain. It must be
something simple, but I can't work it out.
The part of the script that is causing the problem is as follows:


def point(num):
while True:
raw_input("Roll")


You ask the user for input, but don't do anything with their answer. Is 
that deliberate?




uno, dos = random.choice(dice), random.choice(dice)
three = uno+dos


It is confusing to have a variable called "three" which isn't equal to 
three. Likewise for "uno" and "dos", especially for Spanish or Italian 
speakers.




print "{0} + {1} = {2}".format(uno, dos, three)
print "Point is {0}. You scored {1}.".format(num, three)
if three == num:
return "win"


What happens if the caller passes 7 as the argument to point?



if three == 7:
return "lose"
else:
print "Try again."

What I have tried to do is - simulate dice throws, if the total is the same
as originally thrown, return from the function(this works). If I throw a 7,
I also want to return(this does not work as you can see from this sample
output:



I cannot confirm that behaviour. When I try it, it works as expected: if 
you throw seven, it breaks out of the loop and you lose immediately.


I've tried that a couple of times, but because the scores are random, it 
takes a while. So I monkey-patched the game for testing purposes:



Kids! Don't do this at home! Monkey-patching is bad and wrong! 


>>> class MonkeyPatchedRandom:
... scores = [6, 1, 3, 4, 5, 6, 2, 1, 1, 3]
... index = -1
... def choice(self, arg):
... self.index += 1
... return self.scores[self.index]
...
>>> random = MonkeyPatchedRandom()
>>> point(3)
Roll
6 + 1 = 7
Point is 3. You scored 7.
'lose'
>>>


As you can see, if you happen to roll 7 on the first go, it exits the 
loop as expected.



[...]

Point is 4. You scored 7.
You have lost! You have $100 left.


There is nothing in the point() function that could possible print "You 
have lost". There is obviously some other code that you aren't showing us.




As you can see, after throwing a 7, it just continues. It only returns after
throwing a second 7.

1. I know it's bad form to print from a function, I'll change it later.


A better way of stating this is that you should separate *interface* 
from *implementation*: printing messages to the user is part of the 
interface, and actually comparing dice rolls and deciding whether you 
have won or lost is part of the implementation, so they should be in 
separate functions.




2. I've tried the second if statement using "elif".
3. I've tried omitting the "three" variable and just using "uno" + "dos".
4. I've used "uno" and "dos" because I use "one" and "two" in another part
of the script(outside and after the function definition), although they
shouldn't be affected in any way.


Local variables are local. You don't need to fear that variables "one" 
and "two" inside function A will clash with variables inside function B 
(unless you declare them as global!). So don't worry about having every 
variable in every function have a unique name.


More importantly, though, it is confusing to name a variable "one". One 
what? Better names would be "roll_one", "score_one", "dice_a", or even 
"a" and "b" -- at least they are *generic* names and you won't fool the 
reader into expecting that variable two == 2.




--
Steven

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Crazy craps problem

2011-10-08 Thread col speed
On 9 October 2011 13:17, Andreas Perstinger wrote:

> On 2011-10-09 07:16, col speed wrote:
>
>> The part of the script that is causing the problem is as follows:
>>
>> def point(num):
>> while True:
>> raw_input("Roll")
>> uno, dos = random.choice(dice), random.choice(dice)
>> three = uno+dos
>> print "{0} + {1} = {2}".format(uno, dos, three)
>> print "Point is {0}. You scored {1}.".format(num, three)
>> if three == num:
>> return "win"
>> if three == 7:
>> return "lose"
>> else:
>> print "Try again."
>>
>> What I have tried to do is - simulate dice throws, if the total is the
>> same
>> as originally thrown, return from the function(this works). If I throw a
>> 7,
>> I also want to return(this does not work as you can see from this sample
>> output:
>>
>
> I'm pretty sure that your problem is not in the code snippet you have shown
> us. Here it works as expected (I've copied your code, added "import random"
> and "dice = [1, 2, 3, 4, 5, 6]" at the top and saved as "dice.py"):
>
> Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24)
> [GCC 4.5.2] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
> >>> import dice
> >>> dice.point(1)
> Roll
> 4 + 5 = 9
> Point is 1. You scored 9.
> Try again.
> Roll
> 4 + 3 = 7
> Point is 1. You scored 7.
> 'lose'
> >>>
>
> Please show us the part where you use the "point" function.
>
> Bye, Andreas
> __**_
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/**mailman/listinfo/tutor
>


Thanks for your prompt reply! Here's the whole thing:

import random

message = """Welcome to craps Place your bet
 and roll the dice.
 7 or 11 wins.
 2, 3 or 12 loses.
 Others are "point"."""
player = "Your"
dice = range(1, 7)
stake = 100
bet = 5
winmsg = "You have won!You have ${0} left.".format(stake)
losemsg = "You have lost! You have ${0} left.".format(stake)
players = ["Your", "My"]

def win(num):
if num in [7,11]:
return "win"
elif num in [2,3,12]:
return "lose"
else:
return "point"

def changePlayer(player):
if player == "Your":
return "My"
else:
return "Your"

def point(num):
while True:
raw_input("Roll")
uno, dos = random.choice(dice), random.choice(dice)
three = uno+dos
print "{0} + {1} = {2}".format(uno, dos, three)
print "Point is {0}. You scored {1}.".format(num, three)
if three == num:
return "win"
if three == 7:
return "lose"
else:
print "Try again."

print message
while stake:
print "{0} throw! You have ${1}. How much do you bet?".format(player,
stake)
bet = int(raw_input("$"))
stake -= bet
one, two = random.choice(dice), random.choice(dice)
print "{0} + {1} = {2}".format(one, two, one+two)
if win(one+two) == "win":
stake += bet*2
print winmsg
elif win(one+two) == "lose":

print losemsg
else:
if point(one+two) == "win":
stake += bet*2
print winmsg
elif  point(one+two) == "lose":

print losemsg
player = changePlayer(player)

Thanks
Col
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Crazy craps problem

2011-10-08 Thread Andreas Perstinger

On 2011-10-09 07:16, col speed wrote:

The part of the script that is causing the problem is as follows:

def point(num):
 while True:
 raw_input("Roll")
 uno, dos = random.choice(dice), random.choice(dice)
 three = uno+dos
 print "{0} + {1} = {2}".format(uno, dos, three)
 print "Point is {0}. You scored {1}.".format(num, three)
 if three == num:
 return "win"
 if three == 7:
 return "lose"
 else:
 print "Try again."

What I have tried to do is - simulate dice throws, if the total is the same
as originally thrown, return from the function(this works). If I throw a 7,
I also want to return(this does not work as you can see from this sample
output:


I'm pretty sure that your problem is not in the code snippet you have 
shown us. Here it works as expected (I've copied your code, added 
"import random" and "dice = [1, 2, 3, 4, 5, 6]" at the top and saved as 
"dice.py"):


Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dice
>>> dice.point(1)
Roll
4 + 5 = 9
Point is 1. You scored 9.
Try again.
Roll
4 + 3 = 7
Point is 1. You scored 7.
'lose'
>>>

Please show us the part where you use the "point" function.

Bye, Andreas
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] Crazy craps problem

2011-10-08 Thread col speed
Hi again, Once more I've come up with a problem I can't explain. It must be
something simple, but I can't work it out.
The part of the script that is causing the problem is as follows:


def point(num):
while True:
raw_input("Roll")
uno, dos = random.choice(dice), random.choice(dice)
three = uno+dos
print "{0} + {1} = {2}".format(uno, dos, three)
print "Point is {0}. You scored {1}.".format(num, three)
if three == num:
return "win"
if three == 7:
return "lose"
else:
print "Try again."

What I have tried to do is - simulate dice throws, if the total is the same
as originally thrown, return from the function(this works). If I throw a 7,
I also want to return(this does not work as you can see from this sample
output:

Try again.
Roll
6 + 1 = 7
Point is 4. You scored 7.

<--> snip

4 + 1 = 5
Point is 4. You scored 5.
Try again.
Roll
3 + 4 = 7
Point is 4. You scored 7.
You have lost! You have $100 left.

As you can see, after throwing a 7, it just continues. It only returns after
throwing a second 7.

1. I know it's bad form to print from a function, I'll change it later.
2. I've tried the second if statement using "elif".
3. I've tried omitting the "three" variable and just using "uno" + "dos".
4. I've used "uno" and "dos" because I use "one" and "two" in another part
of the script(outside and after the function definition), although they
shouldn't be affected in any way.

Any help greatly appreciated.
Thanks
Col
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor