What does this Python error mean? - python-3.x

This was my test code (Python 3.2)
import random
def singleMatch():
a = random.randint(1, 5050)
b = random.randint(1, 5050-a)
c = 5050-a-b
h = [a, b, c]
print(h)
computer = [841, 842, 3367]
score = 0
for i, j in zip(computer, h):
if i > j:
score = score + 1
if score == 2:
return 1
else:
return 0
def match(n):
matchScore = 0
for i in range(n):
s = singleMatch()
matchScore = matchScore + s
return matchScore
x = match(10000)
print(x)
When I run the code, I sometimes get this error:
Traceback (most recent call last):
File "D:\Ercan\blotto.py", line 32, in <module>
x = match(10000)
File "D:\Ercan\blotto.py", line 28, in match
s = singleMatch()
File "D:\Ercan\blotto.py", line 5, in singleMatch
b = random.randint(1, 5050-a)
File "C:\Python32\lib\random.py", line 215, in randint
return self.randrange(a, b+1)
File "C:\Python32\lib\random.py", line 193, in randrange
raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
ValueError: empty range for randrange() (1,1, 0)
I couldn't figure out what it means, or what I did wrong.

You are telling your program to create a random number between 1 and 5050 and store it in a. Afterwards you want to get another random number between 1 and 5050-a, now if a is 5050, you would ask it to generate a random number between 1 and 0.
reference

Short answer: the error means that a is sometimes equal to 5050.
Long answer: randint() returns a random number lying in the supplied range. If the upper bound is less than the lower bound, then the function fails because there is no actual range to process.
Your first call stores a random number between 1 and 5050 (inclusive) into a. Your second call stores a random number between 1 and 5050 - a (inclusive) into b. If the first call returns 5050, then the second call will fail because the supplied range will be invalid.

Related

Index going out of range in bisect_left in Python 3

I'm writing this piece of code, in which I've used bisect_left function from the bisect module which is a first-party module of Python. I'm using it with two parameters only i.e. sorted_list and target(the one for which I have to find the suitable index value).
The issue is: If my target is greater than the sum of lowest value and highest value, the function is returning the index = len(sorted_li), due to which I'm getting index error. I can use try and except but more than that I'm curious to know why it is behaving like so.
Following is my code:
from bisect import bisect_left
li = [10,15,3,6,10]
k = 19
def binary_search(sorted_list,target):
index = bisect_left(sorted_list,target)
print(index)
if sorted_list[index] == target:
return index
else:
return False
def function(sorted_li,k):
"""
Given a list of numbers and a number k, return whether any two numbers from the list add up to k.
For example, given [10, 15, 3, 7] and k of 17, return true since 10 + 7 is 17.
"""
print(sorted_li)
for i in range(len(sorted_li)):
print('Next iteration')
print(sorted_li[i])
target = k - sorted_li[i]
j = binary_search(sorted_li,target)
if j:
if j != i:
print(sorted_li[i])
print(sorted_li[j])
return True
else:
if j + 1 < len(sorted_li):
if sorted_li[j+1] == target:
print(sorted_li[i])
print(sorted_li[j+1])
return True
if j - 1 > 0:
if sorted_li[j-1] == target:
print(sorted_li[i])
print(sorted_li[j-1])
return True
return False
if __name__ == "__main__":
li.sort()
a = function(li,k)
print(a)
It's output is as follows:
but when I'm changing k to 18, the code is working fine, the output is as follows:
I've tried with various sets of numbers for the same. The output remains the same.
You're using bisect_left which has next purpose: it looking for the insertion point for x (which is target in your case) in a to maintain sorted order.
So for your case when you call first binary_search first time for 16 (19 - 3), it compare your number with items in li list using binary algorithm and then it returns position for insert 5, because in your list [3, 6, 10, 10, 15] insertion point should be after 15 which is correct.
If you open documentation you can find next method in searching sorted list
which does exactly you need, it searching for the exact item in list and return position of it if it exists either it raises ValueError because item not found.
def index(a, x):
'Locate the leftmost value exactly equal to x'
i = bisect_left(a, x)
if i != len(a) and a[i] == x:
return i
raise ValueError

How to multiply every digit of float input by user and then summing up

Hello i want to access float input by users and then multiply every other element of input as per Luhn algorithm but getting below errors. Any help is highly appreciated
def main():
while True:
x = get_float("user_input: ")
if(len(str(x))>12 and len(str(x))<20):
break
#multiply every other digit
#for digits in x:
y = str(x)
y[0::2]= [z*2 for z in y[0::2]]
print(y)
running the program
user_input: 1234567891234
Traceback (most recent call last):
File "credit.py", line 22, in <module>
main()
File "credit.py", line 13, in main
y[0::2]= [z*2 for z in y[0::2]]
TypeError: 'str' object does not support item assignment
you cannot change only a portion of y, because it is immutable (string).
instead, you can do this
y = "".join([str(int(z) * 2) if i % 2 == 0 else z for i, z in enumerate(y)])
this works because it reassign the variable y and not individual characters in y (which you cannot do)

How can i adjust this code to python 3 for palindrome numbers?

# Python program to count and
# print all palindrome numbers in a list.
def palindromeNumbers(list_a):
c = 0
# loop till list is not empty
for i in list_a:
# Find reverse of current number
t = i
rev = 0
while t > 0:
rev = rev * 10 + t % 10
t = t / 10
# compare rev with the current number
if rev == i:
print (i),
c = c + 1
print
print ("Total palindrome nos. are" + str(c))
print
def main():
list_a = [10, 121, 133, 155, 141, 252]
palindromeNumbers(list_a)
list_b = [ 111, 220, 784, 565, 498, 787, 363]
palindromeNumbers(list_b)
if __name__ == "__main__":
main() # main function call
This code, obtained from
https://www.geeksforgeeks.org/all-palindrome-numbers-in-a-list/, has been written in Python 2.
When I run this program in Python 3.6 it returns the value as 0 for both lists.
Can someone tell me how to change it to be compatible with Python 3?
One of the important changes between Python2 and Python3 is integer division, that in Python2 returns a truncated, integer result while in Python3 returns a floating point number. To have a real integer division you have to use a double slash, "//".
In summary, change the line t = t/10 to t = t//10.
Ok, so I have changed the code a bit using a different method to check if the number is the same reversed... I tried not to change too much of your code...
The function reverse() just returns the string given to it reversed...
If I'm not mistaken the function makes a list out of the str by split function then [::-1] gives the list reversed...
def reverse(str):
return str[::-1]
def palindromeNumbers(list_a):
c = 0
# loop till list is not empty
for i in list_a:
# Find reverse of current number
t = i
t = int(reverse((str(t))))
if t == i:
c += 1
print ("Total palindrome nos. are " + str(c))
def main():
list_a = [10, 121, 133, 155, 141, 252]
palindromeNumbers(list_a)
list_b = [ 111, 220, 784, 565, 498, 787, 363]
palindromeNumbers(list_b)
if __name__ == "__main__":
main() # main function call
Try it out! I hope you find this helpful...
I first converted the number to an iterable string str(i). Then I shortened the for loop by only comparing the first half of the number t[a] to the second half of the number t[~a], and then using all() to check that all of the comparisons were true. (using Python 3.6.8)
for i in list_a:
# convert interger to iterable string
t = str(i)
# compare first half of the number to second half of the number
if all([t[a]==t[~a] for a in range(len(t)//2)]):
print (i),
c = c + 1

Index Error Problems

So I'm making a calculator that takes in a string and checks to see if it has certain words like add or subtract and then finding integers. However, in my current code, I run it and get this error message:
Traceback (most recent call last):
File "python", line 1, in <module>
File "python", line 7, in calculator
IndexError: string index out of range
The code is typed out below.
def calculator(string):
if "add" in string or "Add" in string:
total = 0
for i in range(len(string)): #loop for length of string
try:
if type(int(string[i])) == int: #checks to see if there is a number in the string
try:
if type(int(string[i+1])): #checks to see if the number is 2 digits
number_1 = int(string[i])*10
except ValueError:
number_1 = int(string[i])
total = total + number_1 #adds all the numbers to a total variable
except ValueError:
pass
print (total)
If someone could help me out that would be great! Thanks so much!
I believe your problem is with type(int(string[i+1]))
as you have a for loop, i can already be pointing to the last index of string. When you add 1 to that, you get an IndexError
Example:
s = 'blabla'
for i in range(len(s)):
print(s[i])
Output:
b
l
a
b
l
a
Example:
s = 'blabla'
for i in range(len(s)):
print(s[i+1])
Output:
l
a
b
l
a
File "C:\Users\python\scratch\untitled-1.py", line 3, in <module>
print(s[i+1])
builtins.IndexError: string index out of range
Sat down with my friend(#Kay Ace Elits) and realised a bunch of things were amiss but we pieced this together
def calculator(string):
if "add" in string:
total = 0
first_string = "" # before a in add
second_string = "" # after d in add
value_list = string.split('add')
for number in value_list:
total += int(number)
print(total)
elif "Add" in string:
total = 0
first_string = ""
second_string = ""
value_list = string.split('Add')
for number in value_list:
total += int(number)
print(total)
### our test your can modify for other factors
### like spellings and different operations
string = "22add43"
calculator(string)

TypeError: slice indices must be integers or None or have an __index__ method

When running the code in IDLE gives the following error:
Traceback (most recent call last): File "C:/Python34/inversion3.py",
line 44, in <module>
nInversions.inversionMergeSort(m) File "C:/Python34/inversion3.py", line 16, in inversionMergeSort
left = m[0:half] TypeError: slice indices must be integers or None or have an __index__ method
CODE:-
from collections import deque
m = []
f = open("IntegerArray.txt")
for line in f:
m.append(int(line))
class InversionCount:
def __init__(self, n):
self.n = n
def inversionMergeSort(self, m):
if len(m) <= 1:
return m
half = len(m)/2
left = m[0:half]
right = m[half:]
left = self.inversionMergeSort(left)
right = self.inversionMergeSort(right)
return self.inversionSort(left, right)
def inversionSort(self, left, right):
leftQueue = deque(i for i in left)
rightQueue = deque(j for j in right)
orderedList = []
while len(leftQueue) > 0 or len(rightQueue) > 0:
if len(leftQueue) > 0 and len(rightQueue) > 0:
if leftQueue[0] <= rightQueue[0]:
orderedList.append(leftQueue[0])
leftQueue.popleft()
else:
orderedList.append(rightQueue[0])
self.n += len(leftQueue)
rightQueue.popleft()
elif len(leftQueue) > 0:
orderedList.append(leftQueue[0])
leftQueue.popleft()
elif len(rightQueue) > 0:
orderedList.append(rightQueue[0])
rightQueue.popleft()
return orderedList
nInversions = InversionCount(0)
nInversions.inversionMergeSort(m)
print (nInversions.n)
In 3.x, int/int gives a float. which is not an int.
>>> 3/2
1.5
so your line 15
half = len(m)/2
makes half a float. What you need is a double slash
half = len(m)//2
to make half an int, as needed for its use in the slice in line 16.
In your case, len(m)/2 returns a float and line 16 is expecting an int.
You should type cast half to int as the following:
left = m[0:int(half)]
By only using / this will give you result in float you need to use // in order to give the result into integer.
This will resolve the error. It worked for me

Resources