I am new to Python. I want to call a function that detect null value in a excel table and passing "Fail" to a variable stat.
def checkBlank(tb):
book=xlrd.open_workbook(reportFile)
sheet = book.sheet_by_name(tb)
s= "Pass"
for i in range(sheet.nrows):
row = sheet.row_values(i)
for cell in row:
if cell =='':
s="Fail"
return s
print checkBlank('Sheet1')
Above code will return "Fail"
but below code will give: NameError: name 'stat' is not defined
def checkBlank(tb,stat):
book=xlrd.open_workbook(reportFile)
sheet = book.sheet_by_name(tb)
s= "Pass"
for i in range(sheet.nrows):
row = sheet.row_values(i)
for cell in row:
if cell =='':
s="Fail"
print checkBlank('Sheet1', stat)
print stat
How can I assign "Fail" to stat if the function find the empty cell?
It appears that you are attemping to pass a variable into a function to be used as the return value. This is not Pythonic and in general will not work. Instead, your function should be returning a value and you should be assigning that value to a new "variable."
def function(arg):
if arg:
return 'Pass'
else:
return 'Fail'
status = function(False)
print(status) # 'Fail'
In Python, you don't want to try to write a function that calls by reference, because variables don't exist in Python in the same way that they do in C. Instead, what we have are names which are more akin to placeholders and can be used to retrieve objects. This article and many other Stack Overflow answers go into this in more depth.
Related
This is what I am supposed to do in my assignment:
This function is used to create a bank dictionary. The given argument
is the filename to load. Every line in the file will look like key:
value Key is a user's name and value is an amount to update the user's
bank account with. The value should be a number, however, it is
possible that there is no value or that the value is an invalid
number.
What you will do:
Try to make a dictionary from the contents of the file.
If the key doesn't exist, create a new key:value pair.
If the key does exist, increment its value with the amount.
You should also handle cases when the value is invalid. If so, ignore that line and don't update the dictionary.
Finally, return the dictionary.
Note: All of the users in the bank file are in the user account file.
Example of the contents of 'filename' file:
Brandon: 115.5
James: 128.87
Sarah: 827.43
Patrick:'18.9
This is my code:
bank = {}
with open(filename) as f:
for line in f:
line1 = line
list1 = line1.split(": ")
if (len(list1) == 2):
key = list1[0]
value = list1[1]
is_valid = value.isnumeric()
if is_valid == True
value1 = float(value)
bank[(key)] = value1
return bank
My code returns a NoneType object which causes an error but I don't know where the code is wrong. Also, there are many other errors. How can I improve/fix the code?
Try this code and let me explain everything on it because it depends on how much you're understanding Python Data structure:
Code Syntax
adict = {}
with open("text_data.txt") as data:
"""
adict (dict): is a dictionary variable which stores the data from the iteration
process that's happening when we're separating the file syntax into 'keys' and 'values'.
We're doing that by iterate the file lines from the file and looping into them.
The `line` is each line from the func `readlines()`. Now the magic happens here,
you're playing with the line using slicing process which helps you to choose
the location of the character and play start from it. BUT,
you'll face a problem with how will you avoid the '\n' that appears at the end of each line.
you can use func `strip` to remove this character from the end of the file.
"""
adict = {line[:line.index(':')]: line[line.index(':')+1: ].strip('\n') for line in data.readlines()}
print(adict)
Output
{' Brandon': '115.5', ' James': '128.87', ' Sarah': '827.43', ' Patrick': "'18.9"}
In term of Value Validation by little of search you will find that you can check the value if its a number or not
According to Detect whether a Python string is a number or a letter
a = 5
def is_number(a):
try:
float (a)
except ValueError:
return False
else:
return True
By Calling the function
print(is_number(a))
print(is_number(1.4))
print(is_number('hello'))
OUTPUT
True
True
False
Now, let's back to our code to edit;
All you need to do is to add condition to this dict..
adict = {line[:line.index(':')]: line[line.index(':')+1: ].strip(' \n') for line in data.readlines() if is_number(line[line.index(':')+1: ].strip('\n')) == True}
OUTPUT
{'Brandon': '115.5', 'James': '128.87', 'Sarah': '827.43'}
You can check the value of the dict by passing it to the function that we created
Code Syntax
print(is_number(adict['Brandon']))
OUTPUT
True
You can add more extensions to the is_number() function if you want.
You're likely hitting the return in the else statement, which doesn't return anything (hence None). So as soon as there is one line in your file that does not contain 2 white-space separated values, you're returning nothing.
Also note that your code is only trying to assign a value to a key in a dictionary. It is not adding a value to an existing key if it already exists, as per the documentation.
This should effectively do the job:
bank = {}
with open(filename) as file:
for line in file:
key, val = line.rsplit(": ", 1) # This will split on the last ': ' avoiding ambiguity of semi-colons in the middle
# Using a trial and error method to convert number to float
try:
bank[key] = float(val)
except ValueError as e:
print(e)
return bank
I'm learning python and I'm trying to use this function I built and its not working. The function is not changing a single value in the dictionary as it is working now, although it should. I'd like to get some help
def delete_product(diction):
product_to_delete = raw_input()
for key,value in diction.items():
if key == product_to_delete:
value = value - 1
if (value == 0):
del diction[key]
print "removed"
raw_input()
print "we couldnt remove the product because it does not exist"
raw_input()
Mistake in this code snippet:
value = value - 1
if (value == 0):
del diction[key]
Instead of modifying value in the dictionary, you are only modifying local value. So, this function will delete the required entry only when value happens to be 1.
You can modify it as follows or any variation of it:
if value == 1:
del diction[key]
break
else:
diction[key] = value - 1
Moreover, please note that you have to break out of the for loop once the entry is deleted from the dictionary. If you modify the dictionary while you are iterating it, the iterator will not work after that. If you want to delete multiple keys in one iteration, first get list of all keys to be deleted within the loop and delete after the loop.
I am trying to create one table from each call of the defined function and append the tables together. But it works when I first call the function and filled table corr_tb with output. But when I call the function again and expect to append the new output to corr_tb. Nothing happens. Table corr_tb does not change. Is that because of the global or local variable issue?
corr_tb = pd.DataFrame()
def corr_tbl(df, key, var, with_var):
#calculate correlation by key
output = pd.DataFrame(df.groupby(key)[[var, with_var]].corr().ix[1::2,var]).reset_index()[key+[var]]
global corr_tb
if corr_tb.empty:
corr_tb = output
else:
corr_tb.append(output)
#print(output.head()) #result could be print but cannot be appended
#call function
corr_tbl(final, ['key1','key2'], 'var1','Sales')
corr_tbl(final, ['key1','key2'], 'var2','Sales')
pandas.DataFrame.append method doesn't modify the original object but return a new one, you can assign the new one back to corr_tb:
def corr_tbl(...)
# did some calculation here
if ...:
#
else:
corr_tb = corr_tb.append(df) # <<<<<< try modifying this line
I am writing a save function; which writes a list to a new text file if functions are true. However it's not working as I expected. Currently it does not print anything when the save function is called.
The savedata function calls the duplicate function:
My "d" is a list like so:
[ 'ABB'
'CAB'
'BCA']
duplicate=[]
list=[]
def dup():
l=len(d)
for i in range(l):
column.append([x[i] for x in d])
for col in column:
for i in range(0,len(col)-1):
if col[i] == col[i+1]:
print(str(col[i]) + " is a duplicate in column " + str(column.index(col)+1) + " position(index) " + str(col.index(col[i+1])+1))
return False
else:
return True
Now when i print duplicate() KNOWING i do have duplicates in the list, it should return False, however it returns True. Why is this?
You're not calling the function in your if condition, what it's actually checking for is if duplicate has been defined (in this case, yes, as a function).
Use if duplicate():. Also, I don't see where you're defining d. Perhaps that will raise an error.
This question already has answers here:
Getting the name of a variable as a string
(32 answers)
Closed 4 months ago.
I'm trying to access a variable's name. For example, if I call a function to print a list (printL)
and want to print my list's name "A_minus_B":
def printL (xlist):
print "****************************"
print "name of list"
print (" entries : "),len(xlist)
print xlist
print "****************************"
return()
How can I get the function to print "A_minus_B" instead of "name of list", the name I used when calling the function printL(A_minus_B)?
You can't.* The detailed reasons are discussed in the Python language reference, but basically what Python does when you call printL(A_minus_B) is take the value that has been labeled A_minus_B and create a new label, xlist, that happens to refer to the same thing. From that point on, the label xlist has absolutely no connection to the other label A_minus_B, and in fact, the value which has been labeled A_minus_B or xlist or whatever has no connection to any of the names that have been used to label it.
*Well, you can, by using some deep "Python voodoo"... you would basically have to tell Python to read the piece of source code where you call printL(A_minus_B) and extract the variable name from there. Normally that's the kind of thing you probably shouldn't be doing (not because you're a beginner, but because it usually indicates you've designed your program the wrong way), but debugging is one of those cases where it's probably appropriate. Here's one way to do it:
import inspect, pprint
def print_values(*names):
caller = inspect.stack()[1][0]
for name in names:
if name in caller.f_locals:
value = caller.f_locals[name]
elif name in caller.f_globals:
value = caller.f_globals[name]
else:
print 'no such variable: ' + name
# do whatever you want with name and value, for example:
print "****************************"
print name
print (" entries : "),len(value)
print value
print "****************************"
The catch is that when you call this function, you have to pass it the name of the variable you want printed, not the variable itself. So you would call print_values('A_minus_B'), not print_values(A_minus_B). You can pass multiple names to have them all printed out, for example print_values('A_minus_B', 'C_minus_D', 'foo').
Alternate way to do it:
list_dict = {} #creates empty dictionary
list_dict['list_a'] = [1,2,3,4,5,6] # here you create the name (key)
nice_name = 'list_b'
list_dict[nice_name] = [7,8,9,10,11,12] # here you use already existing string as name (key)
def list_info(ld):
for key in sorted(ld):
print "****************************"
print key
print " entries : " ,len(ld[key])
print ld[key]
print "****************************"
list_info(list_dict)