ValueError with random class in python not working - python

Here is the code:
import random
import numpy as np
class Room:
def __init__(self, name, contents):
self.name = name
self.contents = contents
rooms = np.zeros((11, 11))
maxRooms = 7
possibleNextRoom = []
def resetLevel():
global rooms
for r in range(len(rooms[0])):
for c in range(len(rooms[1])):
rooms[r][c] = 0
possibleNextRoom = []
halfHeight = int(len(rooms[1]) / 2)
halfWidth = int(len(rooms[0]) / 2)
rooms[halfWidth][halfHeight] = 1
def countRooms():
global rooms
roomCount = 0
for r in range(len(rooms)):
for c in range(len(rooms)):
if rooms[r][c] == 1:
roomCount += 1
return roomCount
def findPossibleRooms():
for r in range(len(rooms) - 1):
for c in range(len(rooms) - 1):
if rooms[r][c] == 1:
if rooms[r][c+1] != 1:
possibleNextRoom.append((r, c+1))
if rooms[r][c-1] != 1:
possibleNextRoom.append((r, c-1))
if rooms[r-1][c] != 1:
possibleNextRoom.append((r-1, c))
if rooms[r+1][c] != 1:
possibleNextRoom.append((r+1, c))
def addRoom():
nextRoom = random.randrange(0, len(possibleNextRoom))
rooms[possibleNextRoom[nextRoom][0]][possibleNextRoom[nextRoom][1]] = 1
possibleNextRoom.pop(nextRoom)
def generateLevel():
resetLevel()
while countRooms() < maxRooms:
countRooms()
findPossibleRooms()
addRoom()
def displayLevel():
print(rooms)
generateLevel()
displayLevel()
Here is the Error:
ValueError: empty range for randrange() (0, 0, 0)
I thought I was using random correctly, but appearantly not. I tried making the array start with something in it, but it still gave me the same error. I have been working on this for a long time and its giving me a headache. Any help with this is greatly appreciated. The error is on line 54.

In [90]: import random
In [91]: random.randrange?
Signature: random.randrange(start, stop=None, step=1, _int=<class 'int'>)
Docstring:
Choose a random item from range(start, stop[, step]).
...
This produces your error:
In [92]: random.randrange(0,0)
Traceback (most recent call last):
File "<ipython-input-92-566d68980a89>", line 1, in <module>
random.randrange(0,0)
File "/usr/lib/python3.8/random.py", line 226, in randrange
raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width))
ValueError: empty range for randrange() (0, 0, 0)
So if the error occurs in (telling us the line number if 52 is nearly useless)
nextRoom = random.randrange(0, len(possibleNextRoom))
it means possibleNextRoom is an empty list, [] (or possibly something else with a 0 len).
I see a
possibleNextRoom = []
The append in findPossibleRooms operate in-place, so can modify this global list. But they are wrapped in for and if, so I can't say whether they run at all.
In any case, the error tells that nothing has been appended, for one reason or other.

Related

__init__() takes 1 positional argument but 2 were given and empty tkinter

Saw some similar posts about this, but they used something called Django?
First of all, this is school assignment, i know stack overflow isnt to fond of us students asking for stuff. I just wanted to clarify that.
First code runs, but when I close it, the error occurs. And in my tkinter window nothing appears.
The issue lies in the following line of code:
board2 = EQ([0, 4, 7, 5, 2, 6, 1, 3])
The main function is there to test class for a correct solution. This is a Eight Queens problem.
Hope someone can help me out.
Here is the rest of my code for context:
If the code doesnt make sense, here is an image of the assignment, https://imgur.com/a/G5PdrRQ.
from tkinter import *
SIZE = 8
class EQ:
def __init__(self):
self.queens = SIZE * [-1]
window = Tk()
window.title("Eight Queens")
window.mainloop()
def get(self, i):
return self.queens[i]
def set(self, i, j):
self.queens[i] = j
def is_solved(self):
for i in range(0, 8):
#If two queens are in same row
for j in range(i + 1, 8):
if self.queens[i] == self.queens[j]:
return False
#Diagonal down
count = 1
for j in range(i + 1, 8):
if count + self.queens[i] == self.queens[j]:
return
count += 1
#Diagonal up
count = 1
for j in range(i + 1, 8):
if self.queens[i] - count == self.queens[j]:
return False
count += 1
return True
def print_board(self):
for i in range(0, 8):
for j in range(0,8):
print("|", end = " ")
if self.queens[j] == i:
print("X", end = " ")
else:
print(" ", end = " ")
print("|")
def main():
board1 = EQ()
board1.set(0, 2)
board1.set(1, 4)
board1.set(2, 7)
board1.set(3, 1)
board1.set(4, 0)
board1.set(5, 3)
board1.set(6, 6)
board1.set(7, 5)
print("Is board1 a correct eight queen placement?",
board1.is_solved())
board2 = EQ([0, 4, 7, 5, 2, 6, 1, 3])
if board2.is_solved():
print("Eight queens are placed correctly in board2")
board2.print_board()
else:
print("Eight queens are placed incorrectly in board2")
main()
You don't need tkinter at all as the application has just console output.
As the current constructor of EQ does not accept argument, so the second instance creation will raise the error.
To fix it, just modify constructor of EQ to accept optional list:
class EQ:
def __init__(self, queens=None):
self.queens = queens if queens else SIZE*[-1]
# removed tkinter stuff
...

Keep getting type error with decorative function

I keep getting a type error for this. I am experimenting with decorative functions. Any help is appreciated
def primer(func):
def primes(n):
print (n)
return None
#primer
def find_prime(n):
while True:
count = 2
if (count == n):
z = ("PRIME")
return z
elif (n % count == 0):
z = n / count
return z
else:
count += 1
continue
prime = find_prime()
prime(10)
def primer(func):
def primes(n):
print(n)
#return None: dont know why this is here, you could do without it
return primes
#The nontype error is occuring because your code is returning none
#so to fix that all you have to do is return the inner function
#primer
def find_prime(n):
while True:
count = 2
if (count == n):
z = ("PRIME")
return z
elif (n % count == 0):
z = n / count
return z
else:
count += 1
continue
prime = find_prime
# if you want to turn a function into a variable you have to make sure it's
# callable, which means no parantheses around it
prime(15) # then you can call it

Random Number Range in Python, ValueError: empty for Range ()

This python code is returning a ValueError in the random number generator section of the code. I ran it with hardcoded values in the function: def fermat_test(n): at line
a = random.randit(2,n-1), and it seemed to run otherwise. I can't figure out why the range is out of bounds?
import random
def remainder(i,j):
rem = i%j
return rem
def is_even(n): return n % 2 == 0
def square(n): return n**2
def expmod(b, e, m):
if e==0:
return 1
elif is_even(e):
expm = expmod(b, e/2,m)
return remainder(expm*expm,m)
else:
return remainder(b*expmod(b,e-1,m),m)
def fermat_test(n):
a = random.randint(2,n-1)
return expmod(a,n,n)==a
def is_fermat_prime(n, ntimes):
if ntimes == 0:
return True
elif fermat_test(n):
return is_fermat_prime(n,ntimes-1)
else:
return False
## this is the test you can use to test your code
def sum_of_fermat_primes(n):
sum = 0
for i in xrange(n+1):
if is_fermat_prime(i, 70):
sum += i
return sum
print sum_of_fermat_primes(10)
print sum_of_fermat_primes(20)
print sum_of_fermat_primes(560)
print sum_of_fermat_primes(570)
Traceback (most recent call last):
File "C:\Users\Terik\.atom\code.py", line 33, in <module>
print sum_of_fermat_primes(10)
File "C:\Users\Terik\.atom\code.py", line 30, in sum_of_fermat_primes
if is_fermat_prime(i, 70):
File "C:\Users\Terik\.atom\code.py", line 22, in is_fermat_prime
elif fermat_test(n):
File "C:\Users\Terik\.atom\code.py", line 17, in fermat_test
a = random.randint(2,n-1)
File "C:\Python27\lib\random.py", line 242, in randint
return self.randrange(a, b+1)
File "C:\Python27\lib\random.py", line 218, in randrange
raise ValueError, "empty range for randrange() (%d,%d, %d)" % (istart, istop, width)
ValueError: empty range for randrange() (2,0, -2)
The error is because in
a = random.randint(2,n-1)
n - 1 is less than 2. In fact, the value of n comes from i in for i in xrange(n+1), so it starts from 0, 1, 2, etc. These smallest values make the random.randint(2,n-1) invalid.
Your i in xrange starts at 0 it should start at 1 instead.
for i in xrange(1, n+1):

Why is the code (Python) giving error?

import numpy as np
import matplotlib.pyplot as plt
class Prisoners_Dilemma:
def __init__(self,n,p):
self.n = n
self.p = p
def decision_array(self):
self.dict_dict = {}
for i in range(1,self.n + 1):
self.dict_dict[i] = []
list_list = []
for j in range(1,self.n):
#np.random.seed(j)
self.r = np.random.uniform(0,1)
if self.r > self.p:
q = 0
else:
q = 1
list_list.append(q)
self.dict_dict[i] = list_list
return self.dict_dict
def payoff(self):
self.dict_dict_2 = {}
for i in range(1,self.n + 1):
self.dict_dict_2[i] = []
list_list_2 = []
list_list_3=[]
for j in range(1, i):
list_list_2.append(self.dict_dict[j][i-2])
for j in range(i + 1, self.n + 1):
list_list_2.append(self.dict_dict[j][i-1])
list_list_2_np = np.array(list_list_2)
against_i = np.sum(list_list_2_np)
for_i = np.sum(self.dict_dict[i])
if against_i == 0 and for_i == 0:
payoff_i = 2
elif against_i == 0 and for_i != 0:
payoff_i = 5
elif against_i != 0 and for_i == 0:
payoff_i = -5
else:
payoff_i = -2
list_list_3.append(payoff_i)
self.dict_dict_2[i]=list_list_3
return self.dict_dict_2
def gameplay(self, N, initial_count):
self.counter = initial_count
for i in range(N):
for j in range(1, self.n + 1):
z = self.dict_dict_2[j]
x = np.array(z)
self.counter += np.sum(z)
return self.counter
y = Prisoners_Dilemma(15,0.015)
print (y.gameplay(20,100))
In the above code, the compiler gives the error that instance has no attribute as dict_dict_2 even though its prefixed with self. Moreover, it is perfectly fine with dict_dict. For the sake of completeness I have included the whole code but the problem lies only in payoff and gameplay methods?
dict_dict_2 is only created in payoff(), therefore you must call it before attempting to call gameplay().
The issue is that you are only creating self.dict_dict_2 variable in the payoff function, but in your logic where you are calling gameplay() function , you are not calling the payoff() function before accessing dict_dict_2 , from the looks of it you are not calling that function anywhere at all.
Not sure what dict_dict_2 holds, but the above is the reason why you are getting the issue, maybe you can move the initialization part of dict_dict_2 to __init__() function , though that would not fix the complete issue, since you would still be trying to access dict_dict_1[j] which can error out if j is not a key in dict_dict_2 .

python 2d array condition

i'm working on 8 queen(Genetic Algorithm) program with python 3.4
i use a matrix for keep queens position. but i have an error in sort() function,i dont underestand this error.
please help me ...
my code:
from random import randrange
__author__ = 'Moein'
class NQueen:
NUM_COLS = 8
POPULATIONS = 100
current = [[]]
def __init__(self):
self.current = [[0 for col in range(self.NUM_COLS + 1)] for row in range(self.POPULATIONS)]
# generate first Generation
for i in range(0, self.POPULATIONS):
for j in range(0, self.NUM_COLS):
self.current[i][j] = randrange(self.NUM_COLS)
count = 0
condition = True
while condition:
self.crossover()
self.mutation()
self.fitness()
self.sort()
count += 1
print(self.current)
# print(self.current[0])
if self.current[0][self.NUM_COLS] == 0:
condition = False
print(self.current[0])
pass
def fitness(self):
count = 0
for i in range(0, self.POPULATIONS):
for j in range(0, self.NUM_COLS):
for x in range(j + 1, self.NUM_COLS):
if self.current[i][j] == self.current[i][x]:
count += 1
if abs(j - x) == abs(self.current[i][j] - self.current[i][x]):
count += 1
self.current[i][self.NUM_COLS] = count
count = 0
pass
def sort(self):
for i in range(0, self.POPULATIONS - 1):
for j in range(i + 1, self.POPULATIONS):
if self.current[i][self.NUM_COLS] > self.current[j][self.NUM_COLS]:
for x in range(0, self.NUM_COLS + 1):
temp = self.current[i][x]
self.current[i][x] = self.current
self.current[j][x] = temp
pass
def crossover(self):
_new = [[0 for x in range(self.NUM_COLS + 1)] for x in range(self.POPULATIONS)]
for i in range(0, int(self.POPULATIONS / 2)):
for j in range(0, int(self.NUM_COLS / 2)):
_new[i + 49][j] = self.current[i][j]
_new[i + 49 + 1][j] = self.current[i + 1][j]
for j in range(int(self.NUM_COLS / 2), self.NUM_COLS):
_new[i + 49][j] = self.current[i][j]
_new[i + 49 + 1][j] = self.current[i + 1][j]
self.current = _new
pass
def mutation(self):
for i in range(0, self.POPULATIONS):
self.current[i][randrange(self.NUM_COLS)] = randrange(self.NUM_COLS)
pass
nQueen = NQueen()
print(nQueen.current[0])
and my error:
Traceback (most recent call last):
File "C:/Users/Moein/PycharmProjects/NQueen/project.py", line 81, in <module>
nQueen = NQueen()
File "C:/Users/Moein/PycharmProjects/NQueen/project.py", line 27, in __init__
self.sort()
File "C:/Users/Moein/PycharmProjects/NQueen/project.py", line 54, in sort
if self.current[i][self.NUM_COLS] > self.current[j][self.NUM_COLS]:
TypeError: unorderable types: list() > int()
self.current[i][x] = self.current
I guess that its this line causing the problem, since
self.current
is a list, so you are setting
self.current[i][x]
to be a list instead of an int. So at this point:
if self.current[i][self.NUM_COLS] > self.current[j][self.NUM_COLS]:
when you try to compare those values it might happen, that you compare
an int with a list, which causes the error.
TypeError: unorderable types: list() > int()
Cheers
EDIT:
I just tried it out.
Replacing
self.current
with an int for example 2 prevents the Exception from occurring.

Categories