I appreciate thoughts and feedback on the following idea.
Idea:
To abstract sequential execution of the for loop using $
(or another suitable) symbol, such as: $iterable$
This translates into sequential python statements, all exactly the same, except the iterator value updates. So while *
is unpacking in the horizontal way within a statement, $
can be thought of unpacking statements themselves in a vertical way.
Definition:
Code example 1:
#Current
for name in names:
print(name)
is equivalent in execution to
#Proposed
print($names$)
Code example 2:
#Current:
for firstname, lastname in zip(firstnames, lastnames):
print(firstname, lastname)
is equivalent in execution to
#Proposed:
print( $firstnames$, $lastnames$ )
Code example 3: Nested loops are specified using a numeric parameter before $
.
#Current:
for item in items:
for size, color in zip(sizes, colors):
print(item, size, color)
is equivalent in execution to
#Proposed:
print( $items$, 2$sizes$, 2$colors$ )
Whenever in doubt about the rules, the developer can imagine the (nested) for loops.
Examples and features:
Example 1:
#Current, method 1:
total = 0
for number in numbers:
total += number
#Current, method 2:
total = sum(numbers)
#Proposed:
total = 0
total += $numbers$
Example 2:
#Current:
my_dict = dict(zip(keys, values))
#Proposed:
my_dict = {}
my_dict[$keys$] = $values$
Example 3:
#Current method 1:
filtered = []
for value in values:
filtered += [] if value>5 else [value]
#Current method 2:
filtered = [value for value in values if value <= 5]
#Current method 3:
filtered = list(filter(lambda value: value<=5, values))
#Proposed method 1:
filtered = []
filtered += [] if $values$ >5 else [$values$]
#Proposed method 2:
filtered = []
if $values$ <= 5: filtered += [$values$]
Example 4: Notice how examples 3, 4 use the more advanced functional programming which can be simplified using the proposed method and basic commands. Also, notice how in map, developer is required to break the flow of thought that they want to apply a function to a list of arguments, so now they have to treat f as an argument itself to the function map. But in proposed way, developer follows the usual pattern of thought of calling a function with its arguments in parenthesis in front of it.
#Current:
g = map(f, sequence)
#Proposed:
g = []
g.append(f($sequence$))
Example 5: Note that there is no need to copy the same iterable in the proposed way
#Current:
fibo = [1,1]
for i in range(2,10):
fibo.append( fibo[i-1] + fibo[i-2] )
#Proposed:
fibo = [1,1]
rng = range(2,10)
fibo.append( fibo[$rng$-1] + fibo[$rng$-2] )
Example 6: Current method requires developer to decompose the variables into each component to get a clear print statement for debugging. But in the proposed way, simply, the parenthesis and arguments in front of fly can be copied and modified.
#Current:
print(fâDebug variable {âspeedâ} is {speed}â)
print(fâDebug variable {âaltitudeâ} is {altitude}â)
print(fâDebug variable {âangleâ} is {angle}â)
fly(speed, altitude, angle)
#Proposed:
print(fâDebug variable {$(âspeedâ, âaltitudeâ, âangleâ)$} is {$(speed, altitude, angle)$})
fly(speed, altitude, angle)
Example 7:
#Current method 1:
for color in colors:
for size in sizes:
print(color, size)
#Current method 2:
from itertools import product
for color,size in product(colors, sizes):
print(color,size)
#Proposed:
print($colors$, 2$sizes$)
Example 8: Using inline assignments, shortens the expression.
#Current:
for i in range(rows):
for j in range(cols):
transposed[j][i] = matrix[i][j]
#Proposed:
transposed[j := $range(cols)$][i := $range(rows)$] = matrix[i][j]
Example 9: Code repeats for the entire block (this can be obvious if the for loop structures which we are abstracting away can be imagined.)
If there is nested blocks, we put the imaginary loops before the first one with $. Examples 9 and 10 clarify this.
#Current:
for student, grade in zip(students, grades):
if grade > 50:
print(fâ{student} passedâ)
#Proposed:
if $(grades) > 50:
print(fâ{$students$} passedâ)
Example 10: Clarifying example
#Current:
for student, grade, age in zip(students, grades, ages):
if grade > 50:
if age > 5:
print(fâ{student} passedâ)
#Proposed:
if $grades$ > 50:
if $ages$ > 5:
print(fâ{$students$} passedâ)