any suggestions on shortening this python code? [closed] - python

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I have created a program which rolls a dice according to the amount of sides that the user enters. Here is my code:
def var():
import random
dicesides = int(input("Please enter the amount of sides you want the dice that is being thrown to have. The dice sides available are: 4, 6 and 12: "))
script(dicesides, random)
def script(dicesides, random):
if dicesides == 4:
dice4 = int(random.randrange(1, dicesides))
print(dicesides, " sided dice, score", dice4)
elif dicesides == 6:
dice6 = int(random.randrange(1, dicesides))
print(dicesides, " sided dice, score", dice6)
elif dicesides == 12:
dice12 = int(random.randrange(1, dicesides))
print(dicesides, " sided dice, score", dice12)
elif dicesides != 4 or dicesides != 6 or dicesides != 12:
print("That number is invalid. Please try again.")
var()
repeat = str(input("Repeat? Simply put yes or no : "))
if repeat == "yes":
var()
else:
quit()
var()
is there a way for this to be shortened?
Thanks

You can simplify all three of those cases into one block because they all have the exact same action.
def script(dicesides, random):
if dicesides in [4,6,12]:
dice = int(random.randrange(1, dicesides))
print(dicesides, " sided dice, score", dice)
else:
print("That number is invalid. Please try again.")
var()
Whenever you see repeated patterns in your source code, you can usually extract them into a single block.

The whole program (especially without the recursion loop between var and script and the implied bombardment of the callstack. Although your calls are in tail position, this makes no difference in python):
from random import randint
while True:
sides = int(input('Please enter the amount of sides you want the dice that is being thrown to have. The dice sides available are: 4, 6 and 12:'))
if sides in (4, 6, 12):
print('{}-sided die, score {}'.format(sides, randint(1, sides)))
else:
print('That number is invalid.')
if input('Repeat? ') != 'yes':
break
Or the code-golf version of the whole program:
(lambda f,r:f(f, r))((lambda f,r:f(f,r)if((lambda r,i:
print('{}-sided die, score {}'.format(i,r.randint(1,i)
)if i in(4, 6,12)else'That number is invalid.')) (r, (
lambda:int(input('Please enter the amount of sides yo'
'u want the dice that is being thrown to have. The di'
'ce sides available are: 4, 6 and 12: ')))()),input(''
'Repeat? '))[1]=='yes'else None),__import__('random'))

Related

Three Problems that I can not resolve in python [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
So I am creating a new simple game to practice my python programming, it is a point/score system that I wanted to implement. I also wanted to make it so it's intelligent by asking the user if it wants to play. So I have three problems at the moment, when I ask the user if it wants to play I wasn't sure what to do if they said no or "n" if they didn't want to play, instead what happens is that it just continues playing then crashes saying "n" is not defined. The second problem that I have is when the user puts the right answer for the random function I put print("You guessed it right!") but it just prints a bunch of them. My third and final problem is the point system, I wasn't sure if it executed after the million printed statements, but I'll see after I fix it.
Here is my game
import random
total_tries = 4
score = 0
print("Welcome to Guess the number game!")
answer = input("Would you like to play? y/n: ")
if answer == "y":
n = (random.randrange(1, 10))
guess = int(input("I am thinking of a number between 1 and 20: "))
while n!= guess:
if guess < n:
total_tries - 1
print("That is too low!")
guess = int(input("Enter a number again: "))
elif guess > n:
print("That is too high")
total_tries - 1
guess = int(input("Enter a number again: "))
else:
break
while n == guess:
score = +1
print("You guessed it right!")
if total_tries == 0:
print("Thank you for playing, you got", score, "questions correct.")
mark = (score/total_tries) * 100
print("Mark:", str(mark) + ""%"")
print("Goodbye")
Error when putting no for playing:
while n!= guess:
NameError: name 'n' is not defined
For question 1 you want the system to exit when the user says no. I would do this by using sys.exit to kill the code.
import sys
...
answer = input("Would you like to play? y/n: ")
if answer == "y":
n = (random.randrange(1, 10))**strong text**
else:
sys.exit('User does not want to play, exiting')
For problem 2 you are getting your print statement a million times because you're failing to exit. In the code below n is always equal to guess because you never change n. You don't need a while statement here because you already know you only left the above section when n started to equal guess. Another issue to think about. How will you make it stop when the number of turns runs out?
while n == guess:
score = +1
print("You guessed it right!")
For the third question, think about what will happen here if the number of turns reaches 0.
if total_tries == 0:
print("Thank you for playing, you got", score, "questions correct.")
mark = (score/total_tries) * 100
In particular, what would happen when you try to calculate mark?
This condition will only trigger when answer is "y"
if answer == "y":
n = (random.randrange(1, 10))
Remove this and the code will run or modify it as such
if answer == "y":
n = (random.randrange(1, 10))
elif answer == "n"
# set n to some other value

Check whether sum of two list members can be found in another list [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
In this program I have written, so far you get a set of numbers. You choose the number of dice you would like to play with. Every turn you roll the num of dice, and choose two of them to sum to one of the numbers in your original number set.
I am trying to make it so if there are no possible numbers to sum together that would eliminate a number from the original number set. It will say "sorry no possible solutions" and skip the turn.
Eventually I will add the computer to vs and that's what it will skip too, but I would like to have this working first.
import random
lst_player = [2,3,4,5,6,7,8,9,10,11,12]
lst_cpu = [2,3,4,5,6,7,8,9,10,11,12]
num_dice = int(input("Enter the number of dice you would like to play with 3-5 :
"))
def stars():
count = 0
for count in range(30):
count += 1
print("*", end=' ')
print("")
stars()
print("Player set"," ",lst_player)
print("Computer set"," ",lst_cpu)
stars()
while lst_player or lst_cpu != []:
print("")
roll = input("Player turn, enter 'e' to roll : ")
dice_lst = []
if roll == "e":
for e in range(num_dice):
d_lst = random.randint(1,6)
dice_lst.append(d_lst)
else:
print("Invalid input")
continue
while True:
print("")
print("You rolled", dice_lst)
dice_choose = int(input("Choose a dice : "))
dice_lst.remove(dice_choose)
print("")
print("You are left with", dice_lst)
dice_choose1 = int(input("Choose a dice : "))
dice_lst.remove(dice_choose1)
print("")
sum1 = dice_choose + dice_choose1
if sum1 not in lst_player:
dice_lst.append(dice_choose)
dice_lst.append(dice_choose1)
print("You have made an invalid choice")
continue
print(dice_choose, "+", dice_choose1, "sums to", sum1)
print(sum1, "will be removed")
print("")
lst_player.remove(sum1)
break
stars()
print("Player set"," ",lst_player)
print("Computer set"," ",lst_cpu)
stars()
else:
print("You have won or lost. IDK yet.")
My question:
I am trying to make it so if there are no possible numbers to sum together that would eliminate a number from the original number set. It will say "sorry no possible solutions" and skip the turn.
Example:
dice_lst = [1, 2, 3]
lst_player = [6, 7, 8]
as neither 1 + 2 => 3 nor 1 + 3 => 4 nor 2 + 3 => 5 can be found in lst_player I'd like to print "sorry no possible solutions"
If I understood well this is what you you're looking for:
This is not the most elegant solution, but one that is rather easy to understand
and doesn't require knowledge of any other python modules.
you just try out all combinations of two dice, calculate the sum and if you can find a sum, you return True (and stop looking for other solutions)
otherwise (if you have tried all combinations and you found nothing)
you return False)
Now you can use this function in your code to check whether you want to ask the user which dice to choose or whether to immediately continue the loop
def can_remove_a_number(thrown_dice, remaining_numbers):
"""
checks whether the sum of two dice out of thrown_dice
can be found in remaining_numbers
"""
for idx1 in range(len(thrown_dice) - 1):
for idx2 in range(idx1 + 1, len(thrown_dice)):
# next line for debugging only
print("trying die %d and die %d" % (idx1, idx2))
sum_ = thrown_dice[idx1] + thrown_dice[idx2]
# next line for debugging only
print("sum = ", sum_)
if sum_ in remaining_numbers:
return True
return False
and for testing:
print("*" * 30)
print(can_remove_a_number([1,2,2], [5,6,7]))
print("*" * 30)
print(can_remove_a_number([1,2,2], [4,5,6,7]))
print("*" * 30)
# or if you want to write a test
# assert <expression> breaks if expression is not True
assert not can_remove_a_number([1,2,2], [5,6,7])
print("*" * 30)
assert can_remove_a_number([1,2,2], [4,5,6,7])
print("*" * 30)
In fact now a less manual solution.
Just use https://docs.python.org/3.8/library/itertools.html#itertools.combinations
from itertools import combinations
def can_remove_a_number(thrown_dice, remaining_numbers):
for dice in combinations(thrown_dice, 2):
sum_ = sum(dice)
if sum_ in remaining_numbers:
return True
return False
Or if you heard about list comprehensions / comprehensions ( https://python-3-patterns-idioms-test.readthedocs.io/en/latest/Comprehensions.html ) :
def can_remove_a_number(thrown_dice, remaining_numbers):
for sum_ in (sum(dice) for dice in combinations(thrown_dice, 2)):
if sum_ in remaining_numbers:
return True
return False
or with another comprehension
def can_remove_a_number(thrown_dice, remaining_numbers):
for found in (sum(dice) in remaining_numbers
for dice in combinations(thrown_dice, 2)):
if found:
return True
return False
or you combine with the any function ( https://docs.python.org/3.8/library/functions.html#any )
def can_remove_a_number(thrown_dice, remaining_numbers):
return any(sum(dice) in remaining_numbers
for dice in combinations(thrown_dice, 2))

Python occasional list index error when two integer dice held

When I choose to hold two dice it will not always follow the script. It occurs at approximately line 50. Sometimes it doesn't even print the list.
(As a side note- if anyone can simplify the code it would be much appreciated.)
Can anybody help offer a solution and reason for the problem.
(Script is below)
import random
points = 0
final = []
print("Welcome to Yahtzee")
print("Where there are closed questions answer lower case with 'y' or n'")
print("Please be aware that this a variation of the traditional game.\nShould you hold a number- you cannot 'unhold' it.\nIt has been added to your final roll for the round.")
print("Do not be tempted to hold onto a number you haven't rolled\n- this will not work and won't be added to your final score")
def roll_dice():
global collection
collection = []
input("Press Enter to roll the first die")
die_1 = random.randint(1,6)
collection.append(die_1)
print(die_1)
input("Press Enter to roll the second die")
die_2 = random.randint(1,6)
collection.append(die_2)
print(die_2)
input("Press Enter to roll the third die")
die_3 = random.randint(1,6)
collection.append(die_3)
print(die_3)
input("Press Enter to roll the fourth die")
die_4 = random.randint(1,6)
collection.append(die_4)
print(die_4)
input("Press Enter to roll the fifth die")
die_5 = random.randint(1,6)
collection.append(die_5)
print(die_5)
roll_dice()
print(collection)
yeno = input("Would you like to hold any dice? ")
if yeno == "n":
input("This will mean re-rolling all the dice: proceeding...")
del(collection)
roll_dice()
print(collection)
elif yeno == "y":
no = input("How many dice would you like to hold: " )
if no == "1":
num1 = input("Enter the number you would like to keep: ")
num1 = int(num1)
for x in range(len(collection)-1):
if collection[x] == num1:
final.append(num1)
del(collection[x])
print(collection)
print(final)
if no == "2":
num2 = input("Enter the first number you would like to keep: ")
num2 = int(num2)
num3 = input("Enter the second number you would like to keep: ")
num3 = int(num3)
for x in range(len(collection)-1):
if collection[x] == num2:
final.append(num2)
del(collection[x])
for x in range(len(collection)-1):
if collection[x] == num3:
final.append(num3)
del(collection[x])
print(collection)
print(final)
Seems you would do well to read up on what list and the random module has to offer.
Below a suggested simple solution to generate one round of Yatzy.
NOTE: the solution uses formatted string literals so Python 3.6 or greater is needed.
#! /usr/bin/env python3
import sys
import random
greeting = """Welcome to Yatzy
Where there are closed questions answer lower case with 'y' or n'
When asked which dice to hold answer with a list of dice separated by
space.
At most 3 rounds per turn. Between each turn decide what numbers to
keep before rolling again.
Please be aware that this a variation of the traditional game. Should
you hold a number- you cannot 'unhold' it. It has been added to your
final roll for the round.
Do not be tempted to hold onto a number you haven't rolled - this will
not work and won't be added to your final score.
"""
# Assume we have N dice. There are 3 rounds per turn and between
# rounds the player chooses r numbers to keep. The next round will
# then have N - r dice to roll. After each turn the kept dice
# collection is displayed.
#
# The turn stops when 3 rounds have been played or when there are no
# more dice to roll or when the player decides to stop.
def play_one_turn(dice=5, turns=3):
keep = []
msg = "Dice to hold: "
while turns and dice:
turns -= 1
print(f"Kept: {keep}")
play = random.choices(range(1, 7), k=dice)
print(f"Throw --> {play}")
for h in map(int, input(msg).split()):
if h in play:
keep.append(h)
dice -= 1
play.remove(h)
ask = "Another round? (yes/no) "
if not input(ask).strip().upper().startswith('Y'):
break
return keep
if __name__ == "__main__":
print(greeting)
score = play_one_turn()
print(f"Play result {score}")

Loop never seems to actually loop

print("Welcome to my dice game.")
print("First enter how many sides you would like your dice to have, 4, 6 or 12")
print("Then this program will randomly roll the dice and show a number")
#Introduction explaing what the game will do. Test 1 to see if it worked.
while True:
#starts a while loop so the user can roll the dice as many times as they find necessary
import random
#Imports the random function so the code will be able to randomly select a number
dice = int(input("Enter which dice you would to use,4, 6, or 12? "))
#set a variable for the amount of dice number
if dice == 12:
x = random.randint(1,12)
print("You picked a 12 sided dice. You rolled a " + str(x) + " well done")
#Test 2 see if it does pick a random number for a 12 sided di
elif dice == 6:
x = random.randint(1,6)
print("You picked a 6 sided dice. You rolled a " + str(x) + " well done")
#Test 3 see if it does pick a random number for a 6 sided di
elif dice == 4:
x = random.randint(1,4)
print("You picked a 4 sided dice. You rolled a " + str(x) + " well done")
#Test 4 see if it does pick a random number for a 4 sided di
else:
print("Sorry, pick either 12, 6 or 4")
#Test 5 tells the user that they can only pick 4, 6 or 12 if anything else is entered this error shows
rollAgain = input ("Roll Again? ")
if rollAgain == "no":
rollAgain = False
if rollAgain == "yes":
rollAgain = True
break
print ("Thank you for playing")
#if the user enters anything apart from yes y or Yes. The code ends here.
That is the code i have so far. However the code will never actually go to the beginning of the loop, no matter what i enter the code just displays "Thanks for playing" and ends. Can anyone please tell me where i have went wrong?
First, you should be using raw_input to get the user's selection. (assuming python 2) If you're using python 3 then input is fine and keep reading.
Anyway, it'll still quit when you type yes because you break out of the loop! You should move the break statement into the "no" case so it breaks out when you say you do not want to roll again.
rollAgain = raw_input ("Roll Again? ")
if rollAgain == "no":
break
You don't need to set rollAgain to true or false at all. With the above code, anything other than "no" is assumed to be "yes" but you can add checks for that easily.
The problem is that you break your loop when the user wants to roll the dice again. The loop should break when the player doesn't want to play again so you have to do :
http://pastebin.com/hzC1UwDM

Text menu doesn't print properly [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
The Problem has been solved. However, my account is new, so it won't let me answer the question. It seems that changing the instances of input() with raw_input() makes it work. I honestly have no clue why, but it may have something to do with the differences between 2 and 3.
I'm supposed to make a program that can calculate area and circumference. That part hasn't been so difficult.
However, the menu isn't working. The first part of the menu works just fine, but after you make a selection, it doesn't print what it's supposed to.
import math
print ("""
1) Calculate circumference
2) Calculate area
""")
ans = input("Enter 1, 2, or 0 to exit this program: ")
if ans == "1":
diameter = float(input("Enter the diameter: "))
if diameter > 0:
circumference = (diameter*math.pi)
print("The circumference is", circumference)
else:
print("Error: the diameter must be a positive number.")
if ans == "2":
radius = float(input("Enter the radius: "))
if radius > 0:
area = ((radius**2)*math.pi)
print("The area is", area)
else:
print("Error: the radius must be a postive number.")
if ans == "0":
print("Thanks for hanging out with me!")
quit()
After indenting properly, change if ans == "1" to str(ans) == "1" or ans == 1 and it should be fine.
This should work:
import math
print ("""
1) Calculate circumference
2) Calculate area
""")
ans = input("Enter 1, 2, or 0 to exit this program: ")
if str(ans) == "1":
diameter = input("Enter the diameter: ")
print diameter
if float(diameter) > 0.0:
circumference = (diameter*math.pi)
print("The circumference is", circumference)
else:
print("Error: the diameter must be a positive number.")
....
PS: As mentionned in the comments, it works, but it is disgusting. We should only use ans == 1 or modify input to input_raw if you use python < python 3
Your code's indentation shows the span of control of each 'if', 'for', or 'while'.
You need to further indent the instructions under each major 'if' statement so that
they only get executed when that 'if' statement is selected. Otherwise, everything
that is at the leftmost indentation gets executed every time through the loop. For example, you should have something like:
if answer == '1':
....<statements that execute under condition 1>
elif answer == '2':
....<statements that execute under condition 2>
where I have emphasized the indentation with '....'.
The second if statement is not within the brackets of the first. this is true for both 1 and 2.
if ans == "1";
diameter = float(input("enter the diameter: "))
if diameter ....
for me treating ans as integer worked. What I mean by treating ans as integer is instead of writing ans=="1" ,I wrote ans==1.it print corret cvalue. Check this code:
import math
print ("""
1) Calculate circumference
2) Calculate area
""")
ans = input("Enter 1, 2, or 0 to exit this program: ")
print ans
if ans ==1:
diameter = float(input("Enter the diameter: "))
if diameter > 0:
circumference = (diameter*math.pi)
print("The circumference is", circumference)
else:
print("Error: the diameter must be a positive number.")
if ans == 2:
radius = float(input("Enter the radius: "))
if radius > 0:
area = ((radius**2)*math.pi)
print("The area is", area)
else:
print("Error: the radius must be a postive number.")
if ans == 0:
print("Thanks for hanging out with me!")
quit()

Categories

Resources