0

Still very new to python. I have refactored a piece of coe and extracted the following code to a new method. It works fine but in search of more pythonic ways I feel the IF clauses are maybe clumsy. Essentially the function may be passed either a str or a number as the variable 'second_option' As a result there is a subtle difference to the next line.

I tried a conditional assignment but it seemed to get upset over the data frame elements of this.

    def create_crossover_data(self, indicator, second_option, market_data):
    if type(second_option) == str:
        market_data['position'] = market_data[indicator] > market_data[second_option]

    else:
        if type(second_option) == int or float:
            market_data['position'] = market_data[indicator] > second_option
        
    market_data['pre_position'] = market_data['position'].shift(1)
    market_data.dropna(inplace=True)  # dropping the NaN values
    market_data['crossover'] = np.where(market_data['position'] == market_data['pre_position'], False, True)
    market_data.drop(columns=['position', 'pre_position'])
kosh66
  • 60
  • 4
  • 1
    Note also: `if type(second_option) == int or float:` is likely not working how you think it is. See [How to test multiple variables against a single value?](https://stackoverflow.com/questions/15112125/how-to-test-multiple-variables-against-a-single-value) – G. Anderson Apr 19 '21 at 18:40

3 Answers3

3

Generally, in python, it is prudent to use isinstance instead of type. Type only checks that the exact type matches while isinstance checks if our object in question inherits from the given type.

Assuming your second if statement is trying to determine if the variable in question is a number you can use. This method: How can I check if my python object is a number?

Which in your case would be

else:
        if isinstance(second_option,numbers.Number):
            market_data['position'] = market_data[indicator] > second_option

Czarking
  • 143
  • 1
  • 10
  • Thanks. I will now go through all my code and remove type(). Learn a new thing every day here. – kosh66 Apr 19 '21 at 20:23
1

There is a way in Python to check the type of a variable: isinstance().

Here you have a couple of options to rewrite your code:

def create_crossover_data(self, indicator, second_option, market_data):
    if isinstance(second_option, str):
        threshold = market_data[second_option]
    if isinstance(second_option, (int, float)):
        threshold = second_option

    market_data['position'] = market_data[indicator] > threshold

The next one looks simpler but makes the assumption second_option can only be a number or a string, and that might not be true, so I would add some control to that:

def create_crossover_data(self, indicator, second_option, market_data):
    market_data['position'] = market_data[indicator] > second_option if isinstance(second_option, (int, float)) else market_data[second_option]
Carlos Melus
  • 1,472
  • 2
  • 7
  • 12
0

Also new to this, but I see nothing except else if -> elif