I am currently building a function that checks if a location on a board exists and returns boolean values. The location is given as a tuple and the board aka puzzle is given as a 2d list.
For example:
is_valid_location((1,1), [[None]]) → False
is_valid_location((1,1), [[1,2],[2,1]]) → True (because 2x2 puzzle has a row 1 and col 1)
is_valid_location((1,2), [[1,2],[2,1]]) → False
My current code is attempting to assign index 0 of the tuple as x and index 1 of the tuple as y. Then I'm trying to return the boolean value.
def is_valid_location(loc,puzzle):
location=tuple(loc)
x=location[0]
y=location[1]
return x in range(len(puzzle[0])) and y in range(len(puzzle))
The function is not working because I am getting indentation errors, but to my knowledge I've indented correctly. Is there a simpler way to do this without calling any built in functions?
No indentation errors could be found. If you get this error it's mostly caused when you copy paste code in with a mix of tabs and spaces. Remove all spacing and then tab them out again.
Your function could also be simplified to
def is_valid_location(loc, puzzle):
x, y = loc
return 0 <= x < len(puzzle[0]) and 0 <= y < len(puzzle)
Your code works exactly the way you describe when I copy it into my editor, so I would recommend exploring the indentation error further. You might be mixing tabs and spaces; this can be resolved by changing the settings of your text editor such that it always replaces tabs with 4 spaces. Unfortunately it is difficult to help you further without seeing the traceback of the error.
Related
I am trying to solve this problem of displaying prime numbers upto a specified number.
While I have the standard solution for it. I first tried to solve it myself and ended up writing this code. But I'm not getting the desired output. The standard solution uses the while loop as the main loop. And if that's the ideal loop for this example, why would that be so ?
def count_primes(num):
my_primes=[2]
if num<2:
return 0
for x in range(3,num+1,2):
for y in range(3,x+1):
if x%y==0:
break
else:
my_primes.append(x)
return my_primes
count_primes(100)
I expected a list of all prime numbers up to 100. Instead the output displayed only [2]. My guess is that the 'break' keyword broke out of the entire loop instead of only the if loop.
In your second for loop change range(3,x+1) to range(3,x), since your loop goes until y=x and x%x is always 0.
This question has somehow to do with an earlier post from me. See here overlap-of-nested-lists-creates-unwanted-gap
I think that I have found a solution but i can't figure out how to implement it.
First the relevant code since I think it is easier to explain my problem that way. I have prepared a fiddle to show the code:
PYFiddle here
Each iteration fills a nested list in ag depending on the axis. The next iteration is supposed to fill the next nested list in ag but depending on the length of the list filled before.
The generell idea to realise this is as follows:
First I would assign each nested list within the top for-loop to a variable like that:
x = ag[0]
y = ag[1]
z = ag[2]
In order to identify that first list I need to access data_j like that. I think the access would work that way.
data_j[i-1]['axis']
data_j[i-1]['axis'] returns either x,y or z as string
Now I need to get the length of the list which corresponds to the axis returned from data_j[i-1]['axis'].
The problem is how do I connect the "value" of data_j[i-1]['axis'] with its corresponding x = ag[0], y = ag[1] or z = ag[2]
Since eval() and globals() are bad practice I would need a push into the right direction. I couldn't find a solution
EDIT:
I think I figured out a way. Instead of taking the detour of using the actual axis name I will try to use the iterator i of the parent loop (See the fiddle) since it increases for each element from data_j it kinda creates an id which I think I can use to create a method to use it for the index of the nest to address the correct list.
I managed to solve it using the iterator i. See the fiddle from my original post in order to comprehend what I did with the following piece of code:
if i < 0:
cond = 0
else:
cond = i
pred_axis = data_j[cond]['axis']
if pred_axis == 'x':
g = 0
elif pred_axis == 'y':
g = 1
elif pred_axis == 'z':
g = 2
calc_size = len(ag[g])
n_offset = calc_size+offset
I haven't figured yet why cond must be i and not i-1 but it works. As soon as I figure out the logic behind it I will post it.
EDIT: It doesn't work for i it works for i-1. My indices for the relevant list start at 1. ag[0] is reserved for a constant which can be added if necessary for further calculations. So since the relevant indices are moved up by the value of 1 from the beginning already i don't need to decrease the iterator in each run.
I am doing some haskell exercises to learn the language and I have a syntax error I was hoping someone could help me with:
-- Split a list l at element k into a tuple: The first part up to and including k, the second part after k
-- For example "splitAtIndex 3 [1,1,1,2,2,2]" returns ([1,1,1],[2,2,2])
splitAtIndex k l = ([l !! x | x <- firstHalfIndexes], [l !! x | x <- firstHalfIndexes])
where firstHalfIndexes = [0..k-1]
secondHalfIndexes = [k..(length l-1)]
The syntax error is "parse error on input ‘=’" and seems to be coming from my second where clause, but I can't work out why the first where clause is ok but not the second?
The Haskell Report specifies that tab characters flesh out text to the next multiple of eight. Your code appears to assume that it gets fleshed out to the next multiple of four. (My best guess. Might also be configured to be five or six, but those settings seem less popular than four.)
See my page on tabs for ideas on how to safely use tabs in Haskell code; or else do what most other folks do and configure your editor to expand tabs to spaces.
For an example of the style I use, your current code looks like this to the compiler (using > to mark tabs and _ for spaces):
splitAtIndex_..._=_...
> where_> firstHalfIndexes_=_...
> > > secondHalfIndexes_=_...
I would write it to look like this to the compiler:
splitAtIndex_..._=_...
> where_> firstHalfIndexes_=_...
> ______> secondHalfIndexes_=_...
This also looks correct with four-space tabstops (and indeed any size tabstop):
splitAtIndex_..._=_...
> where_> firstHalfIndexes_=_...
> ______> secondHalfIndexes_=_...
(Actually, I would probably just use one space after where rather than a space and a tab, but that's an aesthetics thing, not really a technical one.)
So I can't seem to get this. Without the 'while' loop this code works fine but as soon as I apply the loop it stops working right. From some reason it's treating x as a string. Like if x were 2 it would print y as '2222' instead of 16. I'm still new at this can someone tell my why? Thanks!
go = 'y'
while go == 'y':
print('enter x')
x = input()
y = x * 4
print(y)
print('go again?')
go = input()
Python 3's input function always returns a string. This is a change from Python 2, where input returned different kinds of Python objects depending on what was entered by the user. Python 3's version is equivalent to Python 2's raw_input.
With that background in mind, it's easy to fix your code. Just call the int constructor to turn your string into an integer. Or if you want to support non-integer values (like 1.4), use float instead.
As an aside, as your code is currently formatted in the question, it has an infinate loop. Is your logic to change the go variable really at top level? If so, it won't ever change during the loop, which will run forever.
This is actually dependent on your python version. input will automatically convert your string to an integer if it finds one. To prevent this, use the raw_input function in python < 3. For python 3 and above I believe this is the default behavior.
This is related to random sampling. I am using random.sample(number,5) to return a list of random numbers from within a range of numbers contained in numbers. I am using while i < 100 to return one hundred sets of five numbers. To check for duplicates, I am using :
if len(numbers) != len(set(numbers)):
to identify sets with duplicates and following this with random.sample(number,5) to try to do another randomisation to replace the set with duplicates. I seem to get about 8% getting re-randomised ( using a print statement to say which number was duplicated), but about 5% seem to be missed. What am I doing incorrectly? The actual code is as follows:
while i < 100:
set1 = random.sample(numbers1,5)
if len(set1) != len(set(set1))
print('duplicate(s) found, random selection repeated')
set1 = random.sample(numbers1,5)
In another routine I am trying to do the same as above, but searching for duplicates in two sets by adding the same, substituting set2 for set1. This gives the same sorts of failures. The set2 routine is indented and placed immediately below the above routine. While i < 100: is not repeated for set2.
I hope that I have explained my problem clearly!!
There is nothing in your code to stop the second sample from having duplicates. What if you did something like a second while loop?
while i<100:
i+=1
set1 = random.sample(numbers1,5)
while len(set1) != len(set(set1)):
print('duplicate(s) found, random selection repeated')
set1 = random.sample(numbers1,5)
Of course you're still missing the part of the code that does something... beyond the above it's difficult to tell what you might need to change without a full code sample.
EDIT: here is a working version of the code sample from the comments:
def choose_random(list1,n):
import random
i = 0
set_list=[]
major_numbers=range(1,50) + list1
print(major_numbers)
while i <n:
set1 =random.sample(major_numbers,5)
set2 =random.sample(major_numbers,2)
while len(set(set1)) != len(set1):
print("Duplicate found at %i"%i)
print set1
print("Changing to:")
set1 =random.sample(major_numbers,5)
print set1
set_list.append([set1,set2])
i +=1
return set_list
The code you give obviously has some gaps in it and cannot work as it is there, so I cannot pinpoint where exactly your error is, but running set1 = random.sample(numbers1,5) after the end of the while loop (which is infinite if written as in your question) undoes everything you did before, because it overwrites whatever you managed to set set1 to.
Anyway, random.sample should give you a sample without replacement. If you have any repetitions in random.sample(numbers1, 5) that means that you already have repetitions in numbers1. If that is not supposed to be the case, you should check the content of numbers1 and maybe force it to contain everything uniquely, for example by using set(numbers1) instead.
If the reason is that you want some elements from numbers1 with higher probability, you might want to put this as
set1 = random.sample(numbers1, 5)
while len(set1) != len(set(set1)):
set1 = random.sample(numbers1, 5)
This is a possibly infinite loop, but if numbers1 contains at least 5 different elements, it will exit the loop at some point. If you don't like the theoretical possibility of this loop never exiting, you should probably use a weighted sample instead of random.sample, (there are a few examples of how to do that here on stackoverflow) and remove the numbers you have already chosen from the weights table.