printing the values of an Array prevents a null pointer error - python

I'm trying to search a parameter space for a good model. In my code I'm doing something like the following:
configurations = [None] * 9
index = 0
for param1 in range(3):
for param2 in range (3):
#call constructor
configurations[index] = Configuration(param1, param2)
index = index + 1
return configurations
then I use this array elsewhere to build the models.
However, for some reason it doesn't fill the array. I get an error when accessing index 3 or higher. Inspection shows that the array at these indices are still 'None'. while debugging this, I added a print statement to the code:
configurations = [None] * 9
index = 0
for param1 in range(3):
for param2 in range (3):
#call constructor
configurations[index] = Configuration(param1, param2)
index = index + 1
for x in configurations:
print(x.param1)
return configurations
to my surprise, my code now ran smoothly. The array is completely filled. If I comment out those 2 lines: error. uncomment the lines: it works again.
what is going on here? Why is the print statement altering the behavior of my program? is this an overactive GC that's staved off by printing the values?

I found the issue. the return statement was indented with a Tab, but I use 4 spaces everywhere else in my code. This was causing it to skip the most outer for loop. the print statement somehow prevented this. changing the tab to spaces removed the need for the print statement.

Related

IndexError: list index out of range even though printing individual lists and index doesn't seem to have an error

take = randint(0, len(teacherClass[teacher])-1)
print(take)
print(teacherClass)
print(teacher)
print(teacherClass[teacher])
triesDone = 0
while triesDone < len(teacherClass[teacher]):
cp = teacherClass[teacher][take]
if (cp not in (blocks[teacher][day])) and (blocksS[cp][day][block] == ""):
blocks[teacher][day][block] = cp
blocksS[cp][day][block] = teacherSub[teacher]
take +=1
triesDone += 1
if take == len(teacherClass[teacher])-1:
take = 0
When I run the program after some time, the above part is hit and the program starts working as intended but line 8 raises the error ("IndexError: list index out of range").
Trying to solve that and understand the problem, I tried to print the entire dictionary(teacherClass) and the indices used(teacher and take) but even after that, it seems the line 8 should work.
Output I am getting:
Output with list and index
Please help me understand the problem and a solution. Thanks
There is a possibility that take could be: len(teacherClass[teacher])-1 from the assignment on the first line. Later there is take += 1. This mean that it is larger than the limit, so take = 0 is never executed.
Did you mean:
if take >= len(teacherClass[teacher])-1:
take = 0

ArcGIS Field Calculator: Conditional statement syntax error

Rudimentary Python/ArcPy skills at work here, not sure where I'm going wrong.
Trying to do a simple random selection of 10 features from a layer to be indicated by the placement of a "1" in another attribute set aside for this purpose. Basic concept is is to use random.sample() to generate a random list of 10 FID's, and then check to see if each FID is in the list. NewID is an attribute containing FID's values. This is what I have in the code block:
import random
def randSelTen():
featurecount = arcpy.GetCount_management("layer_name")
linecount = int(str(featurecount))
lst_oids = range(0, linecount)
rand_lines = random.sample(lst_oids, 10)
if !NewID! in rand_lines:
return 1
else:
return 0
I keep getting a syntax error on the conditional containing !NewID!, and no matter what I do I can't fix it. If I replace !NewID! with an integer, the script runs, but of course the output is bad. Any help is appreciated... thanks!
If you are putting this code in the "Codeblock" of the field calculator then the reason you are getting a syntax error is because you can not access fields like that from the codeblock. You must pass in the field as an argument to the function. So you would have to do this:
# -----Codeblock---------
import random
def randSelTen(NewID):
featurecount = arcpy.GetCount_management("layer_name")
linecount = int(str(featurecount))
lst_oids = range(0, linecount)
rand_lines = random.sample(lst_oids, 10)
if NewID in rand_lines:
return 1
else:
return 0
# ----- Expression (goes in bottom text box of the field calculator if using GUI) -----
randSelTen(!NewID!)

Add to dictionary in if loop

I have an if loop in which I am trying to;
(1) Create a dataframe from a filepath.
(2) Format this dataframe
(3) Add that dataframe to a dictionary that is a property of an instance of a class.
Here is my code defining the class and the method:
class myClass:
def __init__(self, name, filepathlist):
self.name = name
self.filepathlist = filepathlist
def formatData(self):
i = 0
self.dataframeDict = {}
if i < (len(self.filepathlist) - 1):
DFRAW = pd.read_csv(self.filepathlist[i], header = 9) #Row 9 is the row that is not blank (all blank auto-skipped)
DFRAW['DateTime'], DFRAW['dummycol1'] = DFRAW[' ;W;W;W;W'].str.split(';', 1).str
DFRAW['Col1'], DFRAW['dummycol2'] = DFRAW['dummycol1'].str.split(';', 1).str
DFRAW['Col2'], DFRAW['dummycol3'] = DFRAW['dummycol2'].str.split(';', 1).str
DFRAW['Col3'], DFRAW['Col4'] = DFRAW['dummycol3'].str.split(';', 1).str
DFRAW = DFRAW.drop([' ;W;W;W;W', 'dummycol1', 'dummycol2', 'dummycol3'], axis = 1)
dictIndex = self.filepathlist[i][39:44]
self.dataframeDict.update({dictIndex: DFRAW})
i = i + 1
Then I create an instance of the class and run the method:
filepathlist = ['filepath1','filepath2']
myINST = myClass('Mydataname', filepathlist)
myINST.formatData()
I then expect myINST.dataframeDict to have two dataframes as per the 2 input filepaths and thus 2 iterations of the if loop. However only 1 is present.
What is the error in my code or my approach?
It is hard to tell whether this will completely solve your problem, because no dummy data is provided. You will, however, get one step closer to your solution if you replace if i < (len(self.filepathlist) - 1): with while i < (len(self.filepathlist) - 1):.
You are currently just checking if i=0 is smaller than len(self.filepathlist)-1. If so, then the if-block is executed once. What you are actually looking for is a loop that keeps on iterating, as long as i is smaller than len(self.filepathlist)-1. This is done with while-loops.
You need to change your condition to for i in range(len(self.filepathlist)):
(Also, remove the assignment of i as the for loop does it automatically. For the same reason, you should also remove the line which increments i).
If you want to use a while loop, change the if line to while i < len(self.filepathlist):.
Notice that there's no -1. This is because you're using < instead of <=. If you want to use -1, then you also need the <= as this will ensure the loop runs the correct number of times.

Assign variable if list index out of range python error

How to pass a string to a variable if an index error is found? Consider the code:
for l1, l2 in zip(open('file1.list'), open ('file2.list')):
a=fasta1[int(l1)]
b=fasta2[int(l2)]
alignments = pairwise2.align.globalxx(a,b)
top_aln = alignments[0]
aln_a, aln_b, score, begin, end = top_aln
print aln_a+'\n'+aln_b
outfast1 = aln_a
outfast2 = aln_b
A number of these functions must be imported (pairwise2 align),
but the file.lists are single column text files with one sequence id (text and numbers) per line, that are used to extract from the fasta1 and fasta2 text files.
Basically, I want to try: each list command ( a=fasta1[int(l1)]) and if there is no error (the id is in range), do as normal (assign variables a and b for that iteration), but if NOT, assign the 'a' variable some placeholder text like 'GGG':
for l1, l2 in zip(open('file1.list'), open ('file2.list')):
try:
a=fasta1[int(l1)]
except IndexError,e:
a="GGG"
continue
try:
b=fasta2[int(l2)]
except (IndexError):
b="CCC"
continue
This code doesn't quite work (when integrated with above code), which isn't surprising given my lack of python prowess, but I don't quite know why. I actually get no text output, despite the print calls... Am I thinking about this right? If there is NO error in the index, I just want it to go on and do the pairwise alignment (with the first a and b variables) and then print some text to stdout.
Any ideas?
Python's conditional (aka ternary) expressions can one-line this for you. They're often criticized for lack of readability, but I think this example reads well enough.
a = fasta1[int(l1)] if int(l1) < len(fasta1) else "GGG"
You don't need continue, because it will skip that iteration of the loop. Consider the following:
for l1, l2 in zip(open('file1.list'), open ('file2.list')):
a = 'GGG'
b = 'CCC'
try:
a = fasta1[int(l1)]
b = fasta2[int(l2)]
except IndexError:
pass

Asterisk coming up in Jupyter Notebook with a specific code

I am using Jupyter Notebook, I keep getting the asterisk that indicates the kernel is busy when I run this specific code:
var = 2
var += 1
var_rem = var % 3
while var_rem == 0:
var += 2
print var
In order to give some context, I am trying to solve the following exercise:
Define a new number variable and choose a value for it. If the
variable + 1 can be divided by three, increase the variable by two.
Test by printing the final value of the variable and varying the
initial value of that same variable.
I have tried restarting the kernel as it was recommended in front of the asterisk issue but it doesn't work. What is specific about this code that the kernel cannot process it? How do I then solve the exercise?
Note: First post around here, I hope it's relevant.
Your code results in an infinite loop. Your variable var_rem does not change its value in the loop, therefore it runs forever (because it remains 0)
You have to recalculate the while condition within the loop.
Based on the statement your logic is wrong. Try this...
var = 2
if ((var + 1) % 3) == 0:
var +=2
print var
else:
print 'Not divisible by 3'

Categories