I'm trying to make a script that takes in an answer and appends it to a new list, then checks to see if the new list is the same as the other list. When these lists are the same, the while loop should break.
NOTE: Each question should not repeat.
Here's my code:
import random
questions = ['a','b','c','d','e']
answered_q = []
while len(answered_q) < len(questions):
question = random.choice(questions)
answered_q.append(question)
raw_input = str(input(question + ": "))
if sorted(questions) == sorted(answered_q):
break
When executed I am still getting random questions but the code does not break when the lists have the same contents.
output :
['b','c','b,'d','d']
If anyone can help it would be great!
Thanks in advance!
I think what you really want to do is only append to your new list if the element to be added isn't already in there, so add a check for that.
while len(answered_q) < len(questions):
question = random.choice(questions)
if question not in answered_q:
answered_q.append(question)
raw_input = str(input(question + ": "))
if sorted(questions) == sorted(answered_q):
break
Of course, under this scheme, the loop should end even without the last if-statement because the length of the two lists will be equal by the time the two sorted lists will be equal.
For one, you're getting random questions (and thus orderings), but you are comparing to a set ordering [a,b,c,d].
To solve that with your current implementation, use a set - { "a", "b", "c", "d" }
Though personally, I would just pop things from one list to the other, looping while len(questions) > 0, which guarantees you won't get questions more than once.
Related
So i'm studying recursion and have to write some codes using no loops
For a part of my code I want to check if I can sum up a subset of a list to a specific number, and if so return the indexes of those numbers on the list.
For example, if the list is [5,40,20,20,20] and i send it with the number 60, i want my output to be [1,2] since 40+20=60.
In case I can't get to the number, the output should be an empty list.
I started with
def find_sum(num,lst,i,sub_lst_sum,index_lst):
if num == sub_lst_sum:
return index_lst
if i == len(sum): ## finished going over the list without getting to the sum
return []
if sub_lst_sum+lst[i] > num:
return find_sum(num,lst,i+1,sub_lst_sum,index_lst)
return ?..
index_lst = find_sum(60,[5,40,20,20,20],0,0,[])
num is the number i want to sum up to,
lst is the list of numbers
the last return should go over both the option that I count the current number in the list and not counting it.. (otherwise in the example it will take the five and there will be no solution).
I'm not sure how to do this..
Here's a hint. Perhaps the simplest way to go about it is to consider the following inductive reasoning to guide your recursion.
If
index_list = find_sum(num,lst,i+1)
Then
index_list = find_sum(num,lst,i)
That is, if a list of indices can be use to construct a sum num using elements from position i+1 onwards, then it is also a solution when using elements from position i onwards. That much should be clear. The second piece of inductive reasoning is,
If
index_list = find_sum(num-lst[i],lst,i+1)
Then
[i]+index_list = find_sum(num,lst,i)
That is, if a list of indices can be used to return a sum num-lst[i] using elements from position i+1 onwards, then you can use it to build a list of indices whose respective elements sum is num by appending i.
These two bits of inductive reasoning can be translated into two recursive calls to solve the problem. Also the first one I wrote should be used for the second recursive call and not the first (question: why?).
Also you might want to rethink using empty list for the base case where there is no solution. That can work, but your returning as a solution a list that is not a solution. In python I think None would be a the standard idiomatic choice (but you might want to double check that with someone more well-versed in python than me).
Fill in the blanks
def find_sum(num,lst,i):
if num == 0 :
return []
elif i == len(lst) :
return None
else :
ixs = find_sum(???,lst,i+1)
if ixs != None :
return ???
else :
return find_sum(???,lst,i+1)
x={}
continueQ=input("would you like to continue?"))
if (continueQ=="yes"):
#if there is less than 4
if x<4:
variable=float(input("Input a float to append to the array:")
x.append(variable)
print(x)
else:
print(x)
else:
print("Goodbye!")
There are a few errors in this code, could someone help me how to create an if statement to check if there are minimum than 4 values inside an array .
Also how to append to an array from an input.
Create a list with x = [], Use len(x) to get the length of list, use while loop with condition if x<4
x=[]
continueQ=input("would you like to continue?")
if (continueQ=="yes"):
#if there is less than 4
while len(x)<4:
variable=float(input("Input a float to append to the array:"))
x.append(variable)
print(x)
else:
print(x)
else:
print("Goodbye!")
The first thing you'll want to do is change that x={} to an x=[]. What you've done is create a dictionary rather than an array, and consequently will run into an assortment of issues as you're dealing with the wrong data structure.
Once you've done that, we can move on to how to check if there are less than 4 values inside an array. In Python, arrays carry a length attribute, which can be accessed by writing len(arrayName), or in your case, len(x). For example, if your array x contained the following values: [1,2,3], then len(x) would return 3, seems simple enough.
Now to check that the length is less than 4, you need to replace your if x<4: with if len(x)<4:.
You already have the correct code to append to your array, it likely wasn't working before because you created a dictionary instead of an array.
There are several errors in your code. Here's a working version:
x = []
continueQ = input('Would you like to continue?')
if continueQ.lower() == 'yes':
while len(x) < 4:
variable=float(input('Input a float to append to the array:'))
x.append(variable)
print(x)
print("Goodbye!")
Explanation
[] represents an empty list, while {} is use for an empty set.
Make sure your bracketing is consistent; all open brackets must be closed.
Use len(x) to find the number of entries in a list x.
Use a while loop to repeat logic until a criterion is satisfied.
I'm learing Python on codecademy and came across this solution for a function that's meant to remove duplicates from a list of numbers:
x = [1, 1, 2, 2]
def remove_duplicates(x):
p = []
for i in x:
if i != i:
p.append(i)
return i
I ran this in pycharm with some print statements and just got an empty list. I'm only curious because when I do this in my head, it makes no sense, but codecademy accepts this as an answer. Is it just a fluke? Or is this on a level I don't understand yet?
You are correct: it doesn't make any sense. First, it creates a list called p that gets each item that is not equal to itself. The only object that I know of that is not equal to itself is NaN, but you don't have any of those, so p is just an empty list. Defining p is useless, however, because it isn't even returned. What is returned is i, which is assigned to each item in the last, so it is the last item in the list by the end of the function. In short, that function is equivalent to this:
def remove_duplicates(x):
return x[-1]
I haven't heard what the function is supposed to return, but perhaps it is supposed to return the number of non-duplicate items. If it is, it "works" just because the last item in the list happens to be the number of non-duplicate items.
Take a look to this snippet to see the pythonic way to remove duplicated (good_result) and also to understand why your code doesn't make any sense:
x = [1, 1, 2, 2]
def remove_duplicates(x):
p = []
for i in x:
if i != i:
p.append(i)
return i
good_result = list(set(x))
print good_result
print remove_duplicates(x)
As you can see, your function is not returning the filtered list without duplicate values, it's just returning the last element of the list (index=-1). So codeacademy shouldn't accept that snippet as a valid answer to the question how to remove duplicateds from a list for sure.
Now, if we assume what codeacademy was really asking is for the number of unique values from a list, then is a casuality your broken code gives the right answer, which is the same as len(good_result). It worked just by luck just to say, it doesn't mean your code is correct :)
your code just returns the last element of the number, that is same as
return x[-1]
It doesn't return a list.
I think you need to check the question that they may be asking like,
a)function to return one of the duplicating element in a list.
b)function to return the no of duplicating elements in a list.
for the above two questions your answer is 2, by luck the answer is correct.
I'm pretty much a complete beginner to python, and i'm having problems removing an integer from a list. I'm getting a error, AttributeError: 'int' object has no attribute 'remove', and i don't know how to fix it. This is probably really easy to experienced eyes, and I have looked at past answers but keep returning same error
repeat = 0
while repeat <= 4:
question_list = [1,2,3,4,5]
number = random.choice(question_list)
if number == 1:
print(question1())
repeat = repeat + 1
number.remove(1)
elif number == 2:
print(question2())
repeat = repeat + 1
number.remove(2)
elif number == 3:
print(question3())
repeat = repeat + 1
number.remove(3)
elif number == 4:
print(question4())
repeat = repeat + 1
number.remove(4)
elif number == 5:
print(question5())
repeat = repeat + 1
number.remove(5)
number = random.choice(question_list) assigns number to an int returned from calling random.choice on your question list. If you want to remove from question_list call remove on the list not number:
question_list.remove(x)
You need to assign question_list outside the while loop, if you put it inside you keep creating a new list so the remove never persists.
question_list = [1,2,3,4,5] # here
while repeat <= 4:
A nicer implementation may be to use a dict and just use range:
import random
# map numbers to functions
questions = {1:question1,2:question2,3:question3,4:question4,5: question5}
question_list = [1, 2, 3, 4, 5] # outside loop
for _ in range(4): # loop in range 4
number = random.choice(question_list)
question_list[func]() # call function using dict key val
question_list.remove(number)
Or simply store the functions in a list and randomly choose one:
question_list = [question1,question2,question3,question4,question5]
for _ in range(4):
func = random.choice(question_list)
func()
question_list.remove(func)
Since a comment already explained why your code doesn't work, I'd like to suggest a simpler alternative.
It seems like you have a few functions you want to call in a random order.
There is no need to complicate things the way you're doing it, and mess around with removing elements from the list.
You can simply have a list of functions, shuffle it, and call every function in order:
questions = [question1, question2, question3, question4, question5]
random.shuffle(questions)
for question in questions:
question()
You should use the remove function on the list, and give the int as a parameter. So it should become:
question_list.remove(something)
But be careful, because if there is no "something" you will get an error.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have a list and I want to return the first number that out of order,
this is what I've written. and it's not working..
a=input("enter list")
out_of_order(a)
def out_of_order(list):
foundit=0
for i in list:
while foundit==0:
if (i+1 < i):
print(i)
foundit=1
if (foundit==0)
print("none")
for the list [4,8,9,10,2,12,16] It should return 2
You are confusing list items and indices. As it stands, you are testing for:
if i+1 < i:
which will never, ever be True - whatever value i takes, i+1 will be one louder larger.
I think what you were trying to do is compare adjacent items by index:
for i in range(len(lst)):
if lst[i+1] < lst[i]:
(note that you shouldn't use list as your own variable name), but:
this will give you problems if you reach the end of the list (where lst[i+1] will cause an IndexError, so you have to either try or alter the range appropriately); and
it is not generally considered Pythonic to use len(range(...)).
Instead, the best way is to compare pairs of elements:
def out_of_order(lst):
for a, b in zip(lst, lst[1:]):
if b < a:
print(b)
break
else:
print("none")
You also make a few other mistakes:
As #timgeb points out, your input will be strings not integers;
You have a SyntaxError (missing colon, incorrect indentation) at the end; and
You are using an integer as a flag, when Python has perfectly serviceable booleans True and False.
First of all, you are getting a string from input, not a list. You could get a list of numbers from the input like this:
inputstr = input('enter comma separated integers! ')
inputlist = inputstr.split(',')
inputnums = [int(x) for x in inputlist]
Another thing is that you should not use list as a variable name, because that's already used for the builtin list. Now, assuming that your a is a proper list, you want to compare one element of the list with the next element:
def out_of_order(lst):
for i in range(len(lst) - 1):
if lst[i+1] < lst[i]:
print(i+1,lst[i+1])
break
Demo:
enter comma separated integers! 100,101,102,100,101,102
3 100 # output of out_of_order(inputnums)
for i in list:
This iterates through the list by letting i be each element. Naturally, i+1 is never less than i.
I haven't used python in a while, but I believe that when you use 'i' it is referring to a number from the list. For your example in the first iteration i would be 4, in the second i would be 8, and so on. Calling i+1 doesn't return the next number in the sequence, it just adds one to it. When you're saying
if (i+1 < i)
in the first iteration you're pretty much saying if ((4+1) < 4), which is never true.
a=input("enter list")
out_of_order(a)
def out_of_order(list):
foundit=0
for i in range(len(list)):
while foundit==0:
if i < len(list)-1:
if (list[i+1] < list[i]):
print(list[i+1])
foundit=1
else
break;
if (foundit==0):
print("none")