python compare two fields, update a third

867
4
Jump to solution
07-22-2019 12:33 PM
NickO_Day
New Contributor III

I'm trying to compare two fields to each other and then use that information to update a third field.  Here are the fields that I have in my data:

      Field A:  Direction (numeric)

      Field B:  Bearing (numeric)

      Field C:  KeepDiscardFlag (text)

Below is the code that I've tried based on other discussions in GeoNet, but it doesn't work (errors out saying that it couldn't evaluate the python expression).  What I'm trying to do is this:

  1. Make sure that Direction and Bearing are not null
  2. Set the KeepDiscardFlag field to "Keep" if Bearing is between Direction (plus or minus 22.5), or
  3. Set the KeepDiscardFlag field to "Delete" if Bearing is not between Direction (plus or minus 22.5)

Expression

Reclass(!KeepDiscardFlag!, !Direction!, !Bearing!)

Code Block

def Reclass(KeepDiscardFlag, Direction, Bearing):
    if ( (Direction is None or Bearing is None) and (Direction - 22.5) <= Bearing <= (Direction + 22.5) :(
      KeepDiscardFlag = "Keep"
   elif ( (Direction is None or Bearing is None) or (Direction - 22.5) >= Bearing >= (Direction + 22.5) :(
      KeepDiscardFlag = "Delete"

Any help would be greatly appreciated!

Tags (2)
1 Solution

Accepted Solutions
LanceCole
MVP Regular Contributor

Nick,

1) When you have a question it is better to post as a question.  You will get a better response.

2) looking at your logic, it needs some work as it very hard to follow and your text does not match your code. 

def Reclass(Direction, Bearing):
  if Direction and Bearing:
    if abs(Direction - Bearing) <= 22.5:
      return "Keep"
    elif abs(Direction - Bearing) > 22.5:
      return "Delete"
  else:
    return "None"‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

When you call your function use Reclass(!Direction!, !Bearing!) as you will be setting the value for !KeepDiscardFlag! using the return statement.  I added a "None" return if Direction or Bearing are either None or Null.  The logic also does not address bearing and direction values around north such as 350 and 10.  The difference is 20 in actual degrees but the math (350-10) is 340, it would return "Delete".

View solution in original post

4 Replies
LanceCole
MVP Regular Contributor

Nick,

1) When you have a question it is better to post as a question.  You will get a better response.

2) looking at your logic, it needs some work as it very hard to follow and your text does not match your code. 

def Reclass(Direction, Bearing):
  if Direction and Bearing:
    if abs(Direction - Bearing) <= 22.5:
      return "Keep"
    elif abs(Direction - Bearing) > 22.5:
      return "Delete"
  else:
    return "None"‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

When you call your function use Reclass(!Direction!, !Bearing!) as you will be setting the value for !KeepDiscardFlag! using the return statement.  I added a "None" return if Direction or Bearing are either None or Null.  The logic also does not address bearing and direction values around north such as 350 and 10.  The difference is 20 in actual degrees but the math (350-10) is 340, it would return "Delete".

NickO_Day
New Contributor III

Hi Lance,

Thanks for the help.  I was trying to write the code as explicitly as possible to explain what I'm doing, but appreciate your cleaning it up.  That was perfect!

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

If one of Lance's responses answered your question, please "Mark Correct" to both give credit and close out the question.

0 Kudos
LanceCole
MVP Regular Contributor

Nick O'Day

I revised the code to handle values around north, such as Reclass(350,10) and return the correct data.  This can be reduced to just a few lines but for readability I left it longer.

def Reclass(Direction, Bearing):
  if Direction and Bearing:
    delta = abs(Direction - Bearing) % 360
    delta = 360-delta if delta>180 else delta
    if delta <= 22.5:
      return "Keep"
    elif delta > 22.5:
      return "Delete"
  else:
    return "None"