Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35c8889e77 | ||
|
|
dca7e9d599 | ||
|
|
ce856e5626 | ||
|
|
072032e80e | ||
|
|
235e7b5268 | ||
|
|
22fa096271 | ||
|
|
13eb12bf69 | ||
|
|
efa189d0b6 | ||
|
|
111f551a39 | ||
|
|
e0fd81dc1d | ||
|
|
420194ef54 | ||
|
|
632448c249 | ||
|
|
c3405d56e5 | ||
|
|
338824c028 | ||
|
|
6625a4d6c1 | ||
|
|
b1fccaf628 | ||
|
|
568e890c9f | ||
|
|
ff86e4a7c2 | ||
|
|
0f10f22345 |
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Python: HotdogSimulation",
|
||||||
|
"type": "python",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "simulation/SimulationRunner.py",
|
||||||
|
"justMyCode": true,
|
||||||
|
"args": "./HotdogSimulation.py"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
GTSP Python Bootcamp
|
GTSP Python Bootcamp
|
||||||
|
|
||||||
This bootcamp is intended for OTP interns with a math and applied analysis
|
This bootcamp is intended for OPT interns with a math and applied analysis
|
||||||
background to get up to speed quickly on how to use Python for practical
|
background to get up to speed quickly on how to use Python for practical
|
||||||
commercial work. It is not intended for large classes above 2-3 study groups
|
commercial work. It is not intended for large classes above 2-3 study groups
|
||||||
of a maximum of 4 students each.
|
of a maximum of 4 students each.
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
# A quick brain teaser
|
||||||
|
print('What has a head and a tail but no body?')
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# A coin
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "0593e529",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import os\n",
|
||||||
|
"from urllib.parse import urlparse\n",
|
||||||
|
"\n",
|
||||||
|
"class JPEGRequestHandler:\n",
|
||||||
|
" def __init__(self, app):\n",
|
||||||
|
" self.app = app\n",
|
||||||
|
"\n",
|
||||||
|
" def __call__(self, environ, start_response):\n",
|
||||||
|
" url = urlparse(environ['REQUEST_URI'])\n",
|
||||||
|
" path = url.path\n",
|
||||||
|
"\n",
|
||||||
|
" if path.endswith('.jpg'):\n",
|
||||||
|
" file_path = path[1:]\n",
|
||||||
|
"\n",
|
||||||
|
" if os.path.isfile(file_path):\n",
|
||||||
|
" with open(file_path, 'rb') as file:\n",
|
||||||
|
" response_body = file.read()\n",
|
||||||
|
" status = '200 OK'\n",
|
||||||
|
" headers = [('Content-type', 'image/jpeg'),\n",
|
||||||
|
" ('Content-Length', str(len(response_body)))]\n",
|
||||||
|
"\n",
|
||||||
|
" start_response(status, headers)\n",
|
||||||
|
" return [response_body]\n",
|
||||||
|
" else:\n",
|
||||||
|
" status = '404 Not Found'\n",
|
||||||
|
" headers = [('Content-type', 'text/plain'),\n",
|
||||||
|
" ('Content-Length', '0')]\n",
|
||||||
|
"\n",
|
||||||
|
" start_response(status, headers)\n",
|
||||||
|
" return []\n",
|
||||||
|
" else:\n",
|
||||||
|
" status = '403 Forbidden'\n",
|
||||||
|
" headers = [('Content-type', 'text/plain'),\n",
|
||||||
|
" ('Content-Length', '0')]\n",
|
||||||
|
"\n",
|
||||||
|
" start_response(status, headers)\n",
|
||||||
|
" return []\n",
|
||||||
|
"\n",
|
||||||
|
"if __name__ == '__main__':\n",
|
||||||
|
" from werkzeug.serving import run_simple\n",
|
||||||
|
" from werkzeug.middleware.dispatcher import DispatcherMiddleware\n",
|
||||||
|
"\n",
|
||||||
|
" app = DispatcherMiddleware(JPEGRequestHandler(app), {'/': app})\n",
|
||||||
|
" run_simple('0.0.0.0', 8000, app, use_reloader=True)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3 (ipykernel)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.9.13"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import os
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
class JPEGRequestHandler:
|
||||||
|
def __init__(self, app):
|
||||||
|
self.app = app
|
||||||
|
|
||||||
|
def __call__(self, environ, start_response):
|
||||||
|
url = urlparse(environ['REQUEST_URI'])
|
||||||
|
path = url.path
|
||||||
|
|
||||||
|
if path.endswith('.jpg'):
|
||||||
|
file_path = path[1:]
|
||||||
|
|
||||||
|
if os.path.isfile(file_path):
|
||||||
|
with open(file_path, 'rb') as file:
|
||||||
|
response_body = file.read()
|
||||||
|
status = '200 OK'
|
||||||
|
headers = [('Content-type', 'image/jpeg'),
|
||||||
|
('Content-Length', str(len(response_body)))]
|
||||||
|
|
||||||
|
start_response(status, headers)
|
||||||
|
return [response_body]
|
||||||
|
else:
|
||||||
|
status = '404 Not Found'
|
||||||
|
headers = [('Content-type', 'text/plain'),
|
||||||
|
('Content-Length', '0')]
|
||||||
|
|
||||||
|
start_response(status, headers)
|
||||||
|
return []
|
||||||
|
else:
|
||||||
|
status = '403 Forbidden'
|
||||||
|
headers = [('Content-type', 'text/plain'),
|
||||||
|
('Content-Length', '0')]
|
||||||
|
|
||||||
|
start_response(status, headers)
|
||||||
|
return []
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
from werkzeug.serving import run_simple
|
||||||
|
from werkzeug.middleware.dispatcher import DispatcherMiddleware
|
||||||
|
|
||||||
|
app = DispatcherMiddleware(JPEGRequestHandler(app), {'/': app})
|
||||||
|
run_simple('0.0.0.0', 8000, app, use_reloader=True)
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import os
|
||||||
|
from http.server import SimpleHTTPRequestHandler, HTTPServer
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
class JPEGRequestHandler(SimpleHTTPRequestHandler):
|
||||||
|
def do_GET(self):
|
||||||
|
url = urlparse(self.path)
|
||||||
|
path = url.path
|
||||||
|
if path.endswith('.jpg'):
|
||||||
|
file_path = path[1:]
|
||||||
|
|
||||||
|
if os.path.isfile(file_path):
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header('Content-Type', 'image/jpeg')
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
with open(file_path, 'rb') as file:
|
||||||
|
self.wfile.write(file.read())
|
||||||
|
else:
|
||||||
|
self.send_error(404, 'File not found')
|
||||||
|
else:
|
||||||
|
self.send_error(403, 'Only .jpg files are allowed')
|
||||||
|
|
||||||
|
def run(server_class=HTTPServer, handler_class=JPEGRequestHandler, port=8000):
|
||||||
|
server_address = ('', port)
|
||||||
|
httpd = server_class(server_address, handler_class)
|
||||||
|
print(f'Serving JPEGs on port {port}...')
|
||||||
|
httpd.serve_forever()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
run()
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>D3.js Image Loading Time Graph</title>
|
||||||
|
<script src="https://d3js.org/d3.v5.min.js"></script>
|
||||||
|
<style>
|
||||||
|
/* Add some basic styling for the chart */
|
||||||
|
.bar {
|
||||||
|
fill: steelblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar:hover {
|
||||||
|
fill: brown;
|
||||||
|
}
|
||||||
|
|
||||||
|
.axis {
|
||||||
|
font: 10px sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.axis path,
|
||||||
|
.axis line {
|
||||||
|
fill: none;
|
||||||
|
stroke: #000;
|
||||||
|
shape-rendering: crispEdges;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="chart"></div>
|
||||||
|
<div id="stats"></div>
|
||||||
|
<script>
|
||||||
|
// Generate the list of image URLs named kublai0.jpg to kublai118.jpg
|
||||||
|
const numberOfImages = 119;
|
||||||
|
const imagePrefix = 'http://localhost:8000/kublai';
|
||||||
|
const imageExtension = '.jpg';
|
||||||
|
const images = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < numberOfImages; i++) {
|
||||||
|
const imageName = `${imagePrefix}${i}${imageExtension}`;
|
||||||
|
images.push(imageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable caching using cache-buster technique
|
||||||
|
const cacheBuster = (url) => `${url}?${new Date().getTime()}`;
|
||||||
|
|
||||||
|
// Load images and measure their loading times
|
||||||
|
const loadImages = async () => {
|
||||||
|
const loadingTimes = [];
|
||||||
|
|
||||||
|
for (const url of images) {
|
||||||
|
const startTime = performance.now();
|
||||||
|
const img = new Image();
|
||||||
|
img.src = cacheBuster(url);
|
||||||
|
img.style.display = 'none';
|
||||||
|
document.body.appendChild(img);
|
||||||
|
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
img.onload = () => {
|
||||||
|
const endTime = performance.now();
|
||||||
|
loadingTimes.push(endTime - startTime);
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadingTimes;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a D3.js bar chart to visualize loading times
|
||||||
|
const createChart = (data) => {
|
||||||
|
const margin = { top: 20, right: 20, bottom: 30, left: 40 },
|
||||||
|
width = 1280 - margin.left - margin.right,
|
||||||
|
height = 500 - margin.top - margin.bottom;
|
||||||
|
|
||||||
|
const x = d3.scaleBand().rangeRound([0, width]).padding(0.1);
|
||||||
|
const y = d3.scaleLinear().rangeRound([height, 0]);
|
||||||
|
|
||||||
|
const svg = d3.select('#chart')
|
||||||
|
.append('svg')
|
||||||
|
.attr('width', width + margin.left + margin.right)
|
||||||
|
.attr('height', height + margin.top + margin.bottom)
|
||||||
|
.append('g')
|
||||||
|
.attr('transform', `translate(${margin.left},${margin.top})`);
|
||||||
|
|
||||||
|
x.domain(data.map((d, i) => i));
|
||||||
|
y.domain([0, d3.max(data)]);
|
||||||
|
|
||||||
|
svg.append('g')
|
||||||
|
.attr('class', 'axis axis--x')
|
||||||
|
.attr('transform', `translate(0,${height})`)
|
||||||
|
.call(d3.axisBottom(x));
|
||||||
|
|
||||||
|
svg.append('g')
|
||||||
|
.attr('class', 'axis axis--y')
|
||||||
|
.call(d3.axisLeft(y).ticks(10))
|
||||||
|
.append('text')
|
||||||
|
.attr('transform', 'rotate(-90)')
|
||||||
|
.attr('y', 6)
|
||||||
|
.attr('dy', '0.71em')
|
||||||
|
.attr('text-anchor', 'end')
|
||||||
|
.text('Loading Time (ms)');
|
||||||
|
|
||||||
|
svg.selectAll('.bar')
|
||||||
|
.data(data)
|
||||||
|
.enter().append('rect')
|
||||||
|
.attr('class', 'bar')
|
||||||
|
.attr('x', (d, i) => x(i))
|
||||||
|
.attr('y', (d) => y(d))
|
||||||
|
.attr('width', x.bandwidth())
|
||||||
|
.attr('height', (d) => height - y(d));
|
||||||
|
|
||||||
|
const stats = document.getElementById('stats');
|
||||||
|
let textContent = '';
|
||||||
|
let average = 0;
|
||||||
|
let sum = 0;
|
||||||
|
let min = parseFloat(data[0]);
|
||||||
|
let max = parseFloat(data[0]);
|
||||||
|
for(datum of data) {
|
||||||
|
loadingTime = parseFloat(datum)
|
||||||
|
sum = sum + loadingTime
|
||||||
|
if(loadingTime > max) {
|
||||||
|
max = loadingTime;
|
||||||
|
}
|
||||||
|
if(loadingTime < min) {
|
||||||
|
min = loadingTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
average = sum / data.length
|
||||||
|
textContent =
|
||||||
|
'Total: ' + sum +
|
||||||
|
' Average: ' + average +
|
||||||
|
' Min: ' + min +
|
||||||
|
' Max: ' + max;
|
||||||
|
stats.textContent = textContent;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Load images and create the chart
|
||||||
|
(async () => {
|
||||||
|
const loadingTimes = await loadImages();
|
||||||
|
createChart(loadingTimes);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 124 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 107 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 167 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 91 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 56 KiB |