kosh66
kosh66

Reputation: 70

easier way to do this IF statement to differentiate type of variable passed to function

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'])

Upvotes: 0

Views: 361

Answers (3)

user3568264
user3568264

Reputation: 13

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

Upvotes: 0

Carlos Melus
Carlos Melus

Reputation: 1552

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]

Upvotes: 1

Czarking
Czarking

Reputation: 143

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

Upvotes: 3

Related Questions