I'm trying to make a minesweeper game through text in python. This error comes up when I try to draw the little numbers. Maybe the way I'm doing this is inefficient, but I don't understand why it throws this error. I've been trying to fiddle with the code, but nothing seems to work. Does anyone have any idea for why it's not working?
import random
minenum = 12
gridsize = 10
grid = [[0] * gridsize for _ in range(gridsize)]
def setup():
global grid
global minecount
for i in range(minenum):
x = random.randrange(0,10)
y = random.randrange(0,10)
grid[y][x] = "m"
xpos = 0
ypos = 0
for n in range(10):
for z in range(10):
count = 0
try:
if grid[ypos + 1][xpos] == "m":
count += 1
except:
pass
try:
if grid[ypos + 1][xpos + 1] == "m":
count += 1
except:
pass
try:
if grid[ypos + 1][xpos - 1] == "m":
count += 1
except:
pass
try:
if grid[ypos - 1][xpos + 1] == "m":
count += 1
except:
pass
try:
if grid[ypos - 1][xpos - 1] == "m":
count += 1
except:
pass
try:
if grid[ypos - 1][xpos] == "m":
count += 1
except:
pass
try:
if grid[ypos][xpos + 1] == "m":
count += 1
except:
pass
try:
if grid[ypos][xpos - 1] == "m":
count += 1
except:
pass
grid[ypos][xpos] = count
xpos += 1
ypos += 1
def printBoard():
for i in range(10):
print(' '.join(str(v) for v in grid[i]))
setup()
printBoard()
[Edit]
here is the error:
Traceback (most recent call last):
File "main.py", line 74, in <module>
setup()
File "main.py", line 63, in setup
grid[ypos][xpos] = count
IndexError: list assignment index out of range
If you add a print(count) before the grid[ypos][xpos] = count you will see that you have 11 instances of count but grid is only 10 so that's why.
You add to the ypos and xpos even when it's at max, a quick fix below but can be better:
print(count)
grid[ypos][xpos] = count
if xpos < gridsize - 1:
xpos += 1
if ypos < gridsize - 1:
ypos += 1
Your code was not working because you never reset xpos when you incremented your ypos so your indexes looked like this (for gridsize = 4):
0 0
1 0
2 0
3 0
4 1
5 1
6 1
7 1
8 2
Instead of what you inteded, i.e.
0 0
1 0
2 0
3 0
0 1
1 1
2 1
3 1
0 2
You should have added xpos = 0 whenever you do ypos += 1
xpos += 1
ypos += 1
xpos = 0
Your code could also use a bit of cleanup:
import random
def setup(minecount, gridsize):
grid = [[0] * gridsize for _ in range(gridsize)]
for _ in range(minecount):
x = random.randrange(0,gridsize)
y = random.randrange(0,gridsize)
grid[y][x] = "m"
for xpos in range(gridsize):
for ypos in range(gridsize):
count = 0
if ypos + 1 < 10 and grid[ypos + 1][xpos] == "m":
count += 1
if ypos + 1 < 10 and xpos +1 < 10 and grid[ypos + 1][xpos + 1] == "m":
count += 1
if ypos + 1 < 10 and xpos - 1 >= 0 and grid[ypos + 1][xpos - 1] == "m":
count += 1
if ypos - 1 >= 0 and xpos + 1 < 10 and grid[ypos - 1][xpos + 1] == "m":
count += 1
if ypos - 1 >= 0 and xpos -1 >= 10 and grid[ypos - 1][xpos - 1] == "m":
count += 1
if ypos - 1 >= 0 and grid[ypos - 1][xpos] == "m":
count += 1
if xpos + 1 < 10 and grid[ypos][xpos + 1] == "m":
count += 1
if xpos - 1 >= 0 and grid[ypos][xpos - 1] == "m":
count += 1
grid[ypos][xpos] = count
return grid
def printBoard(grid):
for i in range(10):
print(' '.join(str(v) for v in grid[i]))
minecount = 12
gridsize = 10
grid = setup(minecount, gridsize)
printBoard(grid)
Didn't even have to change the logic, just switched magic numbers to proper parameters. You are also overwriting all your "m" cells when counting neighbouring bombs, you might want to avoid that.
You have to assign zero to xpos in the end of setup() function:
ypos += 1
xpos = 0
So ...
Am writing a code that makes a Matrix table then calculate how many ( uppercase Letter , Lowercase Letter , Numbers , Symbols )
That's the code i tried :
def Proc_Affiche(T,P,X):
Nb_Maj = 0
Nb_Min = 0
Nb_chiffre = 0
Nb_symbole = 0
for i in range(P):
for j in range(X):
if T[i] in ["A","Z"]:
Nb_Maj = Nb_Maj + 1
elif T[i] in ["a","z"] :
Nb_Min = Nb_Min + 1
elif T[i] in range(1,9):
Nb_chiffre = Nb_chiffre + 1
else :
Nb_symbole = Nb_symbole + 1
print("Nb_Maj= ",Nb_Maj)
print("Nb_Min= ",Nb_Min)
print("Nb_chiffre= ",Nb_chiffre)
print("Nb_symbole= ",Nb_symbole)
So the Output should be like that :
Nb_Maj= ...
Nb_Min= ...
Nb_chiffre= ...
Nb_symbole= ...
The Problem is on the part of intervals Like ["A","Z"]
Strings have some functions you can use to check what they contain
.isalpha() is true for letters
.isnumeric() is true for numbers
.isalnum() is true for letters and numbers
.isupper() is true for uppercase
Thus you could do something like
if T[i].isalpha():
if T[i].isupper():
Nb_Maj += 1
else:
Nb_Min += 1
elif T[i].isnumeric():
Nb_chiffre += 1
else:
Nb_symbole += 1
Yes it is , here is the whlole code if that would help :
from math import*
def Proc_saisie():
X = -1
while X < 1 or X > 20 :
X = int(input("Donner un entier entre 5 et 20 : "))
return X
def Proc_Remplir(P,X):
T= [[] for i in range(P)]
for i in range(P):
for j in range(X):
d = input("T["+str(i)+","+str(j)+"]=")
T[i].append(d)
return T
def Proc_Affiche(T,P,X):
Nb_Maj = 0
Nb_Min = 0
Nb_chiffre = 0
Nb_symbole = 0
for i in range(P):
for j in range(X):
if T[i] in ["A","Z"]:
Nb_Maj = Nb_Maj + 1
elif T[i] in ["a","z"] :
Nb_Min = Nb_Min + 1
elif T[i] in range(1,9):
Nb_chiffre = Nb_chiffre + 1
else :
Nb_symbole = Nb_symbole + 1
print("Nb_Maj= ",Nb_Maj)
print("Nb_Min= ",Nb_Min)
print("Nb_chiffre= ",Nb_chiffre)
print("Nb_symbole= ",Nb_symbole)
#---------------------------
L = Proc_saisie()
C = Proc_saisie()
print("L =",L)
print("C =",C)
TAB = []
TAB = Proc_Remplir(L,C)
TAB = Proc_Affiche(TAB,L,C)
I'm not sure I understand what you want 100%, but I think something like follows would fit:
def Proc_Affiche(T,P,X):
Nb_Maj = 0
Nb_Min = 0
Nb_chiffre = 0
Nb_symbole = 0
for i in range(P):
for j in range(X):
if "A" <= T[i][j] <= "Z":
Nb_Maj = Nb_Maj + 1
elif "a" <= T[i][j] <= "z" :
Nb_Min = Nb_Min + 1
elif 1 <= T[i][j] <= 9:
Nb_chiffre = Nb_chiffre + 1
else :
Nb_symbole = Nb_symbole + 1
print("Nb_Maj= ",Nb_Maj)
print("Nb_Min= ",Nb_Min)
print("Nb_chiffre= ",Nb_chiffre)
print("Nb_symbole= ",Nb_symbole)
I am programming a vehicle routing problem in Python with PuLP. I got all my code in it, but for some reason I get a negative value for one of my decision variables, even though I restricted all of them to be nonnegative.
My code is as follows (Traveltimes is a two dimensional np array, with travel times between each pair of customers (i,j), where c(i,j) = c(j,i) and c(i,i) = 0.):
My code:
numVehicles = 2
numCustomers = 2
prob = LpProblem("DSP", LpMinimize)
var = [[[0 for k in range(numVehicles)] for j in range(numCustomers+1)] for i in range(numCustomers+1)]
for i in range(numCustomers+1):
for j in range(numCustomers+1):
for k in range(numVehicles):
var[i][j][k] = LpVariable("x"+str(i)+","+str(j)+","+str(k), 0,1, cat='Binary')
# ADD OBJECTIVE
obj = ""
for i in range(numCustomers+1):
for j in range(numCustomers+1):
for k in range(numVehicles):
obj += traveltimes[i][j]*var[i][j][k]
prob += obj
# ADD CONSTRAINTS
# All customers visited
for j in range(numCustomers+1):
for k in range(numVehicles):
nr = ""
for i in range(numCustomers+1):
nr += var[i][j][k]
prob += nr == 1
# Enter each customer exactly once
for i in range(numCustomers+1):
nr = ""
for k in range(numVehicles):
for j in range(1, numCustomers+1):
nr += var[i][j][k]
prob += nr == 1
# Leave each customer exactly once
for j in range(numCustomers+1):
nr = ""
for k in range(numVehicles):
for i in range(1, numCustomers+1):
nr += var[i][j][k]
prob += nr == 1
# Per vehicle only one customer can be visited as first
nrFirst = ""
for k in range(numVehicles):
for j in range(numCustomers+1):
nrFirst += var[0][j][k]
prob += nrFirst <= 1
# Max num vehicles
nrOut = ""
for k in range(numVehicles):
for j in range(numCustomers+1):
nrOut += var[0][j][k]
prob += nrOut <= numVehicles
# Restrict x(0,j,k) to be nonpositive
for j in range(numCustomers+1):
for k in range(numVehicles):
prob += var[0][j][k] >= 0
print(prob)
# Solve LP
prob.solve()
for v in prob.variables():
print(v.name, "=", v.varValue)
print("objective=", value(prob.objective))
The first output is the formulation printed
MINIMIZE
1.731*x0,1,0 + 1.731*x0,1,1 + 2.983*x0,2,0 + 2.983*x0,2,1 + 1.731*x1,0,0 + 1.731*x1,0,1 + 9.375*x1,2,0 + 9.375*x1,2,1 + 2.983*x2,0,0 + 2.983*x2,0,1 + 9.375*x2,1,0 + 9.375*x2,1,1 + 0.0
SUBJECT TO
_C1: x0,0,0 + x1,0,0 + x2,0,0 = 1
_C2: x0,0,1 + x1,0,1 + x2,0,1 = 1
_C3: x0,1,0 + x1,1,0 + x2,1,0 = 1
_C4: x0,1,1 + x1,1,1 + x2,1,1 = 1
_C5: x0,2,0 + x1,2,0 + x2,2,0 = 1
_C6: x0,2,1 + x1,2,1 + x2,2,1 = 1
_C7: x0,1,0 + x0,1,1 + x0,2,0 + x0,2,1 <= 1
_C8: x1,1,0 + x1,1,1 + x1,2,0 + x1,2,1 <= 1
_C9: x2,1,0 + x2,1,1 + x2,2,0 + x2,2,1 <= 1
_C10: x0,0,0 + x0,1,0 + x0,2,0 <= 1
_C11: x0,0,0 + x0,0,1 + x0,1,0 + x0,1,1 + x0,2,0 + x0,2,1 <= 1
VARIABLES
0 <= x0,0,0 <= 1 Integer
0 <= x0,0,1 <= 1 Integer
0 <= x0,1,0 <= 1 Integer
0 <= x0,1,1 <= 1 Integer
0 <= x0,2,0 <= 1 Integer
0 <= x0,2,1 <= 1 Integer
0 <= x1,0,0 <= 1 Integer
0 <= x1,0,1 <= 1 Integer
0 <= x1,1,0 <= 1 Integer
0 <= x1,1,1 <= 1 Integer
0 <= x1,2,0 <= 1 Integer
0 <= x1,2,1 <= 1 Integer
0 <= x2,0,0 <= 1 Integer
0 <= x2,0,1 <= 1 Integer
0 <= x2,1,0 <= 1 Integer
0 <= x2,1,1 <= 1 Integer
0 <= x2,2,0 <= 1 Integer
0 <= x2,2,1 <= 1 Integer
It can clearly be observed that all variables are restricted to be an integer between 0 and 1 (thus binary). However, for some reason, I do get negative values for some variable(s), as can be seen below
x0,0,0 = 0.0
x0,0,1 = -1.0
x0,1,0 = 0.0
x0,1,1 = 1.0
x0,2,0 = 0.0
x0,2,1 = 1.0
x1,0,0 = 1.0
x1,0,1 = 1.0
x1,1,0 = 1.0
x1,1,1 = 0.0
x1,2,0 = 0.0
x1,2,1 = 0.0
x2,0,0 = 0.0
x2,0,1 = 1.0
x2,1,0 = 0.0
x2,1,1 = 0.0
x2,2,0 = 1.0
x2,2,1 = 0.0
objective= 11.159
Really looking forward to any suggestions on how to solve this problem, since I clearly do not want negative values!
As a few others have suggested you should write a Minimum Complete and Verifiable Example.
That said, if you are getting constraints violated, and you are sure you've implemented them correctly, I reckon you have an infeasible problem (i.e. if you looked at your constraints carefully you would find there is a combination which makes solving impossible).
To check this add:
print (("Status:"), LpStatus[prob.status])
Just after you do prob.solve(). I reckon you'll find it's infeasible.
prob += nr == 1
"+=" is for assignment
"==" is checking for equivalence, and belongs in an "if" statement or a "while".
For instance:
if prob + nr == 1: #execute what follows if prob + nr is equal to 1
I have a pandas dataframe which contains a list of error values. I want to find the proportion of my errors in certain ranges e.g. what percentage of my error is within +-1%, +-5%, +-10%, +-20% and +-50% etc. A histogram of my data is shown below:
So far I have looked at functions such as pd.cut() and plt.hist() but no libraries seem to give me the answer where my ranges overlap each other so I'm having to resort to a very long custom made function - which is below:
def error_distribution(df):
total_length = len(df.index)
one_perc = five_perc = ten_perc = fifteen_perc = twenty_perc = thirty_perc \
= fourty_perc = fifty_perc = over_fifty = 0
for index, row in df.iterrows():
value = abs(row['Errors'])
if value <= 0.01:
one_perc += 1
five_perc += 1
ten_perc += 1
fifteen_perc += 1
twenty_perc += 1
thirty_perc += 1
fourty_perc += 1
fifty_perc += 1
elif value <= 0.05:
five_perc += 1
ten_perc += 1
fifteen_perc += 1
twenty_perc += 1
thirty_perc += 1
fourty_perc += 1
fifty_perc += 1
elif value <= 0.1:
ten_perc += 1
fifteen_perc += 1
twenty_perc += 1
thirty_perc += 1
fourty_perc += 1
fifty_perc += 1
elif value <= 0.15:
fifteen_perc += 1
twenty_perc += 1
thirty_perc += 1
fourty_perc += 1
fifty_perc += 1
elif value <= 0.2:
twenty_perc += 1
thirty_perc += 1
fourty_perc += 1
fifty_perc += 1
elif value <= 0.3:
thirty_perc += 1
fourty_perc += 1
fifty_perc += 1
elif value <= 0.4:
fourty_perc += 1
fifty_perc += 1
elif value <= 0.5:
fifty_perc += 1
else:
over_fifty += 1
print("Sub 1%: {0:.2f}%".format(one_perc/total_length*100))
print("Sub 5%: {0:.2f}%".format(five_perc/total_length*100))
print("Sub 10%: {0:.2f}%".format(ten_perc/total_length*100))
print("Sub 15%: {0:.2f}%".format(fifteen_perc/total_length*100))
print("Sub 20%: {0:.2f}%".format(twenty_perc/total_length*100))
print("Sub 30%: {0:.2f}%".format(thirty_perc/total_length*100))
print("Sub 40%: {0:.2f}%".format(fourty_perc/total_length*100))
print("Sub 50%: {0:.2f}%".format(fifty_perc/total_length*100))
print("Over 50%: {0:.2f}%".format(over_fifty/total_length*100))
And the output I'm looking for is this:
error_distribution(error_dataset1)
Output:
Sub 1%: 16.55%
Sub 5%: 56.61%
Sub 10%: 71.62%
Sub 15%: 78.53%
Sub 20%: 82.97%
Sub 30%: 88.46%
Sub 40%: 91.09%
Sub 50%: 92.59%
Over 50%: 7.41%
Does anyone know of a standard library that could do this?
Can you try the following:
import numpy as np
arr = np.random.uniform(low=0, high=100, size=(200,))
count, division = np.histogram(arr, bins=[0, .01, 0.05, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 1])
print(count, division)