Skip to content

Commit

Permalink
Merge pull request #609 from realpython/expressions-vs-statements
Browse files Browse the repository at this point in the history
Materials for Python Expressions vs Statements
  • Loading branch information
brendaweles authored Nov 19, 2024
2 parents a046f4e + a68d9d7 commit d70d127
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 0 deletions.
66 changes: 66 additions & 0 deletions expressions-vs-statements/README.md
Original file line number Diff line number Diff line change
@@ -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
```
31 changes: 31 additions & 0 deletions expressions-vs-statements/code_inspector.py
Original file line number Diff line number Diff line change
@@ -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
11 changes: 11 additions & 0 deletions expressions-vs-statements/echo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <stdio.h>

int main() {
int x;
while (x = fgetc(stdin)) {
if (x == EOF)
break;
putchar(x);
}
return 0;
}
24 changes: 24 additions & 0 deletions expressions-vs-statements/generators.py
Original file line number Diff line number Diff line change
@@ -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()
19 changes: 19 additions & 0 deletions expressions-vs-statements/gui_app.py
Original file line number Diff line number Diff line change
@@ -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()
24 changes: 24 additions & 0 deletions expressions-vs-statements/hex_reader.py
Original file line number Diff line number Diff line change
@@ -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())

0 comments on commit d70d127

Please sign in to comment.