Python guessing game hints and points systems [closed] - python

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 6 years ago.
Improve this question
I'm writing my first python game and trying to incorporate two extra elements but I'm unsure how to write it.
1: The idea is that the game will generate a random three digit number with the inbuilt random module (ie. 123) and the user will have 23 tries to guess the correct numbers. It will initiate by asking the user to input three digits between 0-9. I want to create a hint system so that the user knows if they are on the right track. See the example in the link below (I can't embed images apparently).
Click to see example Input/Output for hints
A "W" indicates that all of the characters in the guess are wrong.
One or more "X"s indicates that they have a correct character, but in an incorrect position
One or more "R"s indicates they have a correct character in the right position
To get this kind of hint will I need to create 3 separate numbers and combine them together to form the target number or will I still be able to do it with the following code:
target = random.randint(111, 999)
I've started writing a function that takes in the variables guess (this is what the user has entered) and target (the generated number):
def get_hint(guess, target):
This is as far as I have gotten with it. Laughable, I know. I literally have no idea if it even possible to create this hint system.
2: I would also like it to have a points system where the points start at 10000 (if the user guesses correctly first try) and decreases by 10% each incorrect guess (second guess = 9000, third guess = 8100, etc.) to two decimal places. I have it incrementing a count for the amount of guesses the user has tried so when they guess the correct number the following happens:
if guess == target:
print("Congratulations!")
print("{} was the correct answer!".format(target))
print("You guessed the correct answer in {} tries and scored {} points.".format(tries, points))

First the point system is fairly trivial: just have a score varible and modify it at each round score=score*0.9 and round it to 2 decimals when printing with "{:.2f}".format(score)
Regarding the hint system :
Having a list of three numbers will be far easier to deal with so I'll assume target and guess have one of the following format "123" or [1,2,3] (as strings can be indexed as lists)
The tricky part is doing the right comparisons because you have take care of what digit have already been matched against the target in order to give only "r" in the example case of guess=113 and target=333. Here is a function that does the job:
def hint(guess,target):
if guess == target:
print("win")
else:
#we store a list to keep track of the numbers
#already matched so we don't count them twice as x and r
r=[0]*len(target)
#first we check if there's a direct match
for i,n in enumerate(guess):
if guess[i] == target[i]:
r[i]=1
#we make new lists without the digits that matched
stripped_guess=[n for i,n in enumerate(guess) if r[i] == 0]
stripped_target=[n for i,n in enumerate(target) if r[i] == 0]
#we will now try to count the amount of x
x=0
for n in set(stripped_guess):
#we count how many time that given digit appears
# in the two lists, the smallest is our x amount
x+=min(stripped_guess.count(n),stripped_target.count(n))
if sum(r) == 0 and x == 0:
print("w")
else:
print("r"*sum(r)+"x"*x)
Some tests:
>>> hint(guess="404",target="404")
win
>>> hint("135","331")
rx
>>>hint("11123","12133")
rrrx

If you have a three-digit number in variable num, you can peel away the digits:
In [1]: num = 347
In [2]: num % 10
Out[2]: 7
In [3]: (num % 100) // 10
Out[3]: 4
In [4]: (num % 1000) // 100
Out[4]: 3
Then you can compare digits and place your Xs and Rs.

Related

I want to print all the perfect numbers between 1 to 20 [closed]

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 1 year ago.
Improve this question
n=1
Sum=0
while n<=20:
for i in range(1,n+1):
if(n%i==0):
Sum+=i
if(Sum==n):
print(Sum)
n+=1
I need to print all the perfect numbers between 1 to 20.
Perfect number is defined here
To achieve that, I would isolate the perfect number check in a function as follows:
def is_perfect(n):
s = 0
for i in range(1,n//2+1):
if(n%i==0):
s += i
return n == s
n=20
print([x for x in range(1, n+1) if is_perfect(x)])
One problem is that you never reset the sum but it should be reset for every new number you try. Otherwise Sum will grow over n.
Another issue is, that according to the definition of a perfect number, the number itself is excluded in the division test. But since you run up to n+1, the number itself will always be added and thus Sum is always greater than n.
Third issue is the indentation of the second if. It will print more often than you expect.
Fixing the code is left as an exercise for the reader. If you want a copy&paste solution, there are probably plenty enough on the Internet.
Besides these primary issues which prevent you from the correct results, the code could be improved in several aspects
Python coding style: remove the redundant parentheses
Clean code: naming of the variables
Reuse: define a method is_perfect(number)
Use type hints: def is_perfect_number(number:int)->bool:
Performance: division check needs to run until n/2 only.
Separate the perfection check (sum of divisors == number) from the searching (range for numbers up to 20).
def isPerfect(n):
return 2*n == sum(sum({d,n//d}) for d in range(1,int(n**0.5)+1) if n%d==0)
for n in range(1,21):
if isPerfect(n): print(n)
BTW, there is only one perfect number (6) from 1 to 20 so you may want to broaden that range.

Python input multiple lines and spaces

Im trying to solve one of the a2oj problems "given three numbers a , b and c. print the total sum of the three numbers added to itself."
I came with this
import sys
numbers = [int(x) for x in sys.stdin.read().split()]
print(numbers[0] + numbers[1] + numbers[2])
I saw many topics but I cant figure out how to read just 3 values from input. I know I can stop this procces by typing CTRL+D, but is there any possibility to make it automatic (after reaching third value)?
Thanks
// Thanks for very quick answers, I made mistake and posted only Problem Statement without Input Format: "three numbers separated by bunch of spaces and/or new lines"
So for example input should look like this:
2
1 4
// Ok thanks to you guys finally I made this:
n = []
while len(n) < 3:
s=input()
i = s.split()
[n.append(int(j)) for j in i]
print(2 * sum(n))
It's working but when I sent my results I got Runtime Error. I have no idea why:
Link: https://a2oj.com/p?ID=346
You could just use:
sys.argv
import sys
numbers = [int(x) for x in sys.argv[1:4]]
print(numbers)
print(sum(numbers))
When inputs are given line by line.
from sys import stdin
sum = 0
for num in stdin.readline(4):
sum = sum + int(num)
print(sum)
When inputs are given on CLI.
from sys import argv
sum = 0
for num in argv[1:4]:
sum = sum + int(num)
print(sum)
Use Python strip() and split() functions as per your usecases
I am not sure what you are looking for, but it seems that you are looking for is the input function, from python's builtins:
x=input()
This reads any input from the user, as a string. You have then to convert it to a number if needed.
You can read three values:
x=input("First value:")
y=input("Second value:")
z=input("Third value:")
As you have now specified more precisely the problem statement, I edit my answer:
In your case, this is not very complicated. I am not going to give you the answer straight away, as it would defeat the point, but the idea is to wrap the input inside a while loop. Something like:
numbers=[]
while (you have less than 3 numbers):
(input one line and add the numbers to your list)
(print the sum of your numbers)
That way you are waiting for as many inputs as you need until you reach 3 numbers. By the way, depending on your input, you might have to check whether you do not get more than 3 numbers.
After seeing the update from the question author and linked the online judge question description, the tweak to his code needed is below. It's worth noting that the expected output is in float and has precision set to 6 and the output is 2 * sum of all inputs, not just sum. There is no description on this in the online judge question and you've to understand from the input vs output.
n = []
while len(n) < 3:
s = input()
i = s.split()
n.extend(float(j) for j in i)
print(format(2 * sum(n), '.6f'))
Screenshot below
But the first version of this answer is still valid to the first version of this question. Keeping them if anyone else is looking for the following scenarios.
To separate inputs by enter aka New lines:
numbers_List = []
for i in range(3):
number = int(input())
numbers_List.append(number)
print("Sum of all numbers: ", sum(numbers_List))
Screenshot:
To separate inputs by space aka Bunch of spaces:
Use map before taking input. I'd suggest using input as well instead of sys.stdin.read() to get input from users, separated by space, and ended by pressing Enter key.
Very easy implementation below for any number of inputs and to add using sum function on a list:
numbers = list(map(int, input("Numbers: ").split()))
print("Sum of all numbers: ", sum(numbers))
The screenshot below and link to the program is here
Read Python's Built-in Functions documentation to know more about all the functions I used above.

Dice game (simulating many throws with 3 dices)

I am trying to code a dice game:
How do I write a function that is supposed to simulate 1000 throws of 3 dice and print the number of times a throw resulted in exactly 2 of the dice, but not all 3, landing on the same number. Meaning not (1,2,3) or (5,5,5), but like this (1,2,2).
def throw():
I know I need to use the random- library to generate numbers between 1 and 6.
What I need is example code on how I can approach this and what to do.
Use a for loop and list comprehension to generate the throw:
for i in range(1000):
throw = [random.randint(1, 6) for x in range(3)]
Then just write code to check your condition, something like:
valid = any([throw.count(i) == 2 for i in range(1, 6)])
Then if it's valid is True you can do with it what you need.
The function could be something like this:
import random
matches = 0
for i in range(1000): # 1000 throws
result = (random.randint(1,6), random.randint(1,6), random.randint(1,6)) # three dices randomly from 1 to 6 in a tuple (list)
for i in range(1,7): # count from 1 to 6
if result.count(i) == 2:
matches += 1
break # breaking out of this for-loop for performance improvement
print("Got "+str(matches)+" matches.")
Of course, this code could be heavily improved. But according to your question I assume that you are quite new to Python programming. This is why I tried to write a code that is self-explanatory.
Meta: please keep in mind that Stack Overflow is not the right place to ask for specific coding. It's intended to be a place where you provide code which contains error that you are unable to fix.

Project Euler #25 Python Why this wont work?

I'm trying to solve this problem:
The 12th term, F12, is the first term to contain three digits.
What is the first term in the Fibonacci sequence to contain 1000
digits?
check = True
mylst = [1,1]
i = 1
while check:
if len(str(mylst[i])) >= 1000:
check = False
else:
mylst.append(mylst[i-1] + mylst[i-2])
i=i+1
a =str((mylst[len(mylst)-1]))
print(len(a))
print(a)
I seem to get correct answer for test cases 2 and 3 but my answer is not being accepted. Please help me me I am not able to understand what went wrong.
I think you have an error in your code. If you look at the first iteration, you start with i=1 then call
mylst.append(mylst[i-1] + mylst[i-2])
Which will add mylst[0] + mylst[-1]. This also gives me incorrect answers (for finding the first index with 3 digits, F12. Your code gives me F18).
Obviously this is not what you want to do. You can fix it by changing the list indices you are adding together.
check = True
mylst = [1,1]
i = 1
while check:
if len(str(mylst[i])) >= 1000:
check = False
else:
mylst.append(mylst[i] + mylst[i-1])
i=i+1
Then, as others have mentioned, you want the index of the answer.
print len(mylst)
The answer is the index of the fibonacci number, not the number itself.
So, if Fn is the first term in the Fibonacci sequence to contain 1000 digits you need to enter the corresponding n.
Because the question is what term is the first to contain 1000 digits, not which number. So, if the question was
What is the first term in the Fibonacci sequence to contain 3 digits?
The answer would have been 12, not 144.
A general tip on Project Euler: Read the problem description carefully. And do it at least 3 times. If I had burned one calorie for each minute I've spent troubleshooting a PE problem due to a misread of the problem text, my body would probably be in a healthy shape.

writing an improved version of the Chaos Help

Here is the question proposed by the text.
Write an improved version of the Chaos program from Chapter 1 that allows a user to input two initial values and the number of iterations and then prints a nicely formatted table showing how the values change over time. for example, if the starting values were .25 and .26 with 10 iterations, the table would look like so:
following this is a table with a index 0.25 0.26 as headers and then the 10 iterations in two columns.
here is my initial Chaos program.
# File: chaos.py
def main ():
print ("This program illustrates a chaotic function")
x=eval (input("enter a number between 0 and 1: "))
for i in range (10):
x = 3.9 * x * (1-x)
print (x)
main()
my question is how do i change it to fulfil the above question..
Please if answering take in mind this is my first programming class ever.
You really just have to duplicate the functionality you already have. Instead of just asking the user for an x value, also ask for a y value.
x= float(input("enter a number between 0 and 1: "))
y= float(input("enter another number between 0 and 1: "))
Then in your loop you need to do the same thing you did with the x value to the y value. When you print, remember that you can print two values (x and y) at once by separating them with a comma.
Also, as PiotrLegnica said, you should use float(input(...)) instead of eval(input(...)). Since you know that the user should enter a floating point number (between 0 and 1) you don't have to call eval. Calling eval could be dangerous as it will execute any instruction given to it. That might not matter right now, but it's better to not get in the habit of using it.

Categories