You have a working code, and you want it to be more clean, more pretty, more readable. This is what we call, refactoring. Here is a list of transformation to help you in this task. You can of course choose to apply the transformation or not. A "→" means the code will probably be more readable (according to me). A "↔" means the clarity will depend on the context (neither code is a priori more readable).
if CONDITION:
A
else:
B
# ↔
if not(CONDITION):
B
else:
A
if a == 5:
print("hello")
else:
waw = 2
# ↔ (invert if/else)
if not(a == 5):
waw = 2
else:
print("hello")
# ↔ (not == ↔ !=)
if a != 5:
waw = 2
else:
print("hello")
if CONDITION:
A
else:
pass # do nothing
# →
if CONDITION:
A
if a != 5:
print("hello")
else:
pass # do nothing
# → ("else do nothing" is useless)
if a != 5:
print("hello")
if a == 5:
pass # do nothing
else:
print("hello")
# → (invert if/else)
if a != 5:
print("hello")
else:
pass # do nothing
# → ("else do nothing" is useless)
if a != 5:
print("hello")
# De Morgan on "and"
if not(A and B):
...
# ↔
if (not A) or (not B):
...
# De Morgan on "or"
if not(A or B):
...
# ↔
if (not A) and (not B):
...
if not(a > 10 or a == 5):
print('hello')
# → (De Morgan)
if a <= 10 and a != 5:
print('hello')
if a > 10 or a == 5:
pass
else:
print('hello')
# → (invert if/else)
if not(a > 10 or a == 5):
print('hello')
else:
pass
# → ("else do nothing" is useless)
if not(a > 10 or a == 5):
print('hello')
# → (De Morgan)
if a <= 10 and a != 5:
print('hello')
if a < b:
print("hello")
if a >= b:
print("tada")
# → (à condition que a et b ne soient pas modifiés dans le if !)
if a < b:
print("hello")
else:
print("tada")
if CONDITION:
x = A
else:
x = B
# →
x = A if CONDITION else B
# →
x = (A if CONDITION else B)
# →
x = (A if CONDITION else
B)
if a == 5:
c = 2
else:
c = 0
# → ("one-line if" also called "ternary operator" or "functional if")
c = (5 if a == 5 else 0)
# ↔ (parenthesis are useless)
c = 5 if a == 5 else 0
if CONDITION:
x = A
elif CONDITION_2:
x = B
elif CONDITION_3:
x = C
else:
x = D
# →
x = (A if CONDITION else
B if CONDITION_2 else
C if CONDITION_3 else
D)
if a == 5:
c = 8
elif a == 2:
c = 4
elif a < 0:
c = 1
else:
c = 0
# → (functional if)
c = (8 if a == 5 else
4 if a == 2 else
1 if a < 0 else
0)
You can rename a variable to give it a name more explicit :
e = v * t
i = e / 2.56
# →
distance = velocity * time
distance_inch = distance / 2.56
Generally variable names of few letters are too short (except in mathematical expressions or well known variable names like the "i"
in a loop) and variable names with more than three real words are too long (a comment next to the variable creation will be probably better).
x = ...
operation(x)
# → (only possible if x is used only once)
operation(...)
x = size + 1 # x depends on the size
y = size - 1 # y depends on the size
the_coefficent = x + 2 * y # let's compute the coefficent using the linear formula
print(the_coefficent) # let's print it
# ↔ (inline variable "the_coefficent")
x = size + 1 # x depends on the size
y = size - 1 # y depends on the size
print(x + 2 * y) # let's print the result of the linear formula
# ↔ (inline variables "x" and "y")
print((size + 1) + 2 * (size - 1)) # let's print the result of the linear formula depending on the size
def f(...):
...
if CONDITION:
return True
else:
return False
# →
def f(...):
...
return CONDITION
if CONDITION:
res = True
else:
res = False
# →
res = CONDITION
def is_even(x):
if x % 2 == 0: # if the rest of division by 2 is 0
return True # Vrai, le nombre est pair
else: # sinon
return False # Faux, le nombre n'est pas pair
# → (boolean return)
def is_even(x):
return x % 2 == 0 # x is even iff the rest of division by 2 is 0
# :
if is_even(4):
...
if x % 2 == 0: # if the rest of division by 2 is 0
res = True # le résultat est Vrai, le nombre est pair
else: # sinon
res = False # le résultat est Faux, le nombre n'est pas pair
# → (boolean return)
res = (x % 2 == 0) # the result is true iff the rest of division by 2 is 0
# → (renaming)
is_even = (x % 2 == 0) # on nomme la variable de manière sémantique
# ↔ (parenthesis)
is_even = x % 2 == 0 # parenthèses non nécessaires
def vowel(x):
if x == 'a' or x == 'e' or x == 'i' or x == 'o' or x == 'u':
return True
else:
return False
# → (boolean return)
def vowel(x):
return x == 'a' or x == 'e' or x == 'i' or x == 'o' or x == 'u' # x is a vowel iff x is 'a', 'e', 'i', 'o', 'u'
# :
if vowel('a'): # if 'a' is a vowel
...
# given
def is_even(x):
if x % 2 == 0: # if the rest of division by 2 is 0
return True
else:
return False
# :
if is_even(4) == True: # si the is_even function returns True
...
# →
if is_even(4): # if 4 is even
...
if CONDITION:
A
elif CONDITION_2:
A # same A
# →
if CONDITION or CONDITION_2:
A
if a == 5:
x = 2
elif a > 10:
x = 2
# → (or)
if a == 5 or a > 10:
x = 2
if CONDITION:
A
elif CONDITION_2:
A # same A
else:
B
# →
if CONDITION or CONDITION_2:
A
else:
B
if a == 5:
x = 2
elif a > 10:
x = 2
else:
print('error')
# → (or)
if a == 5 or a > 10:
x = 2
else:
print('error')
def f(...):
...
if CONDITION:
return True
if CONDITION_2:
return True
return False
# →
def f(...):
...
return CONDITION or CONDITION_2
# ↔
def f(...):
...
return (CONDITION
or CONDITION_2)
def interesting(x):
if x > 10: # if x > 10
return True # it's interesting
if x == 5: # if x == 5
return True # it's interesting
return False # otherwise, it's not interesting
# → (or return)
def interesting(x):
return x > 10 or x == 5 # x is interesting if it's > 10 or 5
if CONDITION:
if CONDITION_2:
A
# →
if CONDITION and CONDITION_2:
A
if a == 5:
if a > 10:
print('waw')
# → (and)
if a == 5 and a > 10:
print('waw')
if CONDITION:
if CONDITION_2:
A
else:
B
else:
B # same b
# →
if CONDITION and CONDITION_2:
A
else:
B
if a == 5:
if b > 10:
waw = 2
else:
print('error')
else:
print('error')
# → (and)
if a == 5 and b > 10:
waw = 2
else:
print('error')
def f(...):
...
if CONDITION:
return X
...
# ↔
def f(...):
...
if CONDITION:
return X
else:
...
def f(x):
if x < 0:
return -1
else:
y = x + 2
z = y ** 2
return z
# → (if return)
def f(x):
if x < 0:
return -1
y = x + 2
z = y ** 2
return z
I generally do that when the "if"
is really short like a simple "return"
. Souvent, ce sont des cas particuliers ou des cas de base, le code du bas est plus intéressant.
# Here is how we code a "∃"
def f(...):
...
for x in L:
if condition: # this "if" DOESN'T have a "else"
return True
return False
# → (en python, il y a "all")
def f(...):
...
return any(condition for x in L)
# ↔
def f(...):
...
return any(condition
for x in L)
# Note: in python there is also the for...else but not so much people use it
def contains_a_negative(L):
for x in L: # for each element in the list
if x < 0: # if it's < 0
return True # the list contains_a_negative
return False # in the end, it means it doesn't contain one
# → (any)
def contains_a_negative(L):
return any(x < 0 for x in L)
We'll read it as A list L contains_a_negative if...
# Here is how we code a "∀"
def f(...):
...
for x in L:
if condition: # this "if" DOESN'T have a "else"
return False
return True
# → (en python, il y a "all")
def f(...):
return all(not condition for x in L)
# ↔
def f(...):
return all(not condition
for x in L)
# Note: in python there is also the for...else but not so much people use it
def totally_positive(L):
for x in L: # for each element in the list
if x < 0: # if it's < 0
return False # the list is not totally_positive
return True # in the end, the list is totally_positive
# → (all)
def totally_positive(L):
return all(x >= 0 for x in L)
We'll read it as A list L is totalement_positive if...
# De Morgan on "∀"
not all(condition for x in L)
# →
any(not condition for x in L)
# De Morgan on "∃"
not any(condition for x in L)
# →
all(not condition for x in L)
if not all(x >= 0 for x in L): # si on n'a pas tous les nombres >= 0
...
# → (if non empty)
if any(x < 0 for x in L): # c'est qu'il existe un nombre < 0
...
Attention: cette transformation ne marche pas si L est vide !
# Here is how one code a linear search
def f(...):
for x in L:
if condition:
return a
return b
# → (in python, one can use "next")
def f(...):
return next((a for x in L if condition), b)
# ↔
def f(...):
return next((a for x in L if condition),
b)
# Note: in python there is also the for...else but not so much people use it
Le super_nombre d'une liste est le premier x dans la liste tel que x > 10 :
def super_number(L):
for x in L: # for each element in the list
if x > 10: # if it's > 10
return x # it's the super_number of that list
return 0 # il n'y a pas de super nombre, on renvoie 0
# →
def super_number(L):
return next((x for x in L if x > 10), 0)
L = []
for x in iterable:
L.append(e)
# →
L = [e for x in iterable]
L = []
for x in iterable:
L.append(f(x))
# →
L = list(map(f, iterable))
# ↔
L = [f(x) for x in iterable]
L = []
for x in iterable:
if condition:
L.append(e)
# →
L = [e for x in iterable if condition]
L = []
for x in iterable:
if f(x):
L.append(x)
# →
L = list(filter(f, iterable))
# ↔
L = [x for x in iterable if f(x)]
for x in list(generator):
...
# →
for x in generator:
...
for x in list(map(f, L)): # map, filter, zip...
...
# →
for x in map(f, L):
...
# with
def operation(x):
return (x + 1) * 2 - x
# :
for x in list(map(operation, [1,2,3])):
print(x)
# →
for x in map(operation, [1,2,3]):
print(x)
s = 0
for x in L:
s += a
# → (sum)
s = sum(a for x in L)
# technically, "sum" is a particular case of "reduce" but "reduce" is a bit useless in python
s = ''
for x in L:
s += a
# → (join)
s = ''.join(a for x in L)
# technically, "join" is a particular case of "reduce" but "reduce" is a bit useless in python
if x == 'a' or x == 'e' or x == 'i' or x == 'o' or x == 'u':
...
# → (in)
if x in ('a', 'e', 'i', 'o', 'u'):
...
# it's a particular case of linear search in a list