-2

Currently stuck with this syntax error, error is posted below the code.

@property
def data_rows(self):
    for d in rlgenevautils.to_csv_dict(self.data_file):
        trade_dt  = rlcore.str2dt(d['EventDate'])
        settle_dt = rlcore.str2dt(d['ActualSettleDate'])

        yield (str(d['_UDF_SGCP_ID_'])
              ,str(d['_UDF_Execution_ID_'])
              ,str(d['_UDF_PB_ID_'])
              ,str(d['_UDF_Fund_Admin_ID_'])
              ,str(d['_Portfolio_NameSort_'])
              ,str(d['_Strategy_Code_'])
              ,str(d['_LocationAccount_NameSort_'])
              ,str(d['_Broker_NameSort_'])
              ,str(d['_Investment_Code_'])
              ,trade_dt.isoformat(' ')
              ,settle_dt.isoformat(' ')
              ,rlcore.str2float(d['ABSQuantityForCalcCurrentFace'])
              ,max(rlcore.str2float(d['ABSQuantityForCalcCurrentFace']),rlcore.str2float(d['OriginalFace']))
              ,rlcore.str2float(d['ABSQuantityForCalcCurrentFace'])/max(rlcore.str2float(d['ABSQuantityForCalcCurrentFace']),rlcore.str2float(d['OriginalFace']))
              ,rlcore.str2float(d['Price'])
              ,rlcore.str2float(d['ABSAccruedInterestForCalcCurrentFace'])
              ,if str(d['_Investment_InvestmentGroup_']) == "AssetBacked":
                   rlcore.str2float(d['ABSQuantityForCalcCurrentFace']) * rlcore.str2float(d['Price']) / 100
               else:
                   rlcore.str2float(d['NetCashAmount'])
              ,rlcore.str2float(d['ABSAccruedInterestForCalcCurrentFace']) + rlcore.str2float(d['txtNetCashPreAccrued'])
              )

Traceback (most recent call last):
    File ".\sg\rec_and_liquidity\geneva_trade.py", line 64
      ,if str(d['_Investment_InvestmentGroup_']) == "AssetBacked":
       ^

Code above, unable to figure out what my syntax error is on the if statement. Error message will be pasted as comment shortly

user3428722
  • 71
  • 1
  • 1
  • 4
  • Please edit the original post with the error. The comment box strips out whitespace, which may be useful in diagnosing the problem. – Kevin Sep 02 '14 at 18:42
  • Ok, one momenti will update shortly – user3428722 Sep 02 '14 at 18:43
  • 1
    It looks like you are trying to `yield` with an inline `if`. What you have is not the correct syntax. [This answer](http://stackoverflow.com/a/11880682/651848) shows how to do an inline `if`. – rkyser Sep 02 '14 at 18:43
  • Thanks, I'll take a look at this now. Learning on the job today. – user3428722 Sep 02 '14 at 18:45
  • As a side note, it looks like you're making a lot of things more complicated than they need to be. For example, what is `d['_Investment_InvestmentGroup_']`? If it's already a `str`, why are you calling `str` on it? More generally, there's probably a good way to define the types of each "column" and convert them all in a simple expression instead of one massive ugly thing like this. – abarnert Sep 02 '14 at 18:45
  • 2
    Side note: it's a little weird to put the commas at the beginning of the line instead of the end. – SethMMorton Sep 02 '14 at 18:46

3 Answers3

1

The problem is that you can't put a statement in the middle of an expression.


For simple cases, there is an if expression that, being an expression, can be used in the middle of an expression. In your case:

(rlcore.str2float(d['ABSQuantityForCalcCurrentFace']) * rlcore.str2float(d['Price']) / 100
 if str(d['_Investment_InvestmentGroup_']) == "AssetBacked"
 else rlcore.str2float(d['NetCashAmount']))

For more complicated cases, move the if statement upward and store a temporary value in a variable, then use that variable in the expression (exactly as you're already doing for, each, trade_dt):

if str(d['_Investment_InvestmentGroup_']) == "AssetBacked":
    priceval = rlcore.str2float(d['ABSQuantityForCalcCurrentFace']) * rlcore.str2float(d['Price']) / 100
else:
    priceval = rlcore.str2float(d['NetCashAmount'])

… then just use priceval in the yield.


However, no matter how you solve this, your code is a huge unreadable mess. You have at least three different conversion methods you're using repeatedly; if you discover that you're formatting dates or strings or whatever wrong, you'll need to change that in dozens of places. You'd probably do better off with a mapping of column names to either types, or converters, and then just generate the values by dynamically looking up each converter. For example:

_COLUMNS = {'_UDF_SGCP_ID_': str,
            '_UDF_Execution_ID_': str,
            # ...
            'EventDate': datetime.datetime,
            # ...
            }

_CONVERTERS = {str: str, 
               datetime.datetime: lambda val: rlcore.str2dt(val).isoformat(),
               # ...}

def _converted(d, col):
    val = d[col]
    converter = _CONVERTERS[_COLUMNS[col]]
    return converter(val)

And now you can just do this:

yield(_converted(d, col) for col in (        
    '_UDF_SGCP_ID_',
    '_UDF_Execution_ID_',
    # ...
)
abarnert
  • 354,177
  • 51
  • 601
  • 671
1

You can't include an if statement inside an expression like that. If you want to include it in an expression, you need to use a conditional expression:

(rlcore.str2float(d['ABSQuantityForCalcCurrentFace']) * rlcore.str2float(d['Price']) / 100) if str(d['_Investment_InvestmentGroup_']) == "AssetBacked" elserlcore.str2float(d['NetCashAmount'])

However, this is not very readable. It would be better to move your if statement to before the yield, assign the result to a variable, and use that variable in the yield.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
1

'if' is a statement, and creating tuple this way you can use only expressions.

Change your code like follows:

if condition:
   something
else:
   something2

to

 something if condition else something2
kitek
  • 117
  • 1
  • 13