There are lots of answers already that speak in the general term of "What if does in programming," so let me boil your code out for you.
def valid_day(day):
if day and day.isdigit():#if day
if signifies the beginning of the if block, and works as the other answers have pointed out. What follows is the boolean expression day and day.isdigit(). and is a Boolean operator that requires both operands (both sides of the equation, in layman's terms) to be True in order to evaluate as True. In this case, both day and day.isdigit() must evaluate to True for the if block to run.
In Python, we think of things as "Truthy" and "Falsey." It's easier to define "Truthy" in terms of "Falsey," because the latter is a much shorter list:
None
- 0
- False
- [] "" {} () and the like
Everything else is "Truthy." If you type while -1: print("This loops forever") it will, in fact, loop forever. All non-zero numbers, all non-empty containers (strings, lists, dicts, sets, tuples, etc), anything not explicitly set to False or None will evaluate to True. In this case, the code is checking to make sure that day isn't None, because if it is then day.isdigit() will throw an AttributeError and break the code. You can try it yourself: type None.isdigit() in IDLE. Note that this is likely not the most foolproof implementation, since doing valid_day(31) will also throw AttributeError. valid_day requires a String, even though it's checking numbers.
day = int(day)
if day > 0 and day <= 31:
return day
This is actually repetitive code, since doing int(day) confirms day.isdigit(). If this is your code, perhaps consider a try: except block instead, such as:
def valid_day(day):
try: int(day)
except ValueError as e:
return False #this means whatever you passed to it can't be converted
#into an integer: maybe a floating point string?
if day in range(1,32): return True
else: return False
This will let you avoid the trap of checking for everything you know might fail. Instead, check to make sure your checks will be able to run, and let your program handle whatever you pass to it. This will also allow you to design a Day class that contains more information than an integer but will still return its calendar day using self.__int__(): return self.calendarday and valid_day(Day()) will return True. In addition, your current code returns None when you should be returning False -- as I mentioned above, None is Falsey, so in most cases this will work (e.g. if not valid_day: do_something_drastic()) but in some cases you may want to deal with a boolean directly.
Okay, there's a mouthful of words for you.
TL;DR: if starts the if block, day and day.isdigit() is true only when day is a non-empty string that contains an integer, and the rest does what it says it does.
if 0 < day <= 31.