I've tried posting this question onto other websites and I have received, lightly to say, little to no feedback that helps.
This is the question at hand: Image Here
The code is asking to divide the numbers in a 2d array by 3, and if they're not divisible by 3, then return them to a 0 in the array.
This is the current code I have:
a = [[34,38,50,44,39],
[42,36,40,43,44],
[24,31,46,40,45],
[43,47,35,31,26],
[37,28,20,36,50]]
#print it
def PrintIt(x):
for r in range(len(x)):
for c in range(len(x[0])):
print(x[r][c], end = " ")
print("")
#is supposed to divide and return the sum. but does not
def divSUM(x):
sum = 3
for r in range(len(x)):
for c in range(len(x[0])):
sum = x[r][c] % 3
if sum != 0:
return 0
return sum
divSUM(a)
The divide (divSUM) returns as nothing. and I'm unsure if numpy would work, every time I try it says its outdated so I assume it doesn't. Any help would be nice, but I'm mainly having issues with putting the undivisble by 3 numbers to a 0.
When return is run, the function is stopped. You can append all the values to a list and return that.
Try this:
a = [[34,38,50,44,39],
[42,36,40,43,44],
[24,31,46,40,45],
[43,47,35,31,26],
[37,28,20,36,50]]
#print it
def PrintIt(x):
for r in x:
for c in r:
print(c, end = " ")
print()
def divSUM(x):
sum = 3
output = []
for r in x:
tmp_lst = []
for c in r:
sum = c % 3
if sum != 0:
tmp_list.append(0)
else:
tmp_list.append(sum)
output.append(tmp_lst)
return output
print(divSUM(a))
(What I understood is that if the number % 3 == 0 you let the same number otherwise you put 0.)
I propose to work with numpy it's easy to do it in a simple line :
import numpy as np
a = np.array([[34,38,50,44,39],
[42,36,40,43,44],
[24,31,46,40,45],
[43,47,35,31,26],
[37,28,20,36,50]])
result = np.where(a%3 ==0, a, 0)
>>>result
array([[ 0, 0, 0, 0, 39],
[42, 36, 0, 0, 0],
[24, 0, 0, 0, 45],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 36, 0]])
Otherwise, the problem with your code is that you wrongly choose the place where to put return.
So, you have to do this:
def divSUM(x):
result = []
for r in x:
tmp = []
for c in r:
if c % 3 != 0:
tmp.append(0)
else:
tmp.append(c)
result.append(tmp)
return result
Related
I'm trying to recover separately value R, G & B from a ppm file in three different matrices.
I wrote this script :
#Read file
feep_file = open("feep.ascii.ppm", "r")
def createMatrixRGB(filename):
matrixR = []
matrixG = []
matrixB = []
tableR = []
tableG = []
tableB = []
tmp = False
for lines in filename:
x = lines.split()
for y in x:
if(y == 0 and tmp == False):
tableR.append(y)
if(y == 1 and tmp == False):
tableG.append(y)
if(y == 2 and tmp == False):
tableB.append(y)
tmp = True
matrixR.append(tableR)
matrixG.append(tableG)
matrixB.append(tableB)
tableR = []
tableG = []
tableB = []
return matrixR, matrixB, matrixG
#Read lines
magic_number = feep_file.readline()
name_file = feep_file.readline()
dimension = feep_file.readline()
k = feep_file.readline()
print(magic_number)
ppm_matrix = createMatrixRGB(feep_file)
feep_file.close()
print(ppm_matrix)
The problem is that I have this result :
P3
([[]], [[]], [[]])
I don't see where I did something wrong.
Thanks for your help
The main issue is not converting strings to integers, and the usage of y as an index.
Since it's a coding practice, I am not going to just give a solution.
I will try to show you how to use the debugger to find the problem.
Place a breakpoint, run with Debug, and add x and y to the watch:
As you can see, the value of y is '0', and the type is str.
You can also evaluate expressions in the debugger Console (while debugging).
Paste the expression: y == 0 and tmp == False:
As you can see, the expression: y == 0 and tmp == False evaluates to False.
You may run a single step, and notice that the cursor doesn't step to tableR.append(y) (but skip to if(y == 1 and tmp == False)), because the condition is False.
The reason we are getting False is that y == '0', but not 0.
Now evaluate the expression after converting y to int:
int(y) == 0 and tmp == False:
As you can see int(y) == 0 is True.
After all that...
I don't think you have meant to use the value of y.
I think you meant to use the index of y in x.
[Note: Your conventions are wrong - normally y is the line, and x is the position in the line, but I kept your names].
Corrected code (at least partially corrected):
#Read file
feep_file = open("feep.ascii.ppm", "r")
def createMatrixRGB(filename):
matrixR = []
matrixG = []
matrixB = []
tableR = []
tableG = []
tableB = []
for lines in filename:
x = lines.split()
color_index = 0
for y in x:
if color_index % 3 == 0: # Use color_index modulo 3 (like counting 0, 1, 2, 0, 1, 2...)
tableR.append(int(y))
if color_index % 3 == 1:
tableG.append(int(y))
if color_index % 3 == 2:
tableB.append(int(y))
color_index += 1
matrixR.append(tableR)
matrixG.append(tableG)
matrixB.append(tableB)
tableR = []
tableG = []
tableB = []
return matrixR, matrixB, matrixG
#Read lines
magic_number = feep_file.readline()
name_file = feep_file.readline()
dimension = feep_file.readline()
k = feep_file.readline()
print(magic_number)
ppm_matrix = createMatrixRGB(feep_file)
feep_file.close()
print(ppm_matrix)
Result:
([[0, 0, 0, 15], [0, 0, 0, 0], [0, 0, 0, 0], [15, 0, 0, 0]], [[0, 0, 0, 15], [0, 7, 0, 0], [0, 0, 7, 0], [15, 0, 0, 0]], [[0, 0, 0, 0], [0, 15, 0, 0], [0, 0, 15, 0], [0, 0, 0, 0]])
I am currently creating minesweeper, and have got to the part where i have to create a function that once the player clicks on a cell that is empty, it reveals that cell and all other empty cells including the numbered cells that surround the cluster of empty cells ( come on guys, you know minesweeper :) my approach to programming this game, is to have a list of lists which contain values, 0 is empty, 1-8 is how many bombs are touching that cell, and 50 is a bomb. i call this grid. I then use this grid to map out the whole game. That grid is then hidden with a use of another list of lists, which all contain booleans. True is hidden, False is revealed. I call this boolgrid. for example when a player clicks on cell[2][10] the boolgrid[2][10] turns False, revealing that cell.
When an empty cell is selected, the surrounding cells have to be revealed, which in some cases, are also empty, so the surrounding cells of THAT cell need to be revealed, and so on. My problem is writing a function that supports that, i have tried many things, like creating a list of tuples of cell coordinates where the cell == 0, and then a new list to hold all of the new tuples which can eventually be used to turn all of the corresponding boolgrid cells to False. it doesnt work very well, is messy, unpythonic, takes up alot of memory.
I would be most grateful to anyone who can help me with a function that gives me some pythonic way of achieving this.
below is some stripped down code, which contains the bare elements. the code contains all 0's in the grid so every bool should turn False
# used to hold values to denote what the cell contains,
grid = [[0 for x in range(30)] for x in range(15)]
# used to check what cell is hidden, true is hidden, false is revealed,
booleangrid = [[True for x in range(30)] for x in range(15)]
list_to_hold_tuples = []
def find_connected_0_value_cells(cell):
i = 5 # used as an example in the real program these are whatever cell the player selects
j = 10 # as above
# this function should be given an argument of a cell that the player selected.
# reveal the surrounding cells, AND THEN take each surrounding cell, and go through
# the same process again, until every surrounding cell containing 0, and its surrounding
# cells containing zero have been revealed.
# i know i need some kind of loop, but cannot seem to build it.
# currently this function just reveals the cell and its immediate surrounding cells
if cell[i][j] == 0:
s = i, j + 1
t = i, j - 1
u = i - 1, j - 1
v = i - 1, j
w = i - 1, j + 1
x = i + 1, j - 1
y = i + 1, j
z = i + 1, j + 1
tempholding = [s, t, u, v, w, x, y, z]
for i in tempholding:
list_to_hold_tuples.append(i)
def reveal_empty_cells():
for a,b in list_to_hold_tuples:
booleangrid[a][b] = False
print(booleangrid)
find_connected_0_value_cells(grid)
reveal_empty_cells()
I have refactored and got the rest of it to work.
thanks #zettatekdev
grid = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 2, 1, 0, 0, 0, 0, 0, 0],
[1, 1, 2, 2, 0, 0, 0, 0, 0, 0],
[1, 1, 2, 3, 0, 0, 0, 0, 0, 0],
[1, 1, 2, 5, 0, 0, 0, 0, 0, 0],
[1, 1, 2, 5, 0, 0, 0, 0, 0, 0]]
list_to_hold_tuples = []
list_change_boolgrid =[]
row = 6
cell = 10
booleangrid = [[True for x in range(cell)] for x in range(row)]
def find_connected_0_value_cells(a, b):
list_to_hold_tuples.append((a, b))
if grid[a][b] == 0:
coord_list = get_surrounding_coords(a, b)
for a,b in coord_list:
if check_coord_values(a, b):
if grid[a][b] != 0:
c = a,b
if c not in list_to_hold_tuples:
list_to_hold_tuples.append(c)
else:
c = a,b
if c not in list_to_hold_tuples:
find_connected_0_value_cells(a,b)
def add_surrounding_cells():
extra_coord = True
for a,b in list_to_hold_tuples:
if grid[a][b] == 0:
coord_list = get_surrounding_coords(a,b, extra_coord)
for i in coord_list:
if i not in list_change_boolgrid:
list_change_boolgrid.append(i)
else:
c = a,b
if c not in list_change_boolgrid:
list_change_boolgrid.append(c)
def reveal_empty_cells():
global booleangrid
for a, b in list_change_boolgrid:
if check_coord_values(a,b):
booleangrid[a][b] = False
def check_coord_values(a,b):
if a == -1 or a >= row:
return False
if b == -1 or b >= cell:
return False
else:
return True
def get_surrounding_coords(a, b, *extra_coord):
c = (a, b + 1)
d = (a, b - 1)
e = (a - 1, b - 1)
f = (a - 1, b)
g = (a - 1, b + 1)
h = (a + 1, b - 1)
i = (a + 1, b)
j = (a + 1, b + 1)
if extra_coord:
k = (a, b)
return [c, d, e, f, g, h, i, j, k]
return [c, d, e, f, g, h, i, j]
find_connected_0_value_cells(3,5)
add_surrounding_cells()
reveal_empty_cells()
print(booleangrid)
Ok, so I worked with your code for a bit, and I was able to make a code that works. I did adjust the grid size just to make it easier to figure out, but it should work for your original size. Just make sure you don't test with a grid of all 0s like in your posted code because it will return an error for too many recursions. Here's the code.
EDIT: I changed the code so now it reveals the surrounding numbers as well
# used to hold values to denote what the cell contains,
grid = [[0,1,2,5,4,6,0,0,0,0],
[0,1,2,5,4,6,0,0,0,0],
[0,1,2,5,4,6,0,0,5,0],
[0,1,2,5,4,6,0,0,0,0],
[0,1,2,5,4,6,0,0,0,0],
[0,1,2,5,4,6,6,0,0,0]]
# used to check what cell is hidden, true is hidden, false is revealed,
booleangrid = [[True for x in range(10)] for x in range(6)]
list_to_hold_tuples = []
def find_connected_0_value_cells(i,j):
list_to_hold_tuples.append((i,j))
if grid[i][j] == 0:
s = (i, j + 1)
t = (i, j - 1)
u = (i - 1, j - 1)
v = (i - 1, j)
w = (i - 1, j + 1)
x = (i + 1, j - 1)
y = (i + 1, j)
z = (i + 1, j + 1)
tempholding = [s, t, u, v, w, x, y, z]
for a in tempholding:
if a[0]>=0 and a[1]>=0 and a[0]<=len(grid)-1 and a[1]<=len(grid[i])-1 and grid[a[0]][a[1]]==0:
if (a[0]!=i and a[1]!=j) and (a not in list_to_hold_tuples):
find_connected_0_value_cells(a[0],a[1])
list_to_hold_tuples.append(a)
elif a[0]>=0 and a[1]>=0 and a[0]<=len(grid)-1 and a[1]<=len(grid[i])-1:
list_to_hold_tuples.append(a) #this part adds surrounding non-zero numbers
def reveal_empty_cells():
global booleangrid
for a,b in list_to_hold_tuples:
if a>=0 and a<len(booleangrid) and b>=0 and b<len(booleangrid[a]):
booleangrid[a][b] = False
for i in booleangrid:
print(i)
find_connected_0_value_cells(5,8)#Just using coordinates of 5,8 for testing, this would be click spot
reveal_empty_cells()
I have made a function which takes a list as an input and returns a list too.
e.g. input is [4,6,8,10,12]
and output should be [0,0,1,0,0]
because 8 belongs in fibonacci series
my code is
for i in input1:
phi=0.5+0.5*math.sqrt(5.0)
a=phi*i
out =[ i == 0 or abs(round(a) - a) < 1.0 / i];
return out;
This will work:
input1 = [4,6,8,10,12]
out=[]
for i in input1:
phi=0.5+0.5*math.sqrt(5.0)
a=phi*i
out.append(i == 0 or abs(round(a) - a) < 1.0 / i);
To convert bool to int
import numpy
y=numpy.array(out)
new_output = y*1
I would think that the best way is probably to write a function called is_fibonacci, which takes a numerical input and returns True if the input is a fibonacci number, otherwise False. Then you can just do a list comprehension on your initial list input1: return [1 if is_fibonacci(num) else 0 for num in input1]. (Of course, is_fibonacci could automatically return 1 or 0 instead of a Boolean, in which case the list comprehension is even simpler.)
Writing the is_fibonacci function is an interesting exercise that I will leave to you :) (But happy to help if you are struggling with it.)
This should solve I guess
import math
# A function that returns true if x is perfect square
def isPerfectSquare(x):
s = int(math.sqrt(x))
return s * s == x
# Returns true if n is a Fibinacci Number, else false
def isFibonacci(n):
return isPerfectSquare(5 * n * n + 4) or isPerfectSquare(5 * n * n - 4)
i = [4, 6, 8, 10, 12]
print(i)
j = []
# A utility function to test above functions
for item in i:
if (isFibonacci(item) == True):
j.append(1)
else:
j.append(0)
print(j)
Output:
[4, 6, 8, 10, 12]
[0, 0, 1, 0, 0]
This does what you want
def isFibonaccy(inputList):
out = []
for i in inputList:
phi = 0.5 + 0.5 * math.sqrt(5.0)
a = phi * i
out.append(int(i == 0 or abs(round(a) - a) < 1.0 / i))
return out
print(isFibonaccy([4, 6, 8, 10, 12])) # -> [0, 0, 1, 0, 0]
This function is intended to recursively navigate a maze and find the length of the shortest path. The path itself is not necessary, only the length. The maze is represented by a 2d list with values such as
0 1 0 0 0
0 0 0 1 0
0 0 0 1 0
The user starts at (0,0) and must end up at the end of the maze as defined (in my case it is the bottom right cell). 1's represent walls.
def maze(x,y,array,length):
m = len(array)
n = len(array[0])
if x < 0 or y < 0 or x == m or y == n or array[x][y] == 1:
return float("inf")
elif x == m - 1 and y == n - 1:
return length
else:
array[x][y] = 1
up = maze(x - 1,y,array,length + 1)
right = maze(x,y + 1,array,length + 1)
down = maze(x + 1,y,array,length + 1)
left = maze(x,y - 1,array,length + 1)
return min(up,down,left,right)
array = [[0,1,0,0,0],[0,0,0,1,0],[0,0,0,1,0]]
minLength = maze(0,0,array,1)
print(minLength)
I designed it so that it recursively finds all possible paths from each direction (up, down, left and right), and returns the lowest value from all these paths with each step of the way. It returns inf for any path that is not valid.
For this specific array, it returns 11, which is false, it should be 9. I do not believe it is merely a mathematical error, as I tried printing each step of the way and it is not recognizing certain paths (it returns inf for paths that most definitely have options).
I can't seem to find where my code is going wrong, it seems like it should properly return the value, but in practice it does not.
array is a reference to the original array, not a local copy. See any of the on-line tutorials on how Python passes function arguments, or how it handles lists. You can see the effect by printing array in your main program after the call to maze:
Final Maze [
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 0]
]
Fixing this is relatively easy: copy the nested list and use that copy locally.
from copy import deepcopy
def maze(x,y,array,length):
m = len(array)
n = len(array[0])
if x < 0 or y < 0 or x == m or y == n or array[x][y] == 1:
return float("inf")
elif x == m - 1 and y == n - 1:
return length
else:
new_maze = deepcopy(array)
new_maze[x][y] = 1
up = maze(x - 1,y,new_maze,length + 1)
right = maze(x,y + 1,new_maze,length + 1)
down = maze(x + 1,y,new_maze,length + 1)
left = maze(x,y - 1,new_maze,length + 1)
return min(up,down,left,right)
array = [[0,1,0,0,0],[0,0,0,1,0],[0,0,0,1,0]]
minLength = maze(0,0,array,1)
print("Final Maze", array)
print(minLength)
The output from this is (edited for readability again)
Final Maze [
[0, 1, 0, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 1, 0]
]
9
I need help to do the combination of nested loop output from two iteration.
This is my nested while code:
iteration=0
while (iteration < 2):
count = 0
bit=5
numbers = []
while (count < bit):
Zero = 0
One = 1
IV=(random.choice([Zero, One]))
numbers.append(IV)
count= count + 1
print ('List of bit:', numbers)
iteration=iteration + 1
print ("End of iteration",iteration)
And this is the result:
List of bit: [1, 0, 1, 1, 0]
End of iteration 1
List of bit: [1, 0, 0, 1, 1]
End of iteration 2
However, I would like to combine the result of the loop. Supposedly, the result may produce something like this:
Combination of bit:[1, 0, 1, 1, 0 ,1 , 0, 0, 1, 1]
Hopefully someone may help me to do this.
Thank you so much.
This code should definitely be reorganized, but here is the solution.
from itertools import chain
# list for appending results
combined = []
iteration=0
while (iteration < 2):
count = 0
bit=5
numbers = []
while (count < bit):
Zero = 0
One = 1
IV=(random.choice([Zero, One]))
numbers.append(IV)
count= count + 1
print ('List of bit:', numbers)
iteration=iteration + 1
print ("End of iteration",iteration)
# append the result
combined.append(numbers)
# print the combined list
print(list(chain.from_iterable(combined)))
Output
[1, 0, 1, 1, 0 ,1 , 0, 0, 1, 1]
Simply initialize numbers outside the loop, instead of clearing it for every iteration, so that your results can keep appending to numbers.
iteration=0
numbers = []
while (iteration < 2):
count = 0
bit=5
while (count < bit):
Zero = 0
One = 1
IV=(random.choice([Zero, One]))
numbers.append(IV)
count= count + 1
print ('List of bit:', numbers)
iteration=iteration + 1
print ("End of iteration",iteration)
Given that the code simply creates a list of 10 random binary values, the code seems extremely complex. You could get the same effect with the following:
>>> import random
>>> [random.choice([0,1]) for _ in range(10)]
[0, 0, 0, 0, 1, 0, 1, 0, 1, 1]
However, as the code stands the list of values produced each iteration is thrown away at the start of the next iteration by the line numbers = [].
Either move this before the initial while statement, or create a separate list outside the while statement and append each iteration to it.
This latter approach (with minimal changes to your code) would look like this:
iteration=0
all_numbers = [] # List to hold complete set of results
while (iteration < 2):
count = 0
bit=5
numbers = []
while (count < bit):
Zero = 0
One = 1
IV=(random.choice([Zero, One]))
numbers.append(IV)
count= count + 1
print ('List of bit:', numbers)
iteration=iteration + 1
print ("End of iteration",iteration)
all_numbers.extend(numbers) # Add the iteration to the complete list
print ('Complete list', all_numbers) # Show the aggregate result
your numbers variable is being re-initialized in the outer loop.
Other answers already pointed where your error was, but really that's WAY too much code for such a simple thing. The pythonic way is a much simpler and more readable one-liner:
numbers = [random.randint(0,1) for i in range(10)]