diff --git a/expressions-vs-statements/README.md b/expressions-vs-statements/README.md new file mode 100644 index 0000000000..ace4085f6e --- /dev/null +++ b/expressions-vs-statements/README.md @@ -0,0 +1,66 @@ +# Expression vs Statement in Python: What's the Difference? + +This folder contains sample code from the Real Python tutorial [Expression vs Statement in Python: What's the Difference?](https://realpython.com/python-expression-vs-statement/) + +## Code Inspector + +Identify whether a piece of Python code is an expression or a statement: + +```shell +$ python code_inspector.py +Type a Python code snippet or leave empty to exit. +>>> yield +statement +>>> (yield) +expression +>>> 2 + +invalid +``` + +## GUI App + +Register a lambda expression as a callback, which delegates to a function with statements: + +```shell +$ python gui_app.py +``` + +## Echo Program + +Compile with a C compiler and pipe stdin to the echo program: + +```shell +$ gcc echo.c -o echo.x +$ echo "Hello, World!" | ./echo.x +Hello, World! +``` + +## HEX Reader + +Read a binary file and display its bytes in hexadecimal format: + +```shell +$ python hex_reader.py /path/to/HelloJava.class --columns 8 +ca fe ba be 00 00 00 41 +00 0f 0a 00 02 00 03 07 +00 04 0c 00 05 00 06 01 +(...) +``` + +## Generators + +Generate a random signal and use a low-pass filter to make it smooth: + +```shell +$ python generators.py +-0.96: -0.96 +-0.81: -0.89 +-0.52: -0.67 + 0.22: -0.15 + 0.51: 0.37 + 0.40: 0.46 +-0.08: 0.16 +-0.24: -0.16 + 0.80: 0.28 + 0.47: 0.64 +``` diff --git a/expressions-vs-statements/code_inspector.py b/expressions-vs-statements/code_inspector.py new file mode 100644 index 0000000000..b91a1eff77 --- /dev/null +++ b/expressions-vs-statements/code_inspector.py @@ -0,0 +1,31 @@ +import ast + + +def main(): + print("Type a Python code snippet or leave empty to exit.") + while code := input(">>> "): + print(describe(code)) + + +def describe(code): + if valid(code, mode="eval"): + return "expression" + elif valid(code, mode="exec"): + return "statement" + else: + return "invalid" + + +def valid(code, mode): + try: + ast.parse(code, mode=mode) + return True + except SyntaxError: + return False + + +if __name__ == "__main__": + try: + main() + except EOFError: + pass diff --git a/expressions-vs-statements/echo.c b/expressions-vs-statements/echo.c new file mode 100644 index 0000000000..99c9b342d7 --- /dev/null +++ b/expressions-vs-statements/echo.c @@ -0,0 +1,11 @@ +#include + +int main() { + int x; + while (x = fgetc(stdin)) { + if (x == EOF) + break; + putchar(x); + } + return 0; +} diff --git a/expressions-vs-statements/generators.py b/expressions-vs-statements/generators.py new file mode 100644 index 0000000000..a324e00bd2 --- /dev/null +++ b/expressions-vs-statements/generators.py @@ -0,0 +1,24 @@ +import random + + +def main(): + lf = lowpass_filter() + lf.send(None) + for value in generate_noise(10): + print(f"{value:>5.2f}: {lf.send(value):>5.2f}") + + +def generate_noise(size): + for _ in range(size): + yield 2 * random.random() - 1 + + +def lowpass_filter(): + a = yield + b = yield a + while True: + a, b = b, (yield (a + b) / 2) + + +if __name__ == "__main__": + main() diff --git a/expressions-vs-statements/gui_app.py b/expressions-vs-statements/gui_app.py new file mode 100644 index 0000000000..0a995bb6b7 --- /dev/null +++ b/expressions-vs-statements/gui_app.py @@ -0,0 +1,19 @@ +import tkinter as tk + + +def main(): + window = tk.Tk() + button = tk.Button(window, text="Click", command=lambda: on_click(42)) + button.pack(padx=10, pady=10) + window.mainloop() + + +def on_click(age): + if age > 18: + print("You're an adult.") + else: + print("You're a minor.") + + +if __name__ == "__main__": + main() diff --git a/expressions-vs-statements/hex_reader.py b/expressions-vs-statements/hex_reader.py new file mode 100644 index 0000000000..904719a27f --- /dev/null +++ b/expressions-vs-statements/hex_reader.py @@ -0,0 +1,24 @@ +import argparse +import itertools + +MAX_BYTES = 1024 + + +def main(args): + buffer = bytearray() + with open(args.path, mode="rb") as file: + while chunk := file.read(MAX_BYTES): + buffer.extend(chunk) + for row in itertools.batched(buffer, args.columns): + print(" ".join(f"{byte:02x}" for byte in row)) + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument("path") + parser.add_argument("-c", "--columns", type=int, default=16) + return parser.parse_args() + + +if __name__ == "__main__": + main(parse_args())