From while loop to ValueError - python

I want integer input for the variable x, space separated. User input example 20 15 7 5 4 2. This list should be entered into x and then split into two parts. The parts should be then substracted with each other and output the smallest possible difference. The below code splits the input already partially into to lists but it does not complete it. I thought I would either create a while loop encapsulating all if-statements which however gives me the following error.
Error message
Traceback (most recent call last):
File "C:/Users/Array Partitioning.py", line 28, in <module>
arrpartitioning(input().split())
File "C:/Users/Array Partitioning.py", line 18, in arrpartitioning
b.append(max(x))
ValueError: max() arg is an empty sequence
I assume the while statement does not stop and attempts after a while to loop over an empty list of variable x. Initially, I thought to check the length of the x variable prior starting the while loop again but that does not work. The if-statement in the second while-loop also does not help even if I indent it to include it in the while loop.
# User input, space separated
ui = input()
x = list(map(int, ui)
half = sum(x)//2
# two empty lists to enter the x-values
a = []
b = []
flag = False
# while len(x) != 0:
# while loop to divide the values
while flag == False:
if sum(a) < half:
a.append(max(x))
x.remove(max(x))
while sum(b) < sum(a):
b.append(max(x))
x.remove(max(x))
# Same error message even if I indent the if-statement to the while-block
if len(x) == 0:
flag == True
Can somebody please explain me first, whether the issue is here my while loop and if so, second, how I can exit the while loop once there are no values in x anymore?

you need to add a condition so it exits the loop when x is no longer valid:
# User input, space separated
ui = input()
x = list(map(int, ui.split(' ')))
half = sum(x)//2
# two empty lists to enter the x-values
a = []
b = []
# while len(x) != 0:
# while loop to divide the values
while len(x) > 1:
if sum(a) < half:
a.append(max(x))
x.remove(max(x))
while sum(b) < sum(a):
b.append(max(x))
x.remove(max(x))
# check last element independently
if sum(b) < sum(a) < half:
b.append(x.pop())
else:
a.append(x.pop())
print(x)
print(a)
print(b)

You need to split the user input into separate strings before mapping int onto it. Otherwise, it tries to convert the whole string of 20 15 7 5 4 2 into one integer value. To fix this, try adding a split() to the map input to convert it to a list of strings:
x = list(map(int, ui.split())
EDIT: I was mainly pointing out the problem that caused the error, but the bigger problem is probably the infinite loop as mentioned above.

Related

Running multiline test cases

I have the following prompt:
We want you to calculate the sum of squares of given integers, excluding any negatives.
The first line of the input will be an integer N (1 <= N <= 100), indicating the number of test cases to follow.
Each of the test cases will consist of a line with an integer X (0 < X <= 100), followed by another line consisting of X number of space-separated integers Yn (-100 <= Yn <= 100).
For each test case, calculate the sum of squares of the integers, excluding any negatives, and print the calculated sum in the output.
Note: There should be no output until all the input has been received.
Note 2: Do not put blank lines between test cases solutions.
Note 3: Take input from standard input, and output to standard output.
Specific Rules for Python Solution:
Your source code must be a single file, containing at least a main function
Do not use any for loop, while loop, or any list / set / dictionary comprehension
I have written my square_sum function as:
def square_sum(arr):
if not arr:
return 0
value = arr[0]
if value < 0:
value = 0
return value**2 + square_sum(arr[1:])
square_sum([9, 6, -53, 32, 16])
However, I cannot figure out how to run the multiline test cases on my function and display the result in the aforementioned format. Interestingly, there can be any number of test cases so how do I add the capability to accommodate them? I would like some guidance in this part, thank you.
Assuming that this assignment is to see how to replace all iteration with recursion, and withholding all judgement on the wisdom of doing so, here is a sample solution.
You have already implemented the inner loop. My suggestion would be to add the parsing to that loop, since otherwise you have to either use map or replace it with another recursion.
def square_sum(lst):
if not lst:
return 0
value = int(lst[0])
if value < 0:
value = 0
return value**2 + square_sum(lst[1:])
The outer loop will need to read two lines: the first (discarded) line will contain the number of elements. The second line will contain the strings that you will pass to square_sum. To control the depth of your recursion, use the first line of the input, which tells you how many samples there will be:
def run(n):
count = int(input())
print(square_sum(input().split()))
if n > 1:
run(n - 1)
def main()
n = int(input())
run(n)
Your question asks for a main function. If you need to run it in your module, go ahead and do that:
main()

How to make python function start back over if conditions aren't met?

I am trying to create a function that spreads a rumor form one pixel in to other neighboring pixels as long as they == 1 (not a 0). I think the function I have now can spread it to the neighboring pixel one time, but I want it to loop again and again using the updated versions of the pixel map each time. How can I get it to loop back to the top when certain conditions aren't met?
def spread_rumor(array):
new_array = np.zeros_like(array) #make a copy of your city
for i in range(array.shape[0]): #for each index i for the number of rows:
for j in range(array.shape[1]): #for each index j for the number of columns
if array[i,j] == 0:
new_array[i,j] = 0
elif array[i,j] == 2:
new_array[i,j] = 2
elif array[i,j] == 1: #if the value of the city/board at [i,j] is a 1:
new_array[i,j] = 1 #we only do something if we find a person who can learn the rumor
neighbors = getNeighborValues(i,j, array) #get all of the values of their neighborhood cells
if np.any(np.array(neighbors) == 2) == True:
new_array[i,j] = 2
## there is more than one way to do this!
## You could use a loop to check all the neighbors and move one once you find one
## or you could check to see if there is a 2 in any of the neighbors
frac_empty = np.count_nonzero(array == 0)/array.size
frac_house = np.count_nonzero(array == 1)/array.size
frac_rumor = np.count_nonzero(array == 2)/array.size
if frac_empty + frac_rumor == 1.0: #the copy of our city is the same as city:
##our simulation isn't changing anymore,
##so making a copy and updating it isn't going to
##lead to further changes
spread_rumor = False
else:
##there are still changes going on
#this is where I would want it to start back over at the top again
return showCity(new_array) #this function creates a plt.imshow representation of the resulting array
There are a few loops you could apply to achieve something like this. Firstly, a while loop. while loops, as you may know, run until a condition is met. If you have many conditions, the while statement can get pretty ugly. Many choose to use while True if there are many conditions. Using break will exit the loop.
def rand_string():
while True:
string = "".join(random.sample("abcdefghijk", 7))
if string == "afedgcb":
break
elif string == "cdefgab":
break
elif string == "gbadcef":
break
else:
continue
return string
Above, we choose 7 random letters from the string abcdefghijk and check if the 7 random letters make either afedgcb, cdefgab, or gbadcef. If so, we break out of the loop and return the string. If not, we will restart the loop. The else/continue is not necessary, the loop will still start over if none of the conditions are met because we don't break out of the loop.
Another option is recursion. The example below simply chooses a random number from 0 and 10 and checks if it equals 5. If so, we return the number. If not, we just run the function again.
def rand_num_recursion():
num = random.randint(0,10)
if num == 5:
return num
else:
return rec()
Now, if you were to print(rec()), the answer would always be 5. Why? Because the function will continue to run until the random number chosen is 5. This recursive function can also easily be converted to a while loop:
def rand_num_while():
num = random.randint(0,10)
while num != 5:
num = random.randint(0,10)
return num
What if you have parameters?
With recursion this can be done easily. Of course, the below example is just for demonstration purposes - you would never really need a function to "empty" a list, it is just an example of how to pass updated parameters back to the beginning of the loop.
def empty_list(lst):
if len(lst) == 0:
return lst
else:
print(lst)
return empty_list(lst[:-1]) # return all members of the list except for the last one
When you write print(empty_list([1,2,3,4,5,6])) and keep the print(lst) in the function, the output is as follows:
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5]
[1, 2, 3, 4]
[1, 2, 3]
[1, 2]
[1]
[]
As you can see, every time the condition is not met, we pass an updated parameter back to the beginning of the loop. In this example, you can see that every time the loop occurs, it removes the last element from the list and passes it back to the beginning.

program that among the given numbers finds one that is different in evenness, and return a position of this number

Bob is preparing to pass IQ test. The most frequent task in this test is to find out which one of the given numbers differs from the others. Bob observed that one number usually differs from the others in evenness. Help Bob — to check his answers, he needs a program that among the given numbers finds one that is different in evenness, and return a position of this number.
! Keep in mind that your task is to help Bob solve a real IQ test, which means indexes of the elements start from 1 (not 0)
Examples :
iq_test("2 4 7 8 10") => 3 // Third number is odd, while the rest of the numbers are even
iq_test("1 2 1 1") => 2 // Second number is even, while the rest of the numbers are odd
My Code:
def iq_test(a):
b=[]
c=[]
for i in range(len(a)):
if a[i]%2 == 0:
b.append(a[i])
else:
c.append(a[i])
if len(b)==1:
for i in range(len(a)):
if [a[i]]==b:
return i+1
if len(c)==1:
for i in range(len(a)):
if [a[i]]==c:
return i+1
This works for the given inputs in my IDE, but when I put it in webpage IDE I obtain
Traceback (most recent call last):
File "main.py", line 3, in <module>
Test.assert_equals(iq_test("2 4 7 8 10"),3)
File "/home/codewarrior/solution.py", line 6, in iq_test
if a[i]%2 == 0:
TypeError: not all arguments converted during string formatting
What is the mistake here? Is my code correct?
The parameter given to your function is "2 4 7 8 10". You're iterating over that string and applying a modulo operation, which throws the error you're seeing since Python doesn't do automatic type conversion and can't apply a module to the string "2" (and, if it did, would throw an error at the second iteration when it'd try to apply the modulo operation to " ").
The simplest fix here is to check if it's not a space, then convert to int before the module:
for (i in range (len(a)):
if a[i] != " ":
if int(a[i])%2 == 0:
b.append(a[i])
...
By the way, the index, and range above is not neccessary for strings. You can also iterate over the string directly:
for char in a:
if char != " ":
if int(char)%2 == 0:
b.append(char)
...
You could also split the string into an array and iterate over that:
array = a.split(" ") # results in ["2","4","7","8","10"]
for (item in array):
if int(item)%2 == 0:
b.append(item)
...
In a real world application, I would also opt to check if the character at the current position is convertible to int, but for your case this solution is sufficient.
Also, as someone who recently looked over their own assignments from the first two semesters, get into the habit of using explicitly named variables. e.g instead of b use evenNumbers and instead of c use oddNumbers. This makes your code a lot more readable and better to understand what you did and why.
def iq_test(numbers):
lst = numbers.split()
evens = []
odds = []
for i in lst:
if int(i) % 2 == 0:
evens.append(int(i))
else:
odds.append(int(i))
if len(evens) == 1:
for i in lst:
if int(i) == evens[0]:
return lst.index(i)+1
if len(odds) == 1:
for i in lst:
if int(i) == odds[0]:
return lst.index(i)+1
I got it right

Initializing list of ints. Interpreter returns "ValueError: invalid litteral for int()"

Trying to make a list of ints the user inputs. Inerpreter is returning "ValueError: invalid literal for int() with base 10:"
I'm somewhat new to python and I'm practicing on a website called "geeks for geeks". Here is a link to the problem I'm working on.
The goal of the exercise is to print the first negative integer in a sub array of user specified size. When I try to append the user inputs to the list, the interpreter is giving me a value error. It's obviously not a type error but I can't figure out what kind of input could be given to the program to give it that error. The inputs are on a file on geeks for geek's servers so I can only test on inputs I've made.
# This file is for a programing practice exercise of geeksforgeerks.org
# The exercise is first negative int in window of size k
# selecting number of test cases
T = int(input())
for t in range(T):
# initializing array
n = int(input())
arr = []
while n > 0:
arr.append(int(input().strip()))
n-=1
k = int(input())
win = 0 # index of first element in widow subarray
# terminate loop when the window can't extend further
while win < len(array) - k -1:
# boolean for no negatives found
noNeg = True
for i in range(win, k):
if arr[i] < 0:
print(arr[i])
noNeg = False
break
elif i == k-1 and noNeg:
# 0 if last sub arr index reached and found no negs
print(0)
win+=1
The interpreter is giving the following error on line 11:
print(int(input().strip()))
ValueError: invalid literal for int() with base 10: '-8 2 3 -6 10'
The input data contains multiple numbers on the same line. input() returns a whole line of input, and when you call int(input().strip()) you're trying to parse that whole line as a single number.
You need to split it at whitespace. So instead of a while loop, you can use:
arr = map(int, input().strip().split())
Looks like you're inputting multiple integers, int() won't know how to convert them - it expects a single integer to be contained in the string. You'll want to split up the string and then convert:
Ts = [int(word) for word in input().strip().split(" ")]
Note that this will give you a list instead of a single integer.
you are feeding the input with multiple integers, you can extend your array at line 11 with your desired values:
arr = []
arr.extend(map(int, input().strip().split()))
# input: -8 2 3 -6 10
output:
[-8, 2, 3, -6, 10]

List Index Out of Range in Python; Iteration

I am using the simple program below to see how long an iterative process takes to terminate. However, in line 15, I cannot figure out why I am getting index out range error.
An example of what I am trying to count is the number of steps it takes for the following example iteration: User inputs 4 and then 1234. Then we have: [1,2,3,4] --> [1,1,1,1] --> [0,0,0,0] and then termination. 2 steps is required to get to [0,0,0,0]. I have proven that for the values of n that I am inserting, the system goes to [0,0,0,0] eventually.
import math
index = input("Enter length: ")
n = int(index)
game = input("Enter Coordinates of length n as a number: ")
s = list(game)
Game = []
for k in s:
Game.append(int(k))
l = len(game)
while sum(Game) > 0:
Iteration = []
k = 0
j = 0
while j < l-1:
Iteration.append(math.fabs(Game[j]-Game[j+1])) # line 15
j = j+1
k = k+1
Game = Iteration
print(k)
Game = Iteration is probably why. When j = 1, Game will be a list with only one item because of that. Then, Game[1]-Game[2] will be out of bounds.
Your code is written in a very un-Pythonic style that suggests you're translating directly from C code. (Also, you should basically never use input(); it's insecure because it evaluates arbitrarily user-entered Python code! Use raw_input() instead.)
If you rewrite it in a more Pythonic style, it becomes clear what the problem is:
import math
# you don't do anything with this value, but okay
s = index = int(raw_input("Enter length: "))
# game/Game naming will lead to confusion in longer code
game = raw_input("Enter Coordinates of length n as a list of comma-separated numbers: ")
Game = [int(k) for k in game.split(',')]
l = len(Game)
while sum(Game) > 0:
Game = [math.fabs(Game[j]-Game[j+1]) for j in range(l-1)] # problem here
# no idea what k is for, but it's not used in the loop anywhere
The problem is that in every iteration through your inner while loop, or the line marked # problem here in my version, your Game list gets shorter by one element! So on the second time through the outer while loop, it reads an element past the end of Game.
I have no idea what this code is trying to do, so I can't really suggest a fix, but if you truly intend to shorten the list on every pass, then you of course need to account for its shorter length by putting l=len(Game) inside the while loop.

Categories