Skip to content

Commit f7d26c6

Browse files
committed
2 parents 9b5dde0 + ef919b6 commit f7d26c6

File tree

14 files changed

+773
-12
lines changed

14 files changed

+773
-12
lines changed

apps/net/Ch5_nuget/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public static void GetTitleRange()
3434
Console.ForegroundColor = ConsoleColor.White;
3535
}
3636

37-
public static string GetEpisodeHtml(int episodeNumber, string url = null)
37+
public static string GetEpisodeHtml(int episodeNumber, string url = null)
3838
{
3939
if (string.IsNullOrEmpty(url))
4040
{

apps/net/Ch9_Async/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class MainClass
1313
public static void Main()
1414
{
1515
Console.ForegroundColor = ConsoleColor.White;
16-
Console.WriteLine("Concurrent Web Scraper.");
16+
Console.WriteLine("C# Concurrent Web Scraper.");
1717
var sw = Stopwatch.StartNew();
1818

1919
GetTitleRange().Wait();

apps/py/.idea/dictionaries/screencaster.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/py/ch07_web/guitary/app.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
import os
2+
import sys
3+
4+
folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
5+
sys.path.insert(0, folder)
6+
17
import flask
28
from guitary.services import catalog_service
39

apps/py/ch07_web/wsgi.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from guitary.app import app
2+

apps/py/ch08_db/guitary/app.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,18 @@ def guitars(style: str = None):
2424
return flask.render_template('guitars.html', guitars=guitar_list)
2525

2626

27-
def main():
27+
def configure():
2828
session_factory.global_init('guitary.sqlite')
2929
session_factory.create_tables()
3030
data_loader.load_guitars_if_empty()
3131

32+
33+
def main():
34+
configure()
3235
app.run(debug=True)
3336

3437

3538
if __name__ == '__main__':
3639
main()
40+
else:
41+
configure()

apps/py/ch10_async/ascrape.py

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,34 @@
11
from colorama import Fore
22
import httpx
33
import bs4
4+
import datetime
5+
from unsync import unsync
46

57

68
def main():
7-
print("Using Python packages")
9+
print("Python async web scraper")
810

9-
get_titles()
11+
t0 = datetime.datetime.now()
12+
get_titles().result()
13+
dt = datetime.datetime.now() - t0
14+
print(f"Finished in {dt.total_seconds():,.2f} seconds.")
1015

1116

12-
def get_html(n: int) -> str:
17+
@unsync
18+
async def get_html(n: int) -> str:
1319
print(Fore.YELLOW + f"Getting HTML for episode {n}...", flush=True)
1420
url = f'https://talkpython.fm/{n}'
1521

16-
resp = httpx.get(url)
17-
resp.raise_for_status()
22+
# The "async with" syntax ensures that all active connections are closed on exit.
23+
async with httpx.AsyncClient() as client:
24+
resp = await client.get(url)
25+
resp.raise_for_status()
1826

1927
return resp.text
2028

2129

30+
# @unsync # <-- will run get_title_from_html() on a background thread.
31+
# @unsync(cpu_bound=True) # <-- will run get_title_from_html() on a subprocess.
2232
def get_title_from_html(n: int, html: str) -> str:
2333
print(Fore.CYAN + f"Getting TITLE for episode {n}...", flush=True)
2434

@@ -30,10 +40,24 @@ def get_title_from_html(n: int, html: str) -> str:
3040
return header.text.strip()
3141

3242

33-
def get_titles():
34-
for n in range(220, 230):
35-
html = get_html(n)
36-
title = get_title_from_html(n, html)
43+
# async def get_titles():
44+
# for n in range(220, 231):
45+
# html = await get_html(n)
46+
# title = get_title_from_html(n, html)
47+
# print(Fore.GREEN + title)
48+
49+
@unsync
50+
async def get_titles():
51+
tasks = []
52+
for n in range(220, 231):
53+
task = get_html(n)
54+
episode = n
55+
56+
tasks.append((episode, task))
57+
58+
for episode, task in tasks:
59+
html = await task
60+
title = get_title_from_html(episode, html)
3761
print(Fore.GREEN + title)
3862

3963

apps/py/ch11_notebooks/Lorenz.ipynb

Lines changed: 233 additions & 0 deletions
Large diffs are not rendered by default.

apps/py/ch11_notebooks/lorenz.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from matplotlib import pyplot as plt
2+
from mpl_toolkits.mplot3d import Axes3D
3+
import numpy as np
4+
from scipy import integrate
5+
6+
def solve_lorenz(sigma=10.0, beta=8./3, rho=28.0):
7+
"""Plot a solution to the Lorenz differential equations."""
8+
9+
max_time = 4.0
10+
N = 30
11+
12+
fig = plt.figure()
13+
ax = fig.add_axes([0, 0, 1, 1], projection='3d')
14+
ax.axis('off')
15+
16+
# prepare the axes limits
17+
ax.set_xlim((-25, 25))
18+
ax.set_ylim((-35, 35))
19+
ax.set_zlim((5, 55))
20+
21+
def lorenz_deriv(x_y_z, t0, sigma=sigma, beta=beta, rho=rho):
22+
"""Compute the time-derivative of a Lorenz system."""
23+
x, y, z = x_y_z
24+
return [sigma * (y - x), x * (rho - z) - y, x * y - beta * z]
25+
26+
# Choose random starting points, uniformly distributed from -15 to 15
27+
np.random.seed(1)
28+
x0 = -15 + 30 * np.random.random((N, 3))
29+
30+
# Solve for the trajectories
31+
t = np.linspace(0, max_time, int(250*max_time))
32+
x_t = np.asarray([integrate.odeint(lorenz_deriv, x0i, t)
33+
for x0i in x0])
34+
35+
# choose a different color for each trajectory
36+
colors = plt.cm.viridis(np.linspace(0, 1, N))
37+
38+
for i in range(N):
39+
x, y, z = x_t[i,:,:].T
40+
lines = ax.plot(x, y, z, '-', c=colors[i])
41+
plt.setp(lines, linewidth=2)
42+
angle = 104
43+
ax.view_init(30, angle)
44+
plt.show()
45+
46+
return t, x_t

0 commit comments

Comments
 (0)