Python Problem: Unable to access option in program - python

I keep recieving an TypeError: cannot unpack non-iterable int object when I select option 4 in the menu. How do I fix this, I have tried for hours with no success. Code is below:
from turtle import right
def selection_sort(altered_number_list, sorting_order):
if sorting_order == 1:
for value in range (0, len(altered_number_list)-1):
least_value = value
for index in range (value+1, len(altered_number_list)):
if altered_number_list[index] < altered_number_list[least_value]:
altered_number_list[index], altered_number_list[least_value] = altered_number_list[least_value], altered_number_list[index]
return altered_number_list
else:
for value in range (0, len(altered_number_list)-1):
least_value = value
for index in range (value+1, len(altered_number_list)):
if altered_number_list[index] > altered_number_list[least_value]:
altered_number_list[index], altered_number_list[least_value] = altered_number_list[least_value], altered_number_list[index]
return altered_number_list
def bubble_sort(altered_number_list, sorting_order):
if sorting_order == 1:
for value in range (len(altered_number_list)):
for index in range (0, len(altered_number_list)-1):
if altered_number_list[index] > altered_number_list[index+1]:
altered_number_list[index], altered_number_list[index+1] = altered_number_list[index+1], altered_number_list[index]
return altered_number_list
else:
for value in range (len(altered_number_list)):
for index in range (0, len(altered_number_list)-1):
if altered_number_list[index] < altered_number_list[index+1]:
altered_number_list[index], altered_number_list[index+1] = altered_number_list[index+1], altered_number_list[index]
return altered_number_list
def insertion_sort(altered_number_list, sorting_order):
if sorting_order == 1:
for value in range(1, len(altered_number_list)):
insert_value = number_list[value]
data_switch = value
while data_switch > 0 and altered_number_list[data_switch-1] > insert_value:
altered_number_list[data_switch] = altered_number_list[data_switch-1]
data_switch -= 1
altered_number_list[data_switch] = insert_value
return altered_number_list
else:
for value in range(1, len(altered_number_list)):
insert_value = number_list[value]
data_switch = value
while data_switch > 0 and altered_number_list[data_switch-1] < insert_value:
altered_number_list[data_switch] = altered_number_list[data_switch-1]
data_switch -= 1
altered_number_list[data_switch] = insert_value
return altered_number_list
def quick_sort(altered_number_list, number_list_min, number_list_max, sorting_order):
if number_list_min < number_list_max:
split_value = partition_sort(altered_number_list, number_list_min, number_list_max, sorting_order)
quick_sort(altered_number_list, number_list_min, split_value-1, sorting_order)
quick_sort(altered_number_list, split_value+1, number_list_max, sorting_order)
def partition_sort(alter_number_list, number_list_min, number_list_max, sorting_order):
if sorting_order == 1:
pivot_value = alter_number_list[number_list_min]
left_value = number_list_min + 1
right_value = number_list_max
complete = False
while not complete:
while left_value <= right_value and alter_number_list[left_value] <= pivot_value:
left_value = left_value + 1
while alter_number_list[right_value] >= pivot_value and right_value >= left_value:
right_value = right_value - 1
if right_value < left_value:
complete = True
else:
alter_number_list[left_value], alter_number_list[right_value] = alter_number_list[right_value], alter_number_list[left_value]
alter_number_list[number_list_min], alter_number_list[right_value] = alter_number_list[right_value] = alter_number_list[number_list_min]
return alter_number_list
else:
pivot_value = alter_number_list[number_list_min]
left_value = number_list_min + 1
right_value = number_list_max
complete = False
while not complete:
while left_value <= right_value and alter_number_list[left_value] >= pivot_value:
left_value = left_value + 1
while alter_number_list[right_value] <= pivot_value and right_value >= left_value:
right_value = right_value - 1
if right_value < left_value:
complete = True
else:
alter_number_list[left_value], alter_number_list[right_value] = alter_number_list[right_value], alter_number_list[left_value]
alter_number_list[number_list_min], alter_number_list[right_value] = alter_number_list[right_value] = alter_number_list[number_list_min]
return alter_number_list
import random
print("This program will sort a list of random numbers using a user determined sorting algorithm.")
sorting_algorithms = ["Selection Sort", "Bubble Sort", "Insertion Sort", "Quick Sort"]
sorting_orders = ["Ascending", "Descending"]
number_list = []
while True:
try:
random_numbers = int(input("Input number of random integers generated: "))
print("Sorting Algorithms: ")
for sort in range (0, len(sorting_algorithms)):
print(f"{sort+1} - {sorting_algorithms[sort]}")
sorting_algorithm = int(input("Select sorting algorithm: "))
print("Sorting Orders: ")
for sort in range (0, len(sorting_orders)):
print(f"{sort+1} - {sorting_orders[sort]}")
sorting_order = int(input("Select sorting algorithm order: "))
if random_numbers < 1 or random_numbers > 999999:
print("Invalid input, integer values greater then or equal to one and integer values less then or equal to 999999 are accepted.")
continue
elif sorting_algorithm < 1 or sorting_algorithm > 4:
print("Invalid input, integer values greater then or equal to one and integer values less then or equal to four are accepted.")
continue
elif sorting_order < 1 or sorting_order > 2:
print("Invalid input, integer values greater then or equal to one and integer values less then or equal to two are accepted.")
continue
for i in range(random_numbers):
number_list.append(random.randint(0, 999999))
print (number_list)
number_list_min = 0
number_list_max = len(number_list) - 1
if sorting_algorithm == 1:
altered_number_list = selection_sort(number_list, sorting_order)
break
elif sorting_algorithm == 2:
altered_number_list = bubble_sort(number_list, sorting_order)
break
elif sorting_algorithm == 3:
altered_number_list = insertion_sort(number_list, sorting_order)
break
elif sorting_algorithm == 4:
altered_number_list = quick_sort(number_list, number_list_min, number_list_max, sorting_order)
break
except:
print("Invalid input, integer values in the program specified parameters are accepted.")
print(altered_number_list)
In the code above, I am able to access options 1, 2, and 3 with no difficulty but I am unable to access the 4th option as it displays an error message. At this point, I have tried renaming variables, using different loops and operations, and creating separate functions but I am still unable to access the 4th option which is the quick sort algorithm. Any help is greatly appreciated!
Here is the code for the quick sort and partition sort:
def quick_sort(altered_number_list, number_list_min, number_list_max, sorting_order):
if number_list_min < number_list_max:
split_value = partition_sort(altered_number_list, number_list_min, number_list_max, sorting_order)
quick_sort(altered_number_list, number_list_min, split_value-1, sorting_order)
quick_sort(altered_number_list, split_value+1, number_list_max, sorting_order)
def partition_sort(alter_number_list, number_list_min, number_list_max, sorting_order):
if sorting_order == 1:
pivot_value = alter_number_list[number_list_min]
left_value = number_list_min + 1
right_value = number_list_max
complete = False
while not complete:
while left_value <= right_value and alter_number_list[left_value] <= pivot_value:
left_value = left_value + 1
while alter_number_list[right_value] >= pivot_value and right_value >= left_value:
right_value = right_value - 1
if right_value < left_value:
complete = True
else:
alter_number_list[left_value], alter_number_list[right_value] = alter_number_list[right_value], alter_number_list[left_value]
alter_number_list[number_list_min], alter_number_list[right_value] = alter_number_list[right_value] = alter_number_list[number_list_min]
return alter_number_list
else:
pivot_value = alter_number_list[number_list_min]
left_value = number_list_min + 1
right_value = number_list_max
complete = False
while not complete:
while left_value <= right_value and alter_number_list[left_value] >= pivot_value:
left_value = left_value + 1
while alter_number_list[right_value] <= pivot_value and right_value >= left_value:
right_value = right_value - 1
if right_value < left_value:
complete = True
else:
alter_number_list[left_value], alter_number_list[right_value] = alter_number_list[right_value], alter_number_list[left_value]
alter_number_list[number_list_min], alter_number_list[right_value] = alter_number_list[right_value] = alter_number_list[number_list_min]
return alter_number_list
I believe the main issue lies in the following code:
while True:
try:
random_numbers = int(input("Input number of random integers generated: "))
print("Sorting Algorithms: ")
for sort in range (0, len(sorting_algorithms)):
print(f"{sort+1} - {sorting_algorithms[sort]}")
sorting_algorithm = int(input("Select sorting algorithm: "))
print("Sorting Orders: ")
for sort in range (0, len(sorting_orders)):
print(f"{sort+1} - {sorting_orders[sort]}")
sorting_order = int(input("Select sorting algorithm order: "))
if random_numbers < 1 or random_numbers > 999999:
print("Invalid input, integer values greater then or equal to one and integer values less then or equal to 999999 are accepted.")
continue
elif sorting_algorithm < 1 or sorting_algorithm > 4:
print("Invalid input, integer values greater then or equal to one and integer values less then or equal to four are accepted.")
continue
elif sorting_order < 1 or sorting_order > 2:
print("Invalid input, integer values greater then or equal to one and integer values less then or equal to two are accepted.")
continue
for i in range(random_numbers):
number_list.append(random.randint(0, 999999))
print (number_list)
number_list_min = 0
number_list_max = len(number_list) - 1
if sorting_algorithm == 1:
altered_number_list = selection_sort(number_list, sorting_order)
break
elif sorting_algorithm == 2:
altered_number_list = bubble_sort(number_list, sorting_order)
break
elif sorting_algorithm == 3:
altered_number_list = insertion_sort(number_list, sorting_order)
break
elif sorting_algorithm == 4:
altered_number_list = quick_sort(number_list, number_list_min, number_list_max, sorting_order)
break
except:
print("Invalid input, integer values in the program specified parameters are accepted.")

The error message:
TypeError: cannot unpack non-iterable int object
is most likely telling you that somewhere in your code, you must have a line that looks like:
a, b = c
where c is an int, and thus cannot be split into a and b as if it were a pair.
There is only one line in your code that looks like this, and it is indeed suspicious:
alter_number_list[number_list_min], alter_number_list[right_value] = alter_number_list[right_value] = alter_number_list[number_list_min]
I believe you meant to swap the two values, and the second equal sign = should instead be a comma ,:
alter_number_list[number_list_min], alter_number_list[right_value] = alter_number_list[right_value], alter_number_list[number_list_min]
Note that the full error trace given by python usually includes more information than just this short error message. You should see a longer message telling you in which function and at which line the error occurred. Reading that full error message would have made it a lot faster to find the suspicious line in your code.

Related

Passing data between a series of related functions

I am attempting to create an exam grading program. I successfully wrote each function to do what I need it to, but when I attempt to execute the entire program, I am running into issues with my return variables not being referenced.
Here is my code for context:
def userinput():
allinputs = []
while True:
try:
results = list(map(int, input('Exam points and exercises completed: ').split(' ')))
allinputs.append(results)
except:
ValueError
break
return allinputs
def points(allinputs):
exampoints = []
exercises = []
exercises_converted = []
gradepoints = []
counter = 0
for i in allinputs:
exampoints.append(i[0])
exercises.append(i[1])
for e in exercises:
exercises_converted.append(e//10)
for p in exampoints:
p2 = exercises_converted[counter]
gradepoints.append(p + p2)
counter += 1
return (gradepoints, exampoints, exercises_converted)
def average(gradepoints):
avg_float = sum(gradepoints) / len(gradepoints)
points_avg = round(avg_float, 1)
return points_avg
def pass_percentage(exercises_converted, exampoints):
failexam = []
passexam = []
passorfail = []
i = 0
while i < len(exampoints):
if exampoints[i] < 10 or exercises_converted[i] + exampoints[i] < 15:
failexam.append("fail")
passorfail.append(0)
else:
passexam.append("pass")
passorfail.append(1)
i += 1
percentage_float = len(passexam)/len(failexam)
percentage = round(percentage_float, 1)
return (percentage, passorfail)
def grades_distribution(passorfail, gradepoints):
grades = []
i = 0
l = 5
while i < len(gradepoints):
if passorfail[i] == 0:
grades.append(0)
elif passorfail[i] != 0 and gradepoints[i] >= 15 and gradepoints[i] <= 17:
grades.append(1)
elif passorfail[i] != 0 and gradepoints[i] >= 18 and gradepoints[i] <= 20:
grades.append(2)
elif passorfail[i] != 0 and gradepoints[i] >= 21 and gradepoints[i] <= 23:
grades.append(3)
elif passorfail[i] != 0 and gradepoints[i] >= 24 and gradepoints[i] <= 27:
grades.append(4)
elif passorfail[i] != 0 and gradepoints[i] >= 28 and gradepoints[i] <= 30:
grades.append(5)
i += 1
while l >= 0:
print(l, ": ", "*" * grades.count(l))
return
userinput()
print("Statistics:")
points(allinputs)
print(f"Points average: {average(gradepoints)}")
print(f"Pass percentage: {pass_percentage(exercises_converted, exampoints)}")
print("Grade distribution")
grades_distribution(passorfail, gradepoints)
I have no problems with the mechanics within each function; rather, my error lies where I try calling each of them from the main function.
The user input() function runs fine, and returns allinputs. However, when the second function points(allinputs) is called, the program states that the argument is undefined.
You should store the return value of a function before passing it as argument.
This should solve your problem
allinputs = userinput()
points(allinputs)

the code show bad input and index out of range on the lines, how can i fix it

what‘s the problem with my code and how can I fix it.
The problems are in lines:
world[r].append(element)
world = createWorld()
world = createWorld()
Now I show all of the code, but it seems too long need more text to make it available to post, so ignore this part.so ignore this part.so ignore this part.so ignore this part.so ignore this part.so ignore this part.so ignore this part.so ignore this part.so ignore this part.so ignore this part.so ignore this part.
This was the error given:
IndexError: list index out of range
There are more details in the code below, appreciate it if you can help:)
import random
SIZE = 4
EMPTY = " "
PERSON = "P"
PET = "T"
POOP = "O"
ERROR = "!"
CLEANED = "."
MAX_RANDOM = 10
def clean(world, endRow, endColumn):
print("Scooping the poop")
for r in range(SIZE):
for c in range(SIZE):
if world[r][c] == POOP:
world[r][c] = CLEANED
def count(world, endRow, endColumn):
print("Counting number of occurances of a character")
number = 0
element = input("Enter character: ")
for r in range(SIZE):
for c in range(SIZE):
if world[r][c] == element:
number += 1
return(element, number)
def createElement():
tempNum = random.randrange(MAX_RANDOM)+1
if ((tempNum >= 1) and (tempNum <= 5)):
tempElement = EMPTY
elif ((tempNum >= 6) and (tempNum <= 7)):
tempElement = PERSON
elif (tempNum == 8):
tempElement = PET
elif ((tempNum >= 9) and (tempNum <= 10)):
tempElement = POOP
else:
tempElement = ERROR
return(tempElement)
def createWorld():
world = []
r = 0
while (r < SIZE):
world.append([])
c = 0
while (c < SIZE):
element = createElement()
world[r].append(element)
c = c + 1
r = r + 1
return(world)
def display(world):
print("OUR WORLD")
print("========")
r = 0
while (r < SIZE):
c = 0
while (c < SIZE):
print(world[r][c], end="")
c = c + 1
print()
r = r + 1
print("========\n")
def getEndPoint():
endRow = int(input("Enter the row: "))
while not 0 <= endRow <= 3:
print("Invalid input. Row value should be in range 0-3")
endRow = int(input("Enter the row: "))
endColumn = int(input("Enter the column: "))
while not 0 <= endColumn <= 3:
print("Invalid input. Column value should be in range 0-3")
endColumn = int(input("Enter the column: "))
return (endRow, endColumn)
def start():
world = createWorld()
display(world)
endRow, endColumn = getEndPoint()
element, number = count(world, endRow, endColumn)
print("# occurances of %s=%d" % (element, number))
clean(world, endRow, endColumn)
display(world)
start()
You need to update the r value in the outer loop, currently it is being updated in the inner loop.
def createWorld():
world = []
r = 0
while (r < SIZE):
world.append([])
c = 0
while (c < SIZE):
element = createElement()
world[r].append(element)
c = c + 1
r = r + 1
return (world)

binary search after insertion sort in python

def binary(arr,key):
low = 0
high = len(arr)-1
found = False
while low<=high and not found:
mid = (low+high)//2
if arr[mid] == key:
found = True
index = mid
elif key<arr[mid]:
high = mid-1
else:
low = mid+1
if found == True:
print("key found index: ",index)
else:
print("not found")
This list ask user how many values u want to add
value = int(input("how many number u want to add"))
arr = [0] * value
for n in range(value):
arr[n] = input("Enter value")
print("unsorted array: ")
for n in arr:
print(n, end=" ")
for n in range(1, len(arr)):
temp = arr[n]
j = n - 1
while temp < arr[j] and (j >= 0):
arr[j + 1] = arr[j]
j = j - 1
arr[j + 1] = temp
it show error if value < alist[midpoint]:
TypeError: '<' not supported between instances of 'int' and 'str'
in line 10
The reason for the type error is that arr is a List[str]. You can fix this by changing it to type List[int]:
for n in range(value):
arr[n] = int(input("Enter value"))

How do I run a binary search for words that start with a certain letter?

I am asked to binary search a list of names and if these names start with a particular letter, for example A, then I am to print that name.
I can complete this task by doing much more simple code such as
for i in list:
if i[0] == "A":
print(i)
but instead I am asked to use a binary search and I'm struggling to understand the process behind it. We are given base code which can output the position a given string. My problem is not knowing what to edit so that I can achieve the desired outcome
name_list = ["Adolphus of Helborne", "Aldric Foxe", "Amanita Maleficant", "Aphra the Vicious", "Arachne the Gruesome", "Astarte Hellebore", "Brutus the Gruesome", "Cain of Avernus"]
def bin_search(list, item):
low_b = 0
up_b = len(list) - 1
found = False
while low_b <= up_b and found == False:
midPos = ((low_b + up_b) // 2)
if list[midPos] < item:
low_b = midPos + 1
elif list[midPos] > item:
up_b = midPos - 1
else:
found = True
if found:
print("The name is at positon " + str(midPos))
return midPos
else:
print("The name was not in the list.")
Desired outcome
bin_search(name_list,"A")
Prints all the names starting with A (Adolphus of HelBorne, Aldric Foxe .... etc)
EDIT:
I was just doing some guess and check and found out how to do it. This is the solution code
def bin_search(list, item):
low_b = 0
up_b = len(list) - 1
true_list = []
count = 100
while low_b <= up_b and count > 0:
midPos = ((low_b + up_b) // 2)
if list[midPos][0] == item:
true_list.append(list[midPos])
list.remove(list[midPos])
count -= 1
elif list[midPos] < item:
low_b = midPos + 1
count -= 1
else:
up_b = midPos - 1
count -= 1
print(true_list)
Not too sure if this is what you want as it seems inefficient... as you mention it seems a lot more intuitive to just iterate over the entire list but using binary search i found here i have:
def binary_search(seq, t):
min = 0
max = len(seq) - 1
while True:
if max < min:
return -1
m = (min + max) // 2
if seq[m][0] < t:
min = m + 1
elif seq[m][0] > t:
max = m - 1
else:
return m
index=0
while True:
index=binary_search(name_list,"A")
if index!=-1:
print(name_list[index])
else:
break
del name_list[index]
Output i get:
Aphra the Vicious
Arachne the Gruesome
Amanita Maleficant
Astarte Hellebore
Aldric Foxe
Adolphus of Helborne
You just need to found one item starting with the letter, then you need to identify the range. This approach should be fast and memory efficient.
def binary_search(list,item):
low_b = 0
up_b = len(list) - 1
found = False
midPos = ((low_b + up_b) // 2)
if list[low_b][0]==item:
midPos=low_b
found=True
elif list[up_b][0]==item:
midPos = up_b
found=True
while True:
if found:
break;
if list[low_b][0]>item:
break
if list[up_b][0]<item:
break
if up_b<low_b:
break;
midPos = ((low_b + up_b) // 2)
if list[midPos][0] < item:
low_b = midPos + 1
elif list[midPos] > item:
up_b = midPos - 1
else:
found = True
break
if found:
while True:
if midPos>0:
if list[midPos][0]==item:
midPos=midPos-1
continue
break;
while True:
if midPos<len(list):
if list[midPos][0]==item:
print list[midPos]
midPos=midPos+1
continue
break
else:
print("The name was not in the list.")
the output is
>>> binary_search(name_list,"A")
Adolphus of Helborne
Aldric Foxe
Amanita Maleficant
Aphra the Vicious
Arachne the Gruesome
Astarte Hellebore

Binary Subtraction - Python

I want to make a binary calculator and I have a problem with the subtraction part. Here is my code (I have tried to adapt one for sum that I've found on this website).
maxlen = max(len(s1), len(s2))
s1 = s1.zfill(maxlen)
s2 = s2.zfill(maxlen)
result = ''
carry = 0
i = maxlen - 1
while(i >= 0):
s = int(s1[i]) - int(s2[i])
if s <= 0:
if carry == 0 and s != 0:
carry = 1
result = result + "1"
else:
result = result + "0"
else:
if carry == 1:
result = result + "0"
carry = 0
else:
result = result + "1"
i = i - 1
if carry>0:
result = result + "1"
return result[::-1]
The program works fine with some binaries subtraction but it fails with others.
Can someone please help me because I can't find the mistake? Thanks a lot.
Short answer: Your code is wrong for the case when s1[i] == s2[i] and carry == 1.
Longer answer: You should restructure your code to have three separate cases for s==-1, s==0, and s==1, and then branch on the value of carry within each case:
if s == -1: # 0-1
if carry == 0:
...
else:
...
elif s == 0: # 1-1 or 0-0
if carry == 0:
...
else:
...
else: # 1-0
if carry == 0:
...
else:
...
This way you have a separate block for each possibility, so there is no chance of overlooking a case like you did on your first attempt.
I hope the answer below it helps.
def binarySubstration(str1,str2):
if len(str1) == 0:
return
if len(str2) == 0:
return
str1,str2 = normaliseString(str1,str2)
startIdx = 0
endIdx = len(str1) - 1
carry = [0] * len(str1)
result = ''
while endIdx >= startIdx:
x = int(str1[endIdx])
y = int(str2[endIdx])
sub = (carry[endIdx] + x) - y
if sub == -1:
result += '1'
carry[endIdx-1] = -1
elif sub == 1:
result += '1'
elif sub == 0:
result += '0'
else:
raise Exception('Error')
endIdx -= 1
return result[::-1]
normalising the strings
def normaliseString(str1,str2):
diff = abs((len(str1) - len(str2)))
if diff != 0:
if len(str1) < len(str2):
str1 = ('0' * diff) + str1
else:
str2 = ('0' * diff) + str2
return [str1,str2]

Categories

Resources