Python - creating random number string without duplicates [duplicate] - python

This question already has answers here:
How do I create a list of random numbers without duplicates?
(21 answers)
Closed 5 years ago.
I need help with creating a random string of 4 numbers without having duplicates.
Code:
from random import randint
correct = [randint(1,8), randint(1,8), randint(1,8), randint(1,8)]
usr_guess = [0, 0, 0, 0]
usr_guess_output = []
usr_guess_output_n = []
print(correct)
Also, if you could help me get the user input without needing commas that would be great!
Full code:
from random import randint
correct = [randint(1,8), randint(1,8), randint(1,8), randint(1,8)]
usr_guess = [0, 0, 0, 0]
usr_guess_output = []
usr_guess_output_n = []
print(correct)
guesses = 0
print('Welcome to Mastermind. Guess the combination of numbers between 1 and 8. If you get the correct number and place, a \'*\' will be printed. If you get the correct number but wrong place, a \'-\' will be printed. If you get it wrong completely, a \'#\' will be printed. The position of the output does not correlate to the positions in the actual list of numbers.')
while(True):
usr_guess_output_n = []
usr_guess_output = []
correct_count = 0
guesses += 1
# try: #Makes sure that the program still works even if the user messes up the input
usr_guess = input('Guess at the numbers (separate with commas) > ').split(',') #Splits the user input into a list of integers
usr_guess = [int(x) for x in usr_guess ] #Converts all list items into integers for comparisons
print('')
i = 0
for i in range(0,4): #Iterates the lists to check for comparisons
if correct[i] == usr_guess[i]:
usr_guess_output.append('*')
correct_count += 1
elif correct[i] in usr_guess:
usr_guess_output.append('-')
else:
usr_guess_output.append('#')
if(correct_count > 3):
break
for i in usr_guess_output:
if i == '*':
usr_guess_output_n.append('*')
for i in usr_guess_output:
if i == '-':
usr_guess_output_n.append('-')
for i in usr_guess_output:
if i == '#':
usr_guess_output_n.append('#')
print(str(usr_guess_output_n).replace(',','').replace('[','').replace(']','').replace('\'',''))
# except:
# print('something went wrong. you probably input something other than an integer')
# guesses -= 1
print('\nIt took you ' + str(guesses) + ' guesses!')
input('Press enter to exit')

How about utilising a while loop?
correct = []
#list long enough?
while len(correct) < 4:
#create random number
rand_num = randint(1, 8)
#not in the list?
if rand_num not in correct:
#include in list
correct.append(rand_num)

Related

Why is my input variable adding to itself? Python

I have made this simple password generator with the option to choose the length of the password. It seems to randomly add the length to itself however, so if I keep choosing a length of 5 it will occasionally output a password of 10 characters and then go back to 5.
import random
randomnums = []
checker = [0, 0, 0, 0] ##Make sure there are upper, lower case, symbols and numbers.
while True:
length = input("How long do you want your password?: ")
if length.isdigit() == False:
print("please enter a number..\n")
elif int(int(length)) < 4:
print("Please enter a length of 4 or greater...\n")
else:
break
while checker[0] == 0 or checker[1] == 0 or checker[2] == 0 or checker[3] == 0:
for i in range(0,int(length)):
x = random.randrange(0, 4)
if x == 1:
randomnums.append(random.randrange(0, 10))
checker[0] = 1
elif x == 2:
randomnums.append(random.choice('abcdefghijklmnopqrstuvwxyz'))
checker[1] = 1
elif x == 3:
randomnums.append(random.choice('ABCDEFGHIJKLMNPQRSTUVWXYZ'))
checker[2] = 1
else:
randomnums.append(random.choice('!##$%^&*()_+:"}|<>?'))
checker[3] = 1
password = ''.join(map(str, randomnums)) ##join list to string
print(password)`
You could get any multiple of length with this code. It adds length characters in the body until you got the required length. You should instead generate a password and check it, and if it is bad, repeat.

Program to add the squares of numbers in list which have been entered by while-loop

I'm writing a program which should produce an output of something like this:
`Enter an integer (or Q to quit): 1
Enter an integer (or Q to quit): 2
Enter an integer (or Q to quit): 3
Enter an integer (or Q to quit): Q
(1 x 1) + (2 x 2) + (3 x 3) = 14`
So far, I've gotten the display of the equation right, but I can't seem to figure out how to actually get the total of the equation. Currently, the total displays 18 instead of the expected 14.
Here's my code so far:
`int_list = [] # initiate list
while True:
user_input = input("Enter an integer (or Q to quit): ") # get user input
if user_input == "Q": # break loop if user enters Q
break
integer = int(user_input) # convert user_input to an integer to add to list
int_list.append(integer) # add the integers entered to the list
for i in range(0, len(int_list)):
template = ("({0} x {1})".format(int_list[i], int_list[i]))
if i == len(int_list)-1:
trailing = " = "
else:
trailing = " + "
print(template, end="")
print(trailing, end="")
for i in range(0, len(int_list)):
x = (int_list[i]*int_list[i])
add = (x+x)
print(add)`
Any help would be greatly appreciated :))
Your problem exists in the here:
for i in range(0, len(int_list)):
x = (int_list[i]*int_list[i])
add = (x+x)
print(add)
Let us walk through what the code does to get a better understanding of what is going wrong.
With a list of [1, 2, 3] The for loop will iterate three times
On the first iteration, x will be assigned the value 1 because 1 * 1 is 1.
On the second iteration, x will be assigned the value 4 because 2 * 2 is 4. Notice that rather than the two values being added x's value being overwritten
On the third iteration, x will be assigned the value 9 because 3 * 3 is 9. Again the value is being overwritten.
After the loop, the variable add is created with the value x + x, or in our case 9 + 9 which is 18
This is why with the list [1, 2, 3] the value displayed is 18
Now that we have walked through the problem. We can see that the problem is overriding the value in the for loop then doubling the value before displaying it.
To fix these problems we can first remove the doubling giving the following code
for i in range(0, len(int_list)):
x = (int_list[i]*int_list[i])
print(x)
But the program still has the overriding problem so the value of a list [1, 2, 3] would be 9.
To fix this rather than overriding the value of x, let's create a new variable total that will have the result of the loop added to it every iteration rather than being overwritten.
total = 0
for i in range(0, len(int_list)):
total = total + (int_list[i]*int_list[i])
print(total)
Now let's walk through what the code does now.
With a list of [1, 2, 3] the for loop will iterate three times
On the first iteration, total will be assigned the value 1 because 0 + 1 * 1 is 1.
On the second iteration, total will be assigned the value 5 because 1 + 2 * 2 is 5. Notice how the previous value of the loop iteration is being added to the loop
On the third iteration, total will be assigned the value 14 because 5 + 3 * 3 is 14. Notice again how the previous value of the loop iteration is being added to the loop.
This gives us the correct result of 14.
One nice feature of python is the addition assignment which condentes A = A + B to A += B so it is possible to simply the following code to:
total = 0
for i in range(0, len(int_list)):
total += (int_list[i]*int_list[i])
print(total)
A reason this problem may have been so difficult is that the for loop is more complicated than it needs to be. It is possible that rather than iterating through a list of indices generated by a list of numbers then assessing the numbers from the list by their index. It is possible to iterate through the numbers directly.
With the that simplification your loop would look like this:
total = 0
for number in int_list:
total += number * number
print(total)
These changes would make your whole programme look like this:
int_list = [] # initiate list
while True:
user_input = input("Enter an integer (or Q to quit): ") # get user input
if user_input == "Q": # break loop if user enters Q
break
integer = int(user_input) # convert user_input to an integer to add to list
int_list.append(integer) # add the integers entered to the list
for i in range(0, len(int_list)):
template = ("({0} x {1})".format(int_list[i], int_list[i]))
if i == len(int_list)-1:
trailing = " = "
else:
trailing = " + "
print(template, end="")
print(trailing, end="")
total = 0 # start the total at zero as no values have been calculated yet
for number in int_list: # iterate through all values in the list
total += number * number # add to the total the number squared
print(total)
You duplicate only the last product (2 x 3 x 3 = 18).
Because you reassign x in your loop (x = (int_list[i]*int_list[i])) and than duplicate x with add = (x+x).
But you have to build the sum.
int_list = [] # initiate list
while True:
user_input = input("Enter an integer (or Q to quit): ") # get user input
if user_input == "Q": # break loop if user enters Q
break
integer = int(user_input) # convert user_input to an integer to add to list
int_list.append(integer) # add the integers entered to the list
for i in range(0, len(int_list)):
template = ("({0} x {1})".format(int_list[i], int_list[i]))
if i == len(int_list) - 1:
trailing = " = "
else:
trailing = " + "
print(template, end="")
print(trailing, end="")
x = 0
for i in range(0, len(int_list)):
x += (int_list[i] * int_list[i])
print(x)
You can try this
state= True
combi= []
while state:
user_input = input("Enter an integer (or Q to quit): ").lower()
if "q" in user_input:
state= False
else:
combi.append(int(user_input))
else:
final= sum([x+x for x in combi])
print(final)

Most efficient way to compare lists Python

How can I compare lists to one another. I am looking to compare the first - fourth digit of two lists.
I'm aware of being able to do
if list[1] == list[1]: but id assume there is a more efficient way to get it done. Thank you. I don't want to compare the lists overall, just x part of one list to x part of another
import random
import replit
import numpy
import time
number = 0
answer = 0
guesses = 0
x = 0
useranswer = []
generated = []
for i in range (0,4):
num = random.randrange(1,9)
generated.append(num)
replit.clear()
print("---------------------------------------------------------------------\nWelcome to MASTERMIND! you must guess the number that was generated!\n---------------------------------------------------------------------\n")
def useranswer():
answer = str(input("Select a 4 digit number: "))
if len(answer) != 4:
print("Invalid answer type")
time.sleep(999999999)
answer = ' '
else:
useranswer = list((str(answer)))
if useranswer == generated:
print("Good job! You became the MASTERMIND in one turn!")
else:
while useranswer != generated:
useranswer()
guesses +=1
if useranswer == generated:
print("You have become the mastermind in " + guesses + " tries!")
else:
c = numpy.intersect1d(useranswer, generated, return_indices=True)[1]
print("You got " + c + " correct! ")```
You can always use list slicing to compare the specified range of items between lists.
a = [1, 2, 3, 4, 7, 8]
b = [1, 2, 3, 4, 5, 6]
a[:3] == b[:3]
The above will yield a True if they match.
If you want to return the indexes of common elements between the two lists, there's a library called Numpy which has powerful features to do such jobs efficiently.
import numpy
a = [1, 2, 3, 4]
b = [0, 4, 6, 2]
_, c, d = numpy.intersect1d(a, b, return_indices=True)
This would return the following indexes:
print(c)
print(d)
array([0, 1, 3]
array([0, 3, 1])
But the answer to your question:
import random
import replit
import copy
import numpy
import time
number = 0
answer = 0
guesses = 0
x = 0
useranswer = []
generated = []
for i in range (0,4):
num = random.randrange(1,9)
generated.append(num)
replit.clear()
print("---------------------------------------------------------------------\nWelcome to MASTERMIND! you must guess the number that was generated!\n---------------------------------------------------------------------\n")
def useranswer_func():
answer = str(input("Select a 4 digit number: "))
if len(answer) != 4:
print("Invalid answer type")
time.sleep(9) # The time provided by you is too much to wait!
answer = ' '
else:
useranswer = list(answer)
# You need to return values to use them outside the function.
# Also your generated has int values but useranswer have str. So convert them to int or else they would never compare!
return [int(i) for i in useranswer]
if useranswer == generated:
print("Good job! You became the MASTERMIND in one turn!")
else:
while useranswer != generated:
# The returned values need to be stored in a variable.
# Never use function name and variable name same. That could cause the error that you posted in the comment!
useranswer = useranswer_func()
guesses += 1
if useranswer == generated:
print("You have become the mastermind in " + str(guesses) + " tries!")
else:
c = []
temp = copy.deepcopy(generated) # So that the change you make in temp is not reflected in generated variable too.
for i in range(len(generated)):
if generated[i] == useranswer[i]:
c.append(temp.index(temp[i]))
temp[i] = None # If your generated has repeated values, the index returned will be different or else it would be always same.
print("You got " + str(c) + " correct! ")

Python: Finding Average of Numbers

My task is to:
"Write a program that will keep asking the user for some numbers.
If the user hits enter/return without typing anything, the program stops and prints the average of all the numbers that were given. The average should be given to 2 decimal places.
If at any point a 0 is entered, that should not be included in the calculation of the average"
I've been trying for a while, but I can't figure out how to make the programs act on anything I instruct when the user hits 'enter' or for it to ignore the 0.
This is my current code:
count = 0
sum = 0
number = 1
while number >= 0:
number = int(input())
if number == '\n':
print ('hey')
break
if number > 0:
sum = sum + number
count= count + 1
elif number == 0:
count= count + 1
number += 1
avg = str((sum/count))
print('Average is {:.2f}'.format(avg))
You're very close! Almost all of it is perfect!
Here is some more pythonic code, that works.
I've put comments explaining changes:
count = 0
sum = 0
# no longer need to say number = 1
while True: # no need to check for input number >= 0 here
number = input()
if number = '': # user just hit enter key, input left blank
print('hey')
break
if number != 0:
sum += int(number) # same as sum = sum + number
count += 1 # same as count = count + 1
# if number is 0, we don't do anything!
print(f'Average is {count/sum:.2f}') # same as '... {:.2f} ...'.format(count/sum)
Why your code didn't work:
When a user just presses enter instead of typing a number, the input() function doesn't return '\n', rather it returns ''.
I really hope this helps you learn!
Try this:
amount = 0 # Number of non-zero numbers input
nums = 0 # Sum of numbers input
while True:
number = input()
if not number: # Breaks out if nothing is entered
break
if int(number) != 0: # Only add to the variables if the number input is not 0
nums+=int(number)
amount += 1
print(round(nums/amount,2)) # Print out the average rounded to 2 digits
Input:
1
2
3
4
Output:
2.5
Or you can use numpy:
import numpy as np
n = []
while True:
number = input()
if not number: # Breaks out if nothing is entered
break
if int(number) != 0: # Only add to the variables if the number input is not 0
n.append(int(number))
print(round(np.average(n),2)) # Print out the average rounded to 2 digits
A list can store information of the values, number of values and the order of the values.
Try this:
numbers = []
while True:
num = input('Enter number:')
if num == '':
print('Average is', round(sum(numbers)/len(numbers), 2)) # print
numbers = [] # reset
if num != '0' and num != '': numbers.append(int(num)) # add to list
Benefit of this code, it does not break out and runs continuously.

asking for numbers in python and returning a list

Hey guys I'm stuck on one part of an exercise. What I am supposed to do is ask for a number (the exercise says I need to enter the numbers (4, -3, -15, 0, 10, 22, -9999) with -9999 being the breaking number. It is supposed to make 3 lists. list a is all numbers entered, list p is all positive numbers and list n is all negative numbers. This is the code I have so far:
a = []
p = []
n = []
total = -9999
while(True):
user_input = int(input('Please enter a number:'))
if(user_input == -9999):
break
elif(user_input >= 0):
p.append(user_input)
elif(user_input <= 0):
n.append(user_input)
a = p + n
print('The list of all numbers entered is:', '\n', a)
when I run this program and use these numbers I get [4, 0, 10, 22, -3, -15] which is correct but when I looked at the answer for this exercise it has the numbers in a different order [4, -3, -15, 0, 10, 22]. I'm stuck on how to get the numbers in this order.
One more quick question. On part b of this exercise I am supposed to find the avg of all numbers, positive numbers and negative numbers. When I print a, p, n it does not add 0 to the negative list even though I have the user_input <= 0 which will throw off the average. What am I missing?
Thank you guys.
For the first part use this
while(True):
user_input = int(input('Please enter a number:'))
if(user_input == -9999):
break
elif(user_input >= 0):
p.append(user_input)
elif(user_input <= 0):
n.append(user_input)
#always append to a, makes the order the same as input order.
a.append(user_input)
(The identation problem is bad copy paste I assume)
For the second part you can make the elif like this to make it work for 0
elif(user_input >= 0):
p.append(user_input)
if(user_input <= 0 and user_input != -9999):
n.append(user_input)
The reason it failed is because once it is stored in p, it skips the remaining elif else blocks.
Your indentation is bad coded. As result, the two elif setences are not running inside your while loop. Try the following code.
a = []
p = []
n = []
total = -9999
while(True):
user_input = int(input('Please enter a number:'))
if(user_input == -9999):
break
elif(user_input >= 0):
p.append(user_input)
elif(user_input <= 0):
n.append(user_input)
a = p + n
print('The list of all numbers entered is:', '\n', a)

Categories