How can I avoid dntypes.ExcelErrorName() - datanitro

In my spreadsheet I have cells that contain a string such as
=some string here
Excel displays this cell as below if formatting as general. This makes sense because Excel is trying to calculate a cell with a function that doesn't exist
#Name
DataNitro returns the cell value as (which also make sense)
dntypes.ExcelErrorName()
I can manually specify the cell as text, which Excel subsequently then displays the string, and DataNitro returns the string. However this is unfeasible for the amount of cells I would need to this.
Even if I try and skip over these cells I can't check the type like I can with most other classes
type("a") == str
True
but checking against dntypes.ExcelErrorName returns
dntypes is not defined
How can I either replace these cells with some other value, or format them as plaintext?
Edit
Wrote a function to handle these values for the time but I would rather only use this as a temporary fix
def errorfix(row):
for i,value in enumerate(row):
if type(value).__name__ == "ExcelErrorName":
row[i] = "EXCEL NAME ERROR"
return row

You can pass the values through this function:
def get_text(val):
if not isinstance(val, ExcelError):
return val
if type(val) == ExcelErrorDiv0:
return "#DIV/0!"
if type(val) == ExcelErrorNA:
return "#N/A"
if type(val) == ExcelErrorName:
return "#NAME?"
if type(val) == ExcelErrorNull:
return "#NULL!"
if type(val) == ExcelErrorNum:
return "#NUM!"
if type(val) == ExcelErrorRef:
return "#REF!"
if type(val) == ExcelErrorValue:
return "#VALUE!"
raise TypeError("Unknown Excel Error")
isinstance(val, ExcelError) is the best way to check if something is an error.
If you're doing this a lot, you may want to make a subclass of Cell that does this whenever you call value.

Related

Casting regex match to String

I created a simple code in Scala that checks whether an input is correctly formatted as HH:mm. I expect the code to result in an Array of valid strings. However, what I'm getting as a result is of type Any = Array(), which is problematic as when I try to print that result I get something like that:
[Ljava.lang.Object;#32a59591.
I guess it's a simple problem but being a Scala newbie I didn't manage to solve it even after a good few hours of googling and trial & error.
val scheduleHours = if (inputScheduleHours == "") {
dbutils.notebook.exit(s"ERROR: Missing param value for schedule hours.")
}
else {
val timePattern = """^((?:[0-30]?[0-9]|2[0-3]):[0-5][0-9])$""".r
val inputScheduleHoursParsed = inputScheduleHours.split(";").map(_.trim)
for (e <- inputScheduleHoursParsed) yield e match {
case timePattern(e) => e.toString
case _ => dbutils.notebook.exit(s"ERROR: Wrong param value for schedule hours: '${inputScheduleHours}'")
}
}
The problem is that some branches return the result you want and others return dbutils.notebook.exit which (I think) returns Unit. Scala must pick a type for the result that is compatible with both Unit and Array[String], and Any is the only one that fits.
One solution is to add a compatible value after the calls to dbutils.notebook.exit, e.g.
val scheduleHours = if (inputScheduleHours == "") {
dbutils.notebook.exit(s"ERROR: Missing param value for schedule hours.")
Array.empty[String]
}
Then all the branches return Array[String] so that will be the type of the result.

Comparing four UITextFields' text property

I would like to compare four UITextFields' text property to make sure they are not the same. Ie:
tbx1.text = "hello"
tbx2.text = "goodbye"
tbx3.text = "goodnight"
tbx4.text = "hello"
should return a false but
tbx1.text = "hello"
tbx2.text = "goodbye"
tbx3.text = "goodnight"
tbx4.text = "good morning"
should return a true.
I know I could use a long and complicated if statement but I'm hoping there is a better way
One possible solution is to add all Strings to a Set and check the count of the set. If it is 4, all textfields had a different value, if it is less than 4, you had duplicates.
You can even generalise it to work with a different number of text fields as well. You just add all textfields' text property to an array, create a Set from the array then compare the number of elements in the two collections.
let textFieldValues = [tbx1.text!, tbx2.text!, tbx3.text!, tbx4.text!]
let textFieldSet = Set(textFieldValues)
if textFieldSet.count == textFieldValues.count {
print("No duplicates")
} else {
print("Some duplicates")
}

Counting two words in a string

I have to count two words 'cat' and 'dog' from a string.
If the counts are equal, I would like to return True else false.
For example, for input "dogdoginincatcat" my method should return True.
Here is my code,
def cat_dog(str):
count=0
count1=0
for i in range(len(str)):
if str[i:i+3] == 'cat':
count=count+1
if str[i:i+3] == 'dog':
count1=count+1
if count == count1:
return True
else:
return False
cat_dog('catdog')
just one line to do this using count on a string:
z= "dogdoginincatcat"
print(z.count("cat")==z.count("dog"))
First, DON'T use str (the string class) as a variable name. While Python won't cry at that very moment, you'll regret it later.
Second, it doesn't look like the count and count1 are indented as inside blocks of the 'if' statements, so your code is seen as:
for i in range(len(str))
if something:
pass
count = count + 1
if something_else:
pass
count1 = count1 + 1
Other than that, your code seems to work

How to fix a program that only works once?

def check_answer(self, currentscore):
self.user_entry = self.user_entry.get_text()
if self.user_entry == self.books:
self.current += 1
self.total += 1
self.currentscore = self.current
print "right"
else:
print "wrong"
print self.currentscore
print self.total
When i run it and i put text a second time is says File "C:\Python27\guessing.py", line 16, in check_answer
self.user_entry = self.user_entry.get_text()
AttributeError: 'str' object has no attribute 'get_text'
Could someone explain it to me. Why it to me why it only works once. and also why doesn't the program execute the if statement. It only says wrong.
self.books = 'hello'
You overwrite the variable holding the reference to the text box with its contents. So when check_answer runs for the first time, self.user_entry is your text box, and you can call its method get_text() to retrieve the text entered by the user. Unfortunately, you assign this text to the same variable (self.user_entry =) - so you loose the reference to the text box. After the first call, self.user_entry is a string (instance of str class) retrieved at the first call.
Use a different variable name, like this:
def check_answer(self, currentscore):
self.user_entry_text = self.user_entry.get_text()
if self.user_entry_text == self.books:
self.current += 1
self.total += 1
self.currentscore = self.current
print "right"
else:
print "wrong"
print self.currentscore
print self.total
Also, possibly it doesn't have to be class's field, so you can also skip the self. part. In such case you could use the same name (user_entry), but for sake of readability it's better to call a variable with a name that says precisely what the variable holds:
user_entry_text = self.user_entry.get_text()
if user_entry_text == self.books:

python: checking for errors in the users input

I would like
to check if a string can be a float before I attempt to convert it to a float. This way, if the
string is not float, we can print an error message and exit instead of crashing the
program.
so when the user inputs something, I wanna see if its a float so it will print "true" if its not then it will print"false" rather than crashing. I don't want to use built in functions for this. I need to make my own function for this.
I tried :
import types
def isFloat():
x = raw_input("Enter: ")
if(x) == float:
print("true")
if(x) == str:
print("false")
isFloat()
I don't know if its true or not but it wont work it wont print anything either
The recommended thing to do here is to try it:
try:
f = float(x)
print("true")
except ValueError:
# handle error here
print("false")
This underscores the Python philosophy "It's better to ask for forgiveness than for permission".
The only reliable way to figure out whether a string represents a float is to try to convert it. You could check first and convert then, but why should you? You'd do it twice, without need.
Consider this code:
def read_float():
"""
return a floating-point number, or None
"""
while True:
s = raw_input('Enter a float: ').strip()
if not s:
return None
try:
return float(s)
except ValueError:
print 'Not a valid number: %r' % s
num = read_float()
while num is not None:
... do something ...
print 'Try again?'
num = read_float()