I have a table that I need to do multiple nested if else it appears that only the last if else is used and field only gets populated with 15, there are some that meet the 25,35 and 45 but they don't get updated.
what am I doing wrong?
where = "AppType = 'SFR Active'"
with arcpy.da.UpdateCursor(table1, ["Field1","Field12","Field3","Field4","Field5", "Field6", "Field7","Field8"], where) as cursor:
for row in cursor:
#if row[0] is None:
#continue
if row[0] == "Approved" and row[1] == "Approved" and row[2] == "Approved" and row[3] is not None and row[4] == "Pass":
row[7] = 15
else:
row[7] = 0
if row[3] == "In_1" and row[4] == "Pass":
row[7] = 25
else:
row[7] = 15
if row[3] == "In_2" and row[4] == "Pass":
row[7] = 35
else:
row[7] = 25
if row[3] == "In_3" and row[4] == "Pass":
row[7] = 45
else:
row[7] = 35
cursor.updateRow(row)
Try adding some print statements to help you debug. In your else, print row[3] and row[4] so you can see what values it's actually getting.
Good, call. I am seeing the the prints now.
Your code won't cover all cases I suspect, but what you have is muddled a bit...
for row in cursor:
if row[0] == "Approved" and row[1] == "Approved" and row[2] == "Approved":
if row[3] == "In_1":
if row[4] == "Pass":
row[7] = 25
else:
row[7] = 15
elif row[3] == "In_2":
if row[4] == "Pass":
row[7] = 35
else:
row[7] = 25
elif row[3] == "In_3":
if row[4] == "Pass":
row[7] = 45
else:
row[7] = 35
elif row[3] is not None:
if row[4] == "Pass":
row[7] = 15
else:
row[7] = 9
else:
???????????????
You will have to decide what to do if none of the remaining cases aren't met.
You would be better off constructing all possible combinations and using a dictionary to return what you want to use for the two remaining fields.
Thank you for the visual of formatting the if, elf and else.
Line 24 would just be "Pass", so i can continue.
Just another version using Dan's dictionary suggestion:
valDict = {"In_1": 25, "In_2": 35, "In_3": 45, ...}
with arcpy.da.UpdateCursor(table1, ["Field1", "Field12", "Field3", "Field4", "Field5", "Field6", "Field7", "Field8"],
where) as cursor:
for row in cursor:
# if row[0] is None:
# continue
if all([row[0] == "Approved", row[1] == "Approved", row[2] == "Approved", row[3] is not None, row[4] == "Pass"]):
row[7] = 15
else:
row[7] = valDict.get(row[3]) if row[4] == "Pass" else valDict.get(row[3], 10) - 10
This will point out which In_i values are not in the dictionary by assigning them 0, or subtract the 10 if row[4] does not equal 'Pass' for that row.
Interesting, I will have to try to use the dictionary option.
Jeffk,
I was trying to impalement your suggestion but I am having trouble getting the code to work.
Hopefully I can explain it correctly, I would really appreciate the help to understand dictionaries in this type of situations.
If reviews 1-4 equal approved then, progress filed = 15%, if three out of the four review are pass then Progress field = 0%
If Reviews1-4 fields = Approved & Event field = Foundation or Setback or Shear Panel 1 & EventRes1 field = Pass, then Progress field = 15%, if if Reviews1-4 = Approved & Event field = Foundation or Setback or Shear Panel 1 & EventRes1 field = Needs corrections or In progress or partial Pass or Cancelled, then progress field = 15%
if If Reviews1-4 fields = Approved & Event field = Framing or BC- Framing & EventRes1 field = Pass, then Progress field = 50%, if If Reviews1-4 fields = Approved & Event field = Framing or BC- Framing & EventRes1 field = Needs corrections or In progress or partial Pass or Cancelled, then progress, then progress field = 25%
if If Reviews1-4 fields = Approved & Event field = Insulation or Stucco & EventRes1 field = Pass, then Progress field = 75%, if If Reviews1-4 fields = Approved & Event field = Insulation & EventRes1 field = Needs corrections or In progress or partial Pass or Cancelled, then progress, then progress field = 50%
if If Reviews1-4 fields = Approved & Event field = Final & EventRes1 field = Pass, then Progress field = 100%, if If Reviews1-4 fields = Approved & Event field = Final & EventRes1 field = Needs corrections or In progress or partial Pass or Cancelled, then progress, then progress field = 75%
If both fields "Certif", "CertifDate" are populated , then Progress = 100%
Some fields are blank.
Haven't had time to try to digest this yet... I think it would help if you break this down a little further though since the mixing of 'if if', &, =, and 'then' makes it kind of hard to follow. I'd suggest to write these as if statements, so it will show what you are comparing as a conditional and what is done if it is met.
@CCWeedcontrol, there are some gaps in the explanation of your logic there, but here's another take on evaluating your progress field. I organized evaluation of the larger groups separately to make the evaluation of the progress field a little easier to follow. Please correct as needed to clarify logic gaps.
# Get arcpy.da cursor rows back as dictionary with field names
# https://arcpy.wordpress.com/2012/07/12/getting-arcpy-da-rows-back-as-dictionaries/
def rows_as_dicts(cursor):
colnames = cursor.fields
for row in cursor:
yield dict(zip(colnames, row))
fields = [
"reviewField1",
"reviewField12",
"reviewField3",
"reviewField4",
"EventField",
"EventRes1",
"Certif",
"CertifDate",
"ProgressFiledField"
]
where = "AppType = 'SFR Active'"
with arcpy.da.UpdateCursor(table1, fields, where) as cursor:
for row in rows_as_dicts(cursor):
# Evaluate Review fields
review_approved_count = [
row["reviewField1"],
row["reviewField12"],
row["reviewField3"],
row["reviewField4"]
].count("Approved")
# Evaluate Event
eventField = row["EventField"]
if eventField in ["Foundation", "Setback", "Shear Panel 1"]:
event_state = "Foundation"
elif eventField in ["Framing" or "BC- Framing"]:
event_state = "Framing"
elif eventField in ["Insulation" or "Stucco"]:
event_state = "Insulation"
elif eventField in ["Final"]:
event_state = "Final"
else:
raise Exception(f"EventField value {eventField} not handled.")
# Evaluate eventRes1
eventRes1 = row["EventRes1"]
if eventRes1 in ["Needs corrections", "In progress", "partial Pass", "Cancelled"]:
eventRes1_state = "Not Passed"
elif eventRes1 == "Pass":
eventRes1_state = "Pass"
else:
raise Exception(f"EventRes1 value {eventRes1} not handled.")
# Evaluate Progress
progress_filed = row["ProgressFiledField"]
if review_approved_count == 4:
if event_state == "Foundation":
# Doesn't matter what EventRes1 is?
progress_filed = "15%"
elif event_state == "Framing":
if eventRes1_state == "Passed":
progress_filed = "50%"
else:
# eventRes1 not passed
progress_filed = "25%"
elif event_state == "Insulation":
if eventRes1_state == "Passed":
progress_filed = "75%"
else:
# eventRes1 not passed
progress_filed = "50%"
elif event_state == "Final":
if eventRes1_state == "Passed":
progress_filed = "100%"
else:
# eventRes1 not passed
progress_filed = "75%"
else:
# review_approved_count < 4 and
# doesn't matter what EventField or EventRes1 are.
progress_filed = "0%"
# These dates override all other logic evaluations?
if row["Certif"] and row["CertifDate"]:
progress_filed = "100%"
# Update row with progress.
row["ProgressFiledField"] = progress_filed
row_values = list(row.values())
cursor.updateRow(row_values)