I recently came across the function ip.input_transformers_cleanup
and realized that this function can be used to add some convenient custom syntax to IPython and Jupyter sessions.
And here are some ideas.
Firstly, comments could be used to manipulate the code:
- run a line twice without the need of a for loop:
print("Hello") # TWICE
(full example below)
- don’t run a line by adding a ‘# NOT’ in the end of it :
print("World") # NOT
(full example below)
- delete a variable after two more cells are executed:
k = 5 # DEL after 2 cells
- inline function definitions like this
x = 34 # def foo
x + 10 # RETURN
- Ask ChatGPT for alternative code on a certain line:
h = "hello world" # @GPT: How can I capitalize the first letter here?
print(h)
Secondly, code itself could be manipulated:
- One could use emojis, e.g.
print(💯)
or plt.plot([1, 2], marker=⭐)
.
The input transformer will replace the emojis (or other custom strings) by the correct code. The translation dict can be provided by the users. Prototype implementation here.
- A play_sound function can be added to play a sound in the end of the cell execution.
- A play_sound function can be added to play a sound after every executed line.
- Add a function
order_pizza
after 1000 lines of code are executed.
This is just a thought experiment to explore what is theoretically possible.
Feel free to add things to the list!
def double_run(lines):
new_lines = []
for line in lines:
new_lines.append(line)
if "# TWICE" in line:
new_lines.append(line)
return new_lines
def dont_run(lines):
new_lines = []
for line in lines:
if not "# NOT" in line:
new_lines.append(line)
return new_lines
ip = get_ipython()
ip.input_transformers_cleanup.append(double_run)
ip.input_transformers_cleanup.append(dont_run)
print("Hello") # TWICE
print("World") # NOT
Out:
Hello
Hello
2 Likes
Another idea: inline cell-loops like this.
x = 10 # @modify x = [11,12,13]
print(x)
Out:
10
11
12
13
A working prototype for this example can be found in the code below.
I can imagine that this kind of inline cell-loops can be useful for quick testing of multiple parameters, without the need to re-write a cell in a normal for loop.
Instead, one can add this comment and remove it after the tweaked parameter is found.
import re
def trim_whitespace(s):
s = s.lstrip(" ")
s = s.rstrip(" ")
return s
def create_modified_variable_list(originial_string):
string = originial_string.rstrip("\n")
string = trim_whitespace(string)
part1, part2 = string.split("# @modify")
part1 = trim_whitespace(part1)
part2 = trim_whitespace(part2)
# in part 1, find everything before the equal sign
match1 = re.search(r'(.+)\s*=', part1)
if match1:
before_equal1 = match1.group(1)
before_equal1 = trim_whitespace(before_equal1)
# print(before_equal1)
# in part 2, find everything before the equal sign
match2a = re.search(r'(.+)\s*=', part1)
if match2a:
before_equal2 = match2a.group(1)
before_equal2 = trim_whitespace(before_equal2)
# print(before_equal2)
# in part 2, find everything after the equal sign and in the square brackes
match2b = re.search(r'=\s*\[(.+)\]', string)
if match2b:
inside_brackets = match2b.group(1)
inside_brackets = inside_brackets.split(",")
inside_brackets = [trim_whitespace(s) for s in inside_brackets]
else:
print('No match found.')
# check the variable that should be replaced
modified_lines = []
if before_equal1 == before_equal2:
for param in inside_brackets:
modified_lines.append(f"{before_equal1} = {param} \n")
return modified_lines
def create_modified_cells(original_lines):
ref_lines = original_lines.copy()
replacements = []
multi_lines = []
for num, line in enumerate(original_lines):
if "# @modify " in line:
replacements = create_modified_variable_list(line)
my_index = num
for replacement in replacements:
variation_lines = ref_lines.copy()
variation_lines[my_index] = replacement
multi_lines.append(variation_lines)
return multi_lines
# NEXT 14 LINES ONLY DEBUGGING CODE
my_lines = [
'z = 3 \n',
'x = 10 # @modify x = [11,12,13,14]\n',
'y = x+x+z\n',
'print(y)\n'
];
modfied_cells = create_modified_cells(my_lines)
for number, modfied_cell in enumerate(modfied_cells):
code_to_execute = "".join(modfied_cell)
print(f"Variation {number}:")
exec(code_to_execute)
# debugging over.
# Register ipython input transformer
def iterate_run(lines):
modfied_cells = create_modified_cells(lines)
# print(modfied_cells)
for number, modfied_cell in enumerate(modfied_cells):
code_to_execute = "".join(modfied_cell)
print(f"Variation {number}:")
exec(code_to_execute)
return lines
ip = get_ipython()
ip.input_transformers_cleanup.append(iterate_run)