I could really use some help with understanding where I am going wrong with 2d list comprehension. I have spent hours and the finer points of why its not working out continues to elude me.
The following code is a very basic Lights out game that takes an input
runGenerations2d([0,1,1,0],[1,0,1,0],[1,0,1,0])
Sets up a game board N x N
with a click it needs to change the value of the clicked box.
I believe the problem is
setNewElement
is taking x,y data and the rest of my functions haven't a clue what to do with the values passed on
import time # provides time.sleep(0.5)
from csplot import choice
from random import * # provides choice( [0,1] ), etc.
import sys # larger recursive stack
sys.setrecursionlimit(100000) # 100,000 deep
def runGenerations2d(L , x = 0,y=0):
show(L)
print( L ) # display the list, L
time.sleep(.1) # pause a bit
newL = evolve2d( L ) # evolve L into newL
print(newL)
if min(L) == 1:
#I like read outs to be explained so I added an extra print command.
if x<=1: # Takes into account the possibility of a 1 click completition.
print ('BaseCase Reached!... it took %i click to complete' % (x))
print (x)
done()#removes the need to input done() into the shell
else:
print ('BaseCase Reached!... it took %i clicks to complete' % (x))
print (x)
done()#removes the need to input done() into the shell
return
x = x+1 # add 1 to x before every recusion
runGenerations2d( newL , x,y ) # recurse
def evolve2d( L ):
N = len(L) # N now holds the size of the list L
x,y = sqinput2() # Get 2D mouse input from the user
print(x,y) #confirm the location clicked
return [ setNewElement2d( L, i,x,y ) for i in range(N) ]
def setNewElement2d( L, i, x=0,y=0 ):
if i == (x,y): # if it's the user's chosen column,
if L[i]==1: # if the cell is already one
return L[i]-1 # make it 0
else: # else the cell must be 0
return L[i]+1 # so make it 1
The error after a click
[None, None, None, None]
[None, None, None, None]
The data does not seem 2d.
Try using sqinput instead.
setNewElement2d returns a single number but the calling code is expecting two numbers.
This line
return [ setNewElement2d( L, i,x,y ) for i in range(N) ]
Is setting i to 0, then 1, then 2, ... then N-1. These are single numbers.
You then compare the single numbers to two numbers on this line:
if i == (x,y):
You seem to be assuming i is an x,y pair but it isn't.
Here's how to create every x-y pair for a 3x3 grid:
# Makes (0,0),(0,1)...(2,2)
[(x,y) for x in range(3) for y in range(3)]
I think this code is closer to what you want, still might need changing:
def evolve2d( L ):
N = len(L)
x,y = sqinput2()
print(x,y)
return [setNewElement2d(L, xx, yy, x, y) for xx in range(N) for yy in range(N)]
def setNewElement2d( L, xx, yy, x=0,y=0 ):
if (xx,yy) == (x,y): # if it's the user's chosen row and column
# If it's already 1 return 0 else return 1
return 0 if L[xx][yy]==1 else 1
Related
So, I know that is super simple, but I don't have idea how to found the answer in google :<
It would be grate if you could tell me how I can optimalize this, or just let me know how this type of list is called.
The function takes one argument "n" and return list of numbers from 1 to "n" and every number appends "n" times
def my_function(n):
x = []
y = 1
for i in range(n):
for j in range(n):
x.append(y)
y += 1
return x
my_function(3)
Should return : [1,1,1,2,2,2,3,3,3]
Here's one simple way with no extra libraries involved:
def my_function(n):
# returns array from 1 to n+1 (e.g. if n=3, x=[1,2,3])
x = list(range(1, n+1))
# create a new array with every element of x repeated n times
# Returns x = [1,2,3,1,2,3,1,2,3]
x = x * n
# Sort all elements of x to group them
# Returns x = [1,1,1,2,2,2,3,3,3]
x.sort()
return x
my_function(3)
With no comments/combined, it would just be:
def my_function(n):
x = list(range(1, n+1))* n
x.sort()
return x
You mean smaller like this?
def foo(n):
result = []
for i in range(1, n + 1):
result += ([i]*n)
return result
foo(3)
One liner pythonic way:
def foo(n):
return [i for i in range(1, n+1) for _ in range(n)]
foo(3)
I created this code so that the program will print out all numbers within range (1000 to 10,000) if it is divisible by value k, as set below, but the ouput yields none.. what am I doing wrong?
k = 6
def pincode(k: int):
for x in range(1000,10000):
if x // k == 0:
print(x)
print(pincode(k))
what am I supposed to change to make sure that the code prints out all numbers within the range divisible by k?
There are two bugs, here for printing the function, you need to return value. If you've written print already then just call the function. If you want to print k for x%k==0 then x has multiple values. You can return multiple values by collecting x values to list. The second one is, it is x%k==0 and not x//k==0. // gives you whole number quotient and % will give you remainder. Eg, 49//7 is 7 and 49%7 is 0 and 26//7 is 3 and 26%7 is 5. Your new code:
k = 6
def pincode(k: int):
collect=[]
for x in range(1000,10000):
if x % k == 0:
collect.append(x)
return collect
print(pincode(k))
You can use a single comprehension for such a task.
k = 6
print([x for x in range(1000, 10000) if x % k == 0])
I think you should try changing the // in if x // k == 0: to % which is an operator that returns the remainder instead of the quotient.
Your function pincode(k) doesn't have a return argument, so it returns none. Append the values to a list, then add that list to the return argument.
k = 6
def pincode(k: int):
a = [] #empty list
for x in range(1000,10000):
if x % k == 0: # use % instead of //
a.append(x) # append x to list
return a #return the list
print(pincode(k))
The double forward slash in Python is known as the integer division operator. Essentially, it will divide the left by the right, and only keep the whole number component.
I would suggest to use % to find if the number is divisible.
k = 6
def pincode(k: int):
for x in range(1000,10000):
#print(f"x and k {x} and {k} res {x%k}")
if x % k == 0:
print(x)
print(pincode(k))
Partial Digest Problem is one of the algorithms for getting the places of cut in DNA. Given all the possible lengths of cut, for example [2,2,3,3,4,5,6,7,8,10] I have to figure out a way to find the actual places of cut. In this example total length of the DNA is 10, and the places of actual cut are [0,3,6,8,10].
From the algorithm above, I'm trying to build the actual code in python, and with hand I'm not sure what I've done wrong.
The desired output for this code is
[0,3,6,8,10]
where I'm only getting
"None"
Can anyone please tell me what part in my code is wrong?
# function to remove multiple elements given as list
def delete(elements,A):
for el in elements:
A.remove(el)
return A
# y is given as integer, X as list
def delta(y,X):
n = len(X)
for i in range(n):
X[i] -= y
X[i] = abs(X[i])
return sorted(X)
# If former contains latter, return true. Else, return false
def contains(small, big):
for i in range(len(big)-len(small)+1):
for j in range(len(small)):
if big[i+j] != small[j]:
break
else:
return True
return False
def partialDigest(L):
global width
width = (max(L))
delete([width], L) # Needs to be in list to feed to 'delete' function
X = [0, width]
X = place(L,X)
return X
def place(L,X):
if len(L) == 0: # Baseline condition
return X
y = max(L)
if contains(delta(y,X),L): # If former is the subset of L
delete(delta(y,X), L) # Remove lengths from L
X += list(y) # assert that this y is one of the fixed points, X
X = sorted(X) # To maintain order
print(X)
place(L,X) # Recursive call of the function to redo the upper part
# If none of the if statements match the condition, continue
X.remove(y) # If the code reaches down here, it means the assumption that
# y is one of the points is wrong. Thus undo
L += delta(y,X) # undo L
L = sorted(L) # To maintain order
# Do the same thing except this time it's (width-y)
elif contains(delta(width-y,X),L):
delete(delta(width-y,X), L)
X += list(width - y)
X = sorted(X)
place(L,X)
X.remove(width-y)
L += delta(y,X)
L = sorted(L)
L = [2,2,3,3,4,5,6,7,8,10]
X = partialDigest(L)
print(X)
I have made a game where a board of randomly lit squares are generated (0 is off and 1 is on) and the goal is to light up the entire board. Currently I have been using user input to win the game where when a square is clicked it inverts as well as its neighbors above, bellow, left, and right. Now I am trying to allow the computer to solve the game without user input, but my choice function in evolve2d does not work correctly. Currently it is producing the original list over and over again. Any guidance would be greatly appreciated.
import time # provides time.sleep(0.5)
from csplot import choice
from random import * # provides choice( [0,1] ), etc.
import sys # larger recursive stack
sys.setrecursionlimit(100000) # 100,000 deep
def runGenerations2d(L , x = 0,y=0):
show(L)
print( L ) # display the list, L
time.sleep(.1) # pause a bit
newL = evolve2d( L ) # evolve L into newL
print(newL)
if min(L) == 1:
#I like read outs to be explained so I added an extra print command.
if x<=1: # Takes into account the possibility of a 1 click completition.
print ('BaseCase Reached!... it took %i click to complete' % (x))
print (x)
done()#removes the need to input done() into the shell
else:
print ('BaseCase Reached!... it took %i clicks to complete' % (x))
print (x)
done()#removes the need to input done() into the shell
return
x = x+1 # add 1 to x before every recusion
runGenerations2d( newL , x,y ) # recurse
def setNewElement2d( L, i, j, x=0, y=0 ):
if y==j and (i == x-1 or i == x+1 or i ==x):
return 1-L[j][i]
elif x==i and (j == y-1 or j == y+1):
return 1-L[j][i]
else:
return L[j][i]
def evolve2d( L ):
N = len(L) # N now holds the size of the list
x = choice (L)
y = choice (L)
return [[ setNewElement2d( L, i, j,x,y ) for i in range(N)]for j in range(N) ]
Here is my code:
s = 'Hello world'
c = ['a','b','c','d','e','f']
n = ['1','2','3','4','5','6']
l = [random.choice(c),random.choice(n)]
return ''.join('%s%s' % (x, random.choice(l) if random.random() > 0.5 else '') for x in s)
This will output:
He5lloe w5o5rl5de
But what I am aiming for is something like this code would produce:
s = 'Hello world'
n = ['1','2','3','4','5','6']
return ''.join('%s%s' % (x, random.choice(n) if random.random() > 0.5 else '') for x in s)
Which is:
H4e3l3l6o wo4r3ld
It would be great if someone could also explain as to why the two are reacting differently than I would have assumed.
Sorry, I should have stated my intentions. I would like to randomly select an element from the two lists through each iteration of the for loop within join. Instead what I have is 2 elements being selected once and randomly choosing between the two elements selected.
This is what I don't want:
n = [1,2,3,4,5]
s = ['!','-','=','~','|']
l = [random.choice(n), random.choice(s)] # 1,!
# He1l!lo W!or1l!d
This is what I want:
n = [1,2,3,4,5] # 1 or 2 or 3... etc.
s = ['!','-','=','~','|'] # ! or - or =... etc.
> code to randomly select a list and a new element from that list
# He4ll-o W!or3l~d
Not sure if I have worded myself correctly, but hopefully it is understandable,
By doing l = [random.choice(c),random.choice(n)] you're limiting random.choice(l) to only 2 possible chars (one from each list c and n).
Try this instead:
from random import random, choice
s = 'Hello world'
c = ['a','b','c','d','e','f']
n = ['1','2','3','4','5','6']
L = choice([c, n]) # randomly choose either c or n
return ''.join('%s%s' % (x, choice(L) if random() > 0.5 else '') for x in s)
As an aside, assuming you want to keep the probability of an insertion at 0.5, that can also be written as:
# for each char, either append an empty string or a random char from list
return ''.join('%s%s' % (x, choice((choice(L), ""))) for x in s)
Update
Note that the above answer chooses a substitution list (c or n) and uses it for the whole process. If you want to be able to use both lists in the substitution, you can either create an intermediate list (L = c + n), or perform the list selection in-line.
# This is rather convoluted
return ''.join('%s%s' % (x, choice((choice(choice([c, n])), ""))) for x in s)
Alternatively,
e = ("", ) # tuple with a single empty element
return ''.join('%s%s' % (x, choice(choice([c, n, e, e]))) for x in s)
Choose between c, n, or empty list e (e appears twice to keep the non-empty probability at 50%. Change as required)
From the chosen list/tuple, choose a random element