UnboundLocalError: local variable 'depcoord' referenced before assignment - python

I'm trying to iterate through a csv file, and am getting this error when calling the haversine function to calculate the distance between two locations. I'm confused because the variable seems to be assigned above?
def distance(dep, dest):
depfound = False
arrfound = False
for rowm in csv_reader:
for row in rowm.items():
if depfound == True and arrfound == True:
print ("BREAKING")
break
else:
if row[0] == (dep):
print (row[0])
depcoord = row[11]
print (depcoord)
depfound = True
if row[0] == (dest):
arrcoord = row[11]
print (arrcoord)
arrfound = True
print (haversine(depcoord, arrcoord))
distance("EGKK", "LFMN")

This is because in case your control doesnt come to "else", then the variable is undefined as the print will be executed in all cases.
Following should work
def distance(dep, dest):
depfound = False
arrfound = False
depcoord = None # or any other value as default eg - False
arrfound = None
for rowm in csv_reader:
for row in rowm.items():
if depfound == True and arrfound == True:
print ("BREAKING")
break
else:
if row[0] == (dep):
print (row[0])
depcoord = row[11]
print (depcoord)
depfound = True
if row[0] == (dest):
arrcoord = row[11]
print (arrcoord)
arrfound = True
print (haversine(depcoord, arrcoord))
distance("EGKK", "LFMN")

You call a print with an uninitialized variable. Initialize the variable depcoord = False.

Related

How to create a function based on another dataframe column being True?

I have a dataframe shown below:
Name X Y
0 A False True
1 B True True
2 C True False
I want to create a function for example:
example_function("A") = "A is in Y"
example_function("B") = "B is in X and Y"
example_function("C") = "C is in X"
This is my code currently (incorrect and doesn't look very efficient):
def example_function(name):
for name in df['Name']:
if df['X'][name] == True and df['Y'][name] == False:
print(str(name) + "is in X")
elif df['X'][name] == False and df['Y'][name] == True:
print(str(name) + "is in Y")
else:
print(str(name) + "is in X and Y")
I eventually want to add more Boolean columns so it needs to be scalable. How can I do this? Would it be better to create a dictionary, rather than a dataframe?
Thanks!
If you really want a function you could do:
def example_function(label):
s = df.set_index('Name').loc[label]
l = s[s].index.to_list()
return f'{label} is in {" and ".join(l)}'
example_function('A')
'A is in Y'
example_function('B')
'B is in X and Y'
You can also compute all the solutions as dictionary:
s = (df.set_index('Name').replace({False: pd.NA}).stack()
.reset_index(level=0)['Name']
)
out = s.index.groupby(s)
output:
{'A': ['Y'], 'B': ['X', 'Y'], 'C': ['X']}
I think you can stay with a DataFrame, the same output can be obtained with a function like this:
def func (name, df):
# some checks to verify that the name is actually in the df
occurrences_name = np.sum(df['Name'] == name)
if occurrences_name == 0:
raise ValueError('Name not found')
elif occurrences_name > 1:
raise ValueError('More than one name found')
# get the index corresponding to the name you're looking for
# and select the corresponding row
index = df[df['Name'] == name].index[0]
row = df.drop(['Name'], axis=1).iloc[index]
outstring = '{} is in '.format(name)
for i in range(len(row)):
if row[i] == True:
if i != 0: outstring += ', '
outstring += '{}'.format(row.index[i])
return outstring
of course you can adapt this to the specific shape of your df, I'm assuming that the column containing names is actually 'Name'.

Print element in list based on condition

car_file = open("car.txt", "r")
count = 0
for car_record in car_file:
car_record = car_record.strip('\n')
value = car_record.split(',')
print((count+1),'.', car_record)
count+=1
car_file.close()
car.txt
I want to only print the line that [7] is available
Since your availability is in the last column, you could use value[-1] to access it. I think you should have a look at if statements first. However, here is some code to help you out:
car_file = open("car.txt", "r")
count = 0
for car_record in car_file:
car_record = car_record.strip('\n')
value = car_record.split(',')
if value[-1] == "AVAILABLE":
print((count+1),'.', car_record)
count+=1
car_file.close()
Check if string is in value:
print(value) if 'AVAILABLE' in value else False

Function improperly marks CSV rows as corrupt

I have a CSV file with data in it that should be either a float or an integer, but if its not, the row is marked as corrupt.
I have this if statement that checks several of the columns in each row to see if they are not empty, and if they are a float or integer. Currently, the program marks every row in the CSV file as corrupt. How do I fix this?
def check_if_number(num) :
for i in num:
if i == "." or i == "":
pass
else:
try:
float(i)
except (ValueError, TypeError):
return False
return True
def check_if_empty(item) :
if item == "" :
return True
else:
return False
if (check_if_empty(row[5]) == False
and check_if_number(row[5]) == False
or check_if_empty(row[6]) == False
and check_if_number(row[6]) == False
or check_if_empty(row[8]) == False
and check_if_number(row[8]) == False
or check_if_empty(row[9]) == False
and check_if_number(row[9]) == False
or check_if_empty(row[10]) == False
and check_if_number(row[10]) == False):
corrupt = True
I think your second function is returning True when you want it to return False?
def check_if_empty(item) :
if item == "" :
return False
else:
return True
EDIT:
I have simplified and attached an updated working code that yields what you are looking for just to help substantiate my thought.
def check_if_number(num):
float(num)
for i in num:
if i == "." or i == "":
pass
else:
try:
float(i)
except (ValueError, TypeError):
return False
return True
def check_if_empty(item):
if item == "" :
return False
else:
return True
if check_if_empty('.4') == True and check_if_number('.4') == True:
corrupt = False
else:
corrupt = True
print(corrupt)
... False

how to check if a cell is empty in openpyxl python

I'm making a conditional statement in openpyxl Python to check if a cell is empty. Here's my code:
newlist = []
looprow = 1
print ("Highest col",readex.get_highest_column())
getnewhighcolumn = readex.get_highest_column()
for i in range(0, lengthofdict):
prevsymbol = readex.cell(row = looprow,column=getnewhighcolumn).value
if prevsymbol == "None":
pass
else:
newstocks.append(prevsymbol)
looprow += 1
#print (prevsymbol)
print(newlist)
I tried if prevsymbol == "": and if prevsymbol == null: to no avail.
You compare prevsymbol with str "None", not None object. Try
if prevsymbol == None:
Also here
prevsymbol = readex.cell(row = looprow,column=getnewhighcolumn).value
you use looprow as row index. And you increment looprow only if cell.value is not empty. Here
newstocks.append(prevsymbol)
you use newstocks instead of newlist. Try this code
newlist = []
print ("Highest col",readex.get_highest_column())
getnewhighcolumn = readex.get_highest_column()
for i in range(0, lengthofdict):
prevsymbol = readex.cell(row = i+1,column=getnewhighcolumn).value
if prevsymbol is not None:
newlist.append(prevsymbol)
print(newlist)
Take the quotes away from the None.
if prevsymbol is None:
This is the python equivalent of checking if something is equal to null.

python - 'NoneType' object has no attribute

I'm new with Python/programming and trying to solve little problems to get a hang of it.
I've been struggling with the error below and not too sure how i got it. I understand it is saying the file type is None which is why it's throwing the error. However, I don't get how it is None in the first place? Just wondering if I could get some guidance or hint on the issue? Thank you very much, sorry if the code is messy
line 138, in move
self.ecoList[self.temP].nP = tempAni.p AttributeError: 'NoneType' object has no attribute 'nP'
from random import randint
class Bears:
def __init__(self):
self.p = 0
self.dp = 0
self.nP = 0
self.check = True
def run(self):
self.dp = randint(-1, 1)
self.nP = self.dp + self.p
self.check = False
def __str__(self):
return "Bear_"
def __repr__(self):
return self.__str__()
class Fish:
def __init__(self):
self.p = 0
self.dp = 0
self.nP = 0
self.check = True
def run(self):
self.dp = randint(-1, 1)
self.nP = self.dp + self.p
self.check = False
def __str__(self):
return "Fish|"
def __repr__(self):
return self.__str__()
class EcoSystem:
def __init__(self):
self.ecoList = [None] * 10
self.bearList = []
self.fishList = []
for i in range(2):
self.bearList.append(Bears())
#Adding bear to ecoList
while True:
index = randint(0, 9)
if self.ecoList[index] is None:
self.ecoList[index] = self.bearList[i]
self.ecoList[index].p = index
break
else:
continue
for i in range(2):
self.fishList.append(Fish())
#Adding fish to ecoList
while True:
index = randint(0, 9)
if self.ecoList[index] is None:
self.ecoList[index] = self.fishList[i]
self.ecoList[index].p = index
break
else:
continue
self.move()
def move(self):
#Print out the current eco system
print(*self.ecoList, sep='\n')
anwser = True
while anwser:
#populate next move new position for each object
for i in range(len(self.ecoList)):
if self.ecoList[i] is None:
continue
else:
self.ecoList[i].run()
#run for loop to test next position of the object
for i in range (len(self.ecoList)):
#if [i] item is None skip to next loop
if self.ecoList[i] is None:
continue
elif self.ecoList[i].check == True:
continue
#else check if it is going to move then check adjacent slot is going to be taken
else:
tempAni = None #temp animal to compare with item in loop
#call out new position from item i
newP = self.ecoList[i].nP
#call out direction:
newDP = self.ecoList[i].dp
#do nothing, skip to next slot if it is not going to move
if newDP == 0:
self.ecoList[i].check = True
continue
elif newDP != 0:#test if new position is going to be out of bound
if newP < 0 or newP > (len(self.ecoList)-1):
#set new position back to current
self.ecoList[i].nP = self.ecoList[i].p
self.ecoList[i].dp = 0
self.ecoList[i].check = True
else:
#test if new position is going to be collided
if self.ecoList[newP] is not None:
if self.ecoList[newP].nP == self.ecoList[i].nP:
print("////////////////")
tempAni = self.ecoList[newP]
#test if the next next new position is not None or out of bound
#Assumption - prioritize the closet animal going to move
elif (newP+newDP) > 0 and (newP+newDP) < (len(self.ecoList)-1):
if self.ecoList[newP+newDP] is not None:
#test if this is going to be collided
if self.ecoList[newP+newDP].nP == self.ecoList[i].nP:
print("\\\\\\\\\\\\\\")
tempAni = self.ecoList[newP+newDP]
#if tempAni is not none compare the type
if tempAni is not None:
print ("####")
print (self.ecoList[i].p)
print (self.ecoList[i])
print("-----------")
print (tempAni.p)
print(tempAni)
print ("####")
#test if they are the same type
self.temP = tempAni.p
if tempAni.__class__.__name__ == self.ecoList[i].__class__.__name__:
#if they are, change new position to current position
self.ecoList[i].nP = self.ecoList[i].p
self.ecoList[i].check = True
print("?????")
print(self.temP)
print(tempAni)
print(tempAni.dp)
print(self.ecoList[i])
print(self.ecoList[i].dp)
self.ecoList[self.temP].nP = tempAni.p
self.ecoList[self.temP].check = True
#create new animal of the same type and put it to a random place on the list
#Assumption - if the list is full add do nothing
#Determine tempAni type to create new bear or fish
if isinstance(tempAni, Bears):
#create new bear
newAni = Bears()
else:
#creaete new fish
newAni = Fish()
#while loop if the list is still have available spot add new animal to random spot, otherwise do nothing
while None in self.ecoList:
index = randint(0, 9)
if self.ecoList[index] is None:
self.ecoList.insert(index, newAni)
self.ecoList[index].p = index
print ("*****")
print (self.ecoList[index].p)
print (self.ecoList[index])
print ("*****")
break
#if they are not the same type, kill the fish
else:
#determine if tempAni is the fish or bear
if isinstance(tempAni, Bears):
#if it is bears kill the fish in i
self.ecoList[i].p = -1
self.ecoList[i].check = True
self.ecoList[self.temP].check = True
elif isinstance(tempAni, Fish):
#if it is fish kill it
self.ecoList[self.temP].p = -1
self.ecoList[i].check = True
self.ecoList[self.temP].check = True
#Apply the change after all the checks are finished
#Remove all the fish got killed and apply the moves
for i in range (len(self.ecoList)):
if self.ecoList[i] is not None:
if self.ecoList[i].p == -1:
self.ecoList[i] = None
elif self.ecoList[i].check == False:
self.ecoList[i].check = True
newP = self.ecoList[i].nP
if newP != i:
self.ecoList[newP] = self.ecoList[i]
self.ecoList[newP].p = newP
self.ecoList[i] = None
#Print out the current eco system
print ("---------------------------------------")
for i in range (len(self.ecoList)):
print(self.ecoList[i])
print(i)
#Ask if user want to continue playing
test = True
while test == True:
strAns = input ('Enter y/n to continue or not: ')
if strAns.lower() == "n":
anwser = False
test = False
break
elif strAns.lower() == "y":
test = False
break
def main():
EcoSystem()
main()
The error means that self.ecoList[self.temP] is None, although your code does not expect it to be None. So, this is the offending line:
self.ecoList[self.temP].nP = tempAni.p
Your code actually wants to assign tempAni.p to None.nP. None does not have such an attribute, and that is why you get the error. The line where the code throws the exception is just an indication that something is wrong in your code, somewhere. Finding this bug is your task now.
You need to breathe calmly and step-by-step figure out where your code is wrong. This might be anywhere and nobody here on SO will find this for you. Add print and/or assert statements to your code, and narrow down the issue. This is debugging work, and you have to go through it!

Categories