How to make a poll in python with lists - python

I am trying to make a poll as an exercise that uses user input to find where people want to go on vacation. Here is my code so far:
done = False
places = []
while done == False:
dreamvacation = input("What is your dream vacation? ")
if dreamvacation == "quit":
for item in places:
number = places.count(item)
if number == 1:
print("{} occured in the list 1 time.".format(item))
else:
print("{} occured in the list {} times.".format(item, number))
while number > 0:
places.remove(item)
number -= 1
done = True
places.append(dreamvacation)
Basically it does the poll and each time someone enters something, it adds it to the list. Then when someone says quit, it counts the items and says something different depending on how many times the vacation spot occurred. If it occurs multiple times, I had the other duplicates removed after they were counted using a while loop. But, when it removes duplicates, the whole list shifted and the index spot moved forward thus skipping a spot. For example:
[a(index is here),b,c,a,]
After the counting, both a's would be removed and the index position would move forward:
[b,c(index is here)]
How can I make it so the index position stays in the same spot while the list shifts?
If I can do this, then I could have my program remove duplicates and singles after the letter is counted.

You do not need to delete entries of places. It only makes it hard to keep track. Please see the following example. I re-structured your code a little bit as well:
done = False
places = []
# user input stage
while not done:
dream_loc = input('where to go? ')
if dream_loc == 'quit':
done = True
else:
places.append(dream_loc)
# counting stage
for loc in set(places):
count = places.count(loc)
if count == 1:
print("{} occured in the list 1 time.".format(loc))
else:
print("{} occured in the list {} times.".format(loc, count))

Related

Removal of 3 or more consecutive letters in a string given by the user

Candy Crush horizontal. The program asks for a string and outputs the string remaining after removing groups of 3 or more consecutive identical characters. The removal of the groups continues until no more groups are found to be removed. The program should allow repetition until the user does not want to continue.
#Message
print("Hello! Welcome to Candy Crush!")
while True:
decision = str(input("Would you like to add a string? "))
if decision == "Yes" or decision == "yes":
num = str(input("Please enter a string: "))
list = list(num)
print("Your original list is", list)
print("Your original string: ", num)
while len(list) >= 3:
for i in range(len(list) - 2):
if list[i] == list[i + 1] == list[i + 2]:
list.pop(i + 2)
list.pop(i + 1)
list.pop(i)
print("Your trimmed list is", list)
result = "".join(list)
print("\nThe output of your string is: ", result)
if decision == "No" or decision == "no":
print("Thank you for playing! Have a great day!")
exit()
Traceback (most recent call last):
Python Candy Crush.py", line 12, in <module>
if list[i] == list[i + 1] == list[i + 2]:
IndexError: list index out of range
Hi Dark_Knight and welcome to Stack Overflow!
Here is the solution I had in mind. Although this solves the problem, I wanted to make this a learning experience for you and other programmers who stumble upon this. I blocked off, with comments, the start and end of my changes as well as step by step comments on the decisions I made for the solution.
#Message
print("Hello! Welcome to Candy Crush!")
while True:
decision = str(input("Would you like to add a string? "))
if decision == "Yes" or decision == "yes":
# Start of solution changes
# Lets make variables more clear
stringInput = str(input("Please enter a string: "))
charactersInput = list(stringInput)
print("Your original list is", charactersInput) # Still the same...
print("Your original string: ", stringInput) # Also still the same
# For our loop, idx will be used to track the index of the list
idx = 0
# Lets use a while loop instead of a for loop
# We will exit the loop when there aren't 3 consecutive characters
while idx < len(charactersInput) - 2:
# Check if the current character is the same as the next 2
if charactersInput[idx] == charactersInput[idx + 1] == charactersInput[idx + 2]:
# If so, remove the current and next 2 characters
# We are using pop() to remove the characters
# So the next character will be at the current index
charactersInput.pop(idx)
charactersInput.pop(idx)
charactersInput.pop(idx)
# Okay, we made a change to the list, so we need to reset idx
# As there might be a new set of 3 consecutive characters
idx = 0
else:
# If the current character is not the same as the next two,
# then increment idx by 1
idx += 1
result = "".join(charactersInput)
# End of solution changes
print("\nThe output of your string is: ", result)
if decision == "No" or decision == "no":
print("Thank you for playing! Have a great day!")
exit()
Here are some things to keep in mind that might make finding your own solution easier.
Make sure that all of your variables are clear and don't utilize keywords used in Python (or any other programming language). Using list for a list isn't descriptive and is the same terminology Python uses to work with lists
Break down the problems into smaller pieces. While I was working I first asked "What type of loop do I need?", then "At my current iteration in the loop, what do I need to check?", etc, etc,
Help out the community and include as many fixes you tried before creating a post. It not only helps people trying to help you out but also helps other users learn what solutions don't work

Happy Numbers doesn't update variable

I've been coding for about 3 months. Could someone help me understand why my code isn't working? I could look up the answer, but I'd really like to figure out what is going wrong. It runs perfectly the first time through the code, but while it is While-Looping, x always stays as the number inserted into the function. Thanks for your help! The assignment and code is below (for an Udemy class).
Happy Numbers -
A happy number is defined by the following process. Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers, while those that do not end in 1 are unhappy numbers. Display an example of your output here. Find first 8 happy numbers.
def find_happy_number(x):
#we need a bunch of lists
digit_list = []
squared_list = []
result_list = []
happy_numbers = []
unhappy_numbers = []
while True:
#break our number into digits
x = str(x)
for digit in x:
digit_list.append(int(digit))
#square each digit and store in list
for digit in digit_list:
squared_digit = digit**2
squared_list.append(squared_digit)
#adds all numbers on that list
result = sum(squared_list)
print(result)
#check to see if it is a happy number
if result == 1:
print(f'{x} is a happy number!')
break
#check to see if it is an un-happy number
if result in result_list:
print(f'{x} is an UN-happy number!')
break
#if it isn't we continue the churning.
#adds result to result list to see if we are looping infinitally
x = result
result_list.append(result)
`
The PROBLEM is that you are not resetting digit_list and squared_list in every loop, so they just keep getting bigger and bigger. Move their initialization into the while loop, or use a list comprehension instead of a loop.
Consider this for your loop:
while True:
digit_list = [int(digit) for digit in str(x)]
squared_list = [digit**2 for digit in digit_list]
Now you don't need to initialize them. Or, for extra fun, combine it all into one:
while True:
result = sum(int(digit)**2 for digit in str(x))

Python, Return from a function fails, stuck in While Loop

I am new to python and coding and for a school project I have to print a simple receipt. I am using a few functions and one of them, which asks for the prices of the purchased items, uses a While Not Loop. The input loops until the user enters '0'.
The problem is that if I input a purchased item price with three or more decimal places (e.g 19.999). When they enter 0 after this incorrect input, the Return command seems to get stuck in the While Not Loop. When the code gets to the Return command, execution jumps to the While Not Loop and back again, then half way through the While Not Loop to 'prices = str(prices)' and continues normally. The result is that we cannot exit the program the intended way, with a '0'.
Here is the function.
def shop_list(): #this definition asks for the prices of the items, adds the input to a list and loops, until 0 is entered, which stops the loop.
while True:
try:
prices = float(input("Please input a value. Enter 0 to print receipt: ")) # the input that allows the customer to enter their prices
zero_check.append(prices)
if prices == 0:
if len(zero_check) == 1:
if zero_check[0] == 0:
exit_ask()
else:
'do nothing' #this is a place holder line, something must be here but we dont need anything here
else:
'do nothing'
else:
'do nothing'
except ValueError: #if the input creates an error, do the below
print("\nERROR, please enter a valid number.\n") #this error message will come up if you input anything other than a number
continue #loops the back to the 'try'
else:
break #breaks the While True loop
if prices != 0:
number = None
while not number:
prices = str(prices) #converting the price to a string so we can split it
string_number = prices.split(".") #splitting the price at the decimal point
if len(string_number[1]) > 2: #if there is more than two decimal points, print an error
print ("\nERROR: Too many decimal places!\n")
prices = float(prices)
shop_list()
else:
number = float(prices)
prices = str(prices)
price_lnth = len(prices)
if price_lnth > 15:
print ('\nERROR, too many numbers.\n')
shop_list()
else:
prices = float(prices)
if prices > 0: #if the input was valid then this will run
shopplist.append(prices) #this is what adds a price into a list
shop_list() # loops back to the start of this definition
elif prices < 0:
print('\nERROR, no negative numbers.\n')
shop_list() # loops back to the start of this definition
else:
'do nothing'
return
When there is an error (and in the normal logic too), you call shop_list() recursively. When you then enter 0, this second invocation returns, but the original one carries on where it was. I suggest working with loops only, not recursion, or perhaps only recursion (but remember that recursion will eat stack space).

Multiple Same Numbers Entered in Guessing Game; Loop Stops Working?

I've been making a 4 number guessing game to learn python that meets three criteria:
replayable
tells player how many tries it took to guess correct answer
tells player how many numbers are correct to steer player to right answer
I thought I met the criteria but there is this really weird bug that happens in the game. If you try to guess the number using trial and error; the game breaks and doesn't detect that your answer is right. If the answer is '[1, 2, 3, 4]' and you try to get the answer by doing '[1, 1, 1, 1]' then '[1, 2, 2, 2,]' and eventually get '[1, 2, 3, 4]'; the program will say that the 4 numbers match but it won't let you win the game and just asks you to play again. This bug has been really killing me and I hope the person reading understands what I'm trying to say.
Sorry about the big long block of code but, the problem could be anywhere here but I honestly cannot see it; I will annotate as best as I can to make it look less confusing. I just... why is this happening!?
def compareLists(a, b): # to compare the guessed numbers and random numbers
return list(set(a) & set(b))
rNums = random.sample(range(10), 4) # random list of numbers
def start():
count = 0 # count for number of tries
global rNums
gNums = [] # guessed numbers
print(rNums) # cheating to save time
flag = True # to stop the guessing loop
while flag:
print("Get ready to guess 4 numbers!")
for i in range(0, 4): # asks the player 4 times to input a number
x = int(input("Guess: "))
gNums.append(x) # puts numbers in guessed numbers
comparison = len(compareLists(rNums, gNums)) # storing the length of the list of similar numbers
isCorrect = gNums == rNums # to check if lists are the same
print("You guessed: ", gNums) # telling player what they have guessed
if isCorrect: # if the lists are the same
if count > 1:
print("You win!! It only took you %d tries!" %count) # telling the player how many tries it took
else: #congratulating the player on a flawless guess
print("I CAN'T BELIEVE WHAT I'M SEEING!!!")
print("YOU GOT IT IN ONE GO!!")
count += 1 # increment count
rNums = random.sample(range(10), 4) # generate new numbers
gNums.clear()
pAgain = input("Play again?")
if pAgain.lower() in ('y', 'yes'): # replaying the game
continue
elif pAgain.lower() in ('n', 'no'):
flag = False
else:
print("Incorrect syntax!")
else:
print("You guessed " + str(comparison) + " numbers right, keep guessing!") # tells the player how many numbers are similar so the player can get a more educated guess
gNums.clear() # empties guessed numbers
count += 1 # increment count
print("Number of tries so far: %d" %count) # showing player number of tries so far
Your comparison for checking if the two lists are the same isn't working:
isCorrect = gNums == rNums # to check if lists are the same
The above code is checking if the two lists are identical, but the elements have to be in the same order.
For your test, you can just check if the number that match (ignoring order) is equal to the length of the list of numbers:
isCorrect = comparison == len(gNums) # to check if lists are the same
For more information on comparing lists regardless of order, see this answer.
Also, you should increment your count before you do your comparison with 1, or else your program will say you only took one go when you actually took two.

Loop and validation in number guessing game

I have previously studied Visual Basic for Applications and am slowly getting up to speed with python this week. As I am a new programmer, please bear with me. I understand most of the concepts so far that I've encountered but currently am at a brick wall.
I've written a few functions to help me code a number guessing game. The user enters a 4 digit number. If it matches the programs generated one (I've coded this already) a Y is appended to the output list. If not, an N.
EG. I enter 4567, number is 4568. Output printed from the list is YYYN.
import random
def A():
digit = random.randint(0, 9)
return digit
def B():
numList = list()
for counter in range(0,4):
numList.append(A())
return numList
def X():
output = []
number = input("Please enter the first 4 digit number: ")
number2= B()
for i in range(0, len(number)):
if number[i] == number2[i]:
results.append("Y")
else:
results.append("N")
print(output)
X()
I've coded all this however theres a few things it lacks:
A loop. I don't know how I can loop it so I can get it to ask again. I only want the person to be able to guess 5 times. I'm imagining some sort of for loop with a counter like "From counter 1-5, when I reach 5 I end" but uncertain how to program this.
I've coded a standalone validation code snippet but don't know how I could integrate this in the loop, so for instance if someone entered 444a it should say that this is not a valid entry and let them try again. I made an attempt at this below.
while myNumber.isnumeric() == True and len(myNumber) == 4:
for i in range(0, 4)):
if myNumber[i] == progsNumber[i]:
outputList.append("Y")
else:
outputList.append("N")
Made some good attempts at trying to work this out but struggling to patch it all together. Is anyone able to show me some direction into getting this all together to form a working program? I hope these core elements that I've coded might help you help me!
To answer both your questions:
Loops, luckily, are easy. To loop over some code five times you can set tries = 5, then do while tries > 0: and somewhere inside the loop do a tries -= 1.
If you want to get out of the loop ahead of time (when the user answered correctly), you can simply use the break keyword to "break" out of the loop. You could also, if you'd prefer, set tries = 0 so loop doesn't continue iterating.
You'd probably want to put your validation inside the loop in an if (with the same statements as the while loop you tried). Only check if the input is valid and otherwise continue to stop with the current iteration of your loop and continue on to the next one (restart the while).
So in code:
answer = [random.randint(0, 9) for i in range(4)]
tries = 5
while tries > 0:
number = input("Please enter the first 4 digit number: ")
if not number.isnumeric() or not len(number) == len(answer):
print('Invalid input!')
continue
out = ''
for i in range(len(answer)):
out += 'Y' if int(number[i]) == answer[i] else 'N'
if out == 'Y' * len(answer):
print('Good job!')
break
tries -= 1
print(out)
else:
print('Aww, you failed')
I also added an else after the while for when tries reaches zero to catch a failure (see the Python docs or maybe this SO answer)

Categories