Skip to content

Commit 1f57e15

Browse files
committed
Move various code snippets into their own files
1 parent b74f347 commit 1f57e15

9 files changed

Lines changed: 645 additions & 441 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
title: Include Code Files
2+
author: Bruno Beaufils
3+
version: 1.0.0
4+
quarto-required: ">=1.2"
5+
contributes:
6+
filters:
7+
- include-code-files.lua
8+
9+
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
--- include-code-files.lua – filter to include code from source files
2+
---
3+
--- Copyright: © 2020 Bruno BEAUFILS
4+
--- License: MIT – see LICENSE file for details
5+
6+
--- Dedent a line
7+
local function dedent(line, n)
8+
return line:sub(1, n):gsub(" ", "") .. line:sub(n + 1)
9+
end
10+
11+
--- Find snippet start and end.
12+
--
13+
-- Use this to populate startline and endline.
14+
-- This should work like pandocs snippet functionality: https://github.com/owickstrom/pandoc-include-code/tree/master
15+
local function snippet(cb, fh)
16+
if not cb.attributes.snippet then
17+
return
18+
end
19+
20+
-- Cannot capture enum: http://lua-users.org/wiki/PatternsTutorial
21+
local comment
22+
local comment_stop = ""
23+
if
24+
string.match(cb.attributes.include, ".py$")
25+
or string.match(cb.attributes.include, ".jl$")
26+
or string.match(cb.attributes.include, ".r$")
27+
then
28+
comment = "#"
29+
elseif string.match(cb.attributes.include, ".o?js$") or string.match(cb.attributes.include, ".css$") then
30+
comment = "//"
31+
elseif string.match(cb.attributes.include, ".lua$") then
32+
comment = "--"
33+
elseif string.match(cb.attributes.include, ".html$") then
34+
comment = "<!%-%-"
35+
comment_stop = " *%-%->"
36+
else
37+
-- If not known assume that it is something one or two long and not alphanumeric.
38+
comment = "%W%W?"
39+
end
40+
41+
local p_start = string.format("^ *%s start snippet %s%s", comment, cb.attributes.snippet, comment_stop)
42+
local p_stop = string.format("^ *%s end snippet %s%s", comment, cb.attributes.snippet, comment_stop)
43+
local start, stop = nil, nil
44+
45+
-- Cannot use pairs.
46+
local line_no = 1
47+
for line in fh:lines() do
48+
if start == nil then
49+
if string.match(line, p_start) then
50+
start = line_no + 1
51+
end
52+
elseif stop == nil then
53+
if string.match(line, p_stop) then
54+
stop = line_no - 1
55+
end
56+
else
57+
break
58+
end
59+
line_no = line_no + 1
60+
end
61+
62+
-- Reset so nothing is broken later on.
63+
fh:seek("set")
64+
65+
-- If start and stop not found, just continue
66+
if start == nil or stop == nil then
67+
return nil
68+
end
69+
70+
cb.attributes.startLine = tostring(start)
71+
cb.attributes.endLine = tostring(stop)
72+
end
73+
74+
--- Filter function for code blocks
75+
local function transclude(cb)
76+
if cb.attributes.include then
77+
local content = ""
78+
local fh = io.open(cb.attributes.include)
79+
if not fh then
80+
io.stderr:write("Cannot open file " .. cb.attributes.include .. " | Skipping includes\n")
81+
else
82+
local number = 1
83+
local start = 1
84+
85+
-- change hyphenated attributes to PascalCase
86+
for i, pascal in pairs({ "startLine", "endLine" }) do
87+
local hyphen = pascal:gsub("%u", "-%0"):lower()
88+
if cb.attributes[hyphen] then
89+
cb.attributes[pascal] = cb.attributes[hyphen]
90+
cb.attributes[hyphen] = nil
91+
end
92+
end
93+
94+
-- Overwrite startLine and stopLine with the snippet if any.
95+
snippet(cb, fh)
96+
97+
if cb.attributes.startLine then
98+
cb.attributes.startFrom = cb.attributes.startLine
99+
start = tonumber(cb.attributes.startLine)
100+
end
101+
102+
for line in fh:lines("L") do
103+
if cb.attributes.dedent then
104+
line = dedent(line, cb.attributes.dedent)
105+
end
106+
if number >= start then
107+
if not cb.attributes.endLine or number <= tonumber(cb.attributes.endLine) then
108+
content = content .. line
109+
end
110+
end
111+
number = number + 1
112+
end
113+
114+
fh:close()
115+
end
116+
117+
-- remove key-value pair for used keys
118+
cb.attributes.include = nil
119+
cb.attributes.startLine = nil
120+
cb.attributes.endLine = nil
121+
cb.attributes.dedent = nil
122+
123+
-- return final code block
124+
return pandoc.CodeBlock(content, cb.attr)
125+
end
126+
end
127+
128+
return {
129+
{ CodeBlock = transclude },
130+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from vidigi.logging import EventLogger
2+
from vidigi.utils import EventPosition, create_event_position_df
3+
from vidigi.animation import animate_activity_log
4+
import simpy
5+
import numpy as np
6+
7+
8+
class Patient:
9+
def __init__(self, p_id):
10+
self.id = p_id
11+
12+
class SimpleActivityModel:
13+
def __init__(self, master_seed=42):
14+
self.env = simpy.Environment()
15+
self.patient_counter = 0
16+
self.logger = EventLogger(env=self.env)
17+
18+
# Seed setup using numpy's SeedSequence
19+
self.master_seed = master_seed
20+
self.seed_seq = np.random.SeedSequence(master_seed)
21+
self.rng = np.random.default_rng(self.seed_seq)
22+
23+
def generate_arrivals(self):
24+
while True:
25+
self.patient_counter += 1
26+
p = Patient(self.patient_counter)
27+
self.logger.log_arrival(entity_id=p.id)
28+
self.env.process(self.patient_journey(p))
29+
yield self.env.timeout(3)
30+
31+
def patient_journey(self, patient):
32+
self.logger.log_queue(entity_id=patient.id, event="wait_here")
33+
yield self.env.timeout(70)
34+
self.logger.log_departure(entity_id=patient.id)
35+
36+
def run(self):
37+
self.env.process(self.generate_arrivals())
38+
self.env.run(until=180)
39+
40+
model = SimpleActivityModel()
41+
model.run()
42+
event_log = model.logger.to_dataframe()
43+
event_log.to_csv("test_log.csv")
44+
45+
animate_activity_log(
46+
event_log = event_log,
47+
event_position_df = create_event_position_df([
48+
EventPosition(event="wait_here", x=250 , y=25 , label="Wait Here!"),
49+
EventPosition(event="depart", x=300, y=10, label="Exit")
50+
]),
51+
every_x_time_units=1,
52+
limit_duration=60,
53+
override_x_max=300,
54+
override_y_max=50,
55+
plotly_height=600,
56+
plotly_width=1200,
57+
display_stage_labels=False,
58+
# time_display_units="%M minutes",
59+
gap_between_entities=20,
60+
entity_icon_size=70,
61+
wrap_queues_at=10,
62+
simulation_time_unit="minutes",
63+
debug_write_intermediate_objects=True
64+
)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
2+
from vidigi.logging import EventLogger
3+
from vidigi.utils import EventPosition, create_event_position_df
4+
from vidigi.animation import animate_activity_log
5+
import simpy
6+
import numpy as np
7+
8+
class Patient:
9+
def __init__(self, p_id):
10+
self.id = p_id
11+
12+
class SimpleActivityModel:
13+
def __init__(self, master_seed=42):
14+
self.env = simpy.Environment()
15+
self.patient_counter = 0
16+
self.patient_inter = 2
17+
self.logger = EventLogger(env=self.env)
18+
19+
# Seed setup using numpy's SeedSequence
20+
self.master_seed = master_seed
21+
self.seed_seq = np.random.SeedSequence(master_seed)
22+
self.rng = np.random.default_rng(self.seed_seq)
23+
24+
def generate_arrivals(self):
25+
while True:
26+
self.patient_counter += 1
27+
p = Patient(self.patient_counter)
28+
self.logger.log_arrival(entity_id=p.id)
29+
self.env.process(self.patient_journey(p))
30+
sampled_inter = self.rng.exponential(scale=self.patient_inter)
31+
yield self.env.timeout(sampled_inter)
32+
33+
def patient_journey(self, patient):
34+
self.logger.log_queue(entity_id=patient.id, event="wait_here")
35+
yield self.env.timeout(70)
36+
self.logger.log_departure(entity_id=patient.id)
37+
38+
def run(self):
39+
self.env.process(self.generate_arrivals())
40+
self.env.run(until=180)
41+
42+
model = SimpleActivityModel()
43+
model.run()
44+
event_log = model.logger.to_dataframe()
45+
event_log.to_csv("test_log.csv")
46+
47+
animate_activity_log(
48+
event_log = event_log,
49+
event_position_df = create_event_position_df([
50+
EventPosition(event="wait_here", x=250 , y=25 , label="Wait Here!"),
51+
EventPosition(event="depart", x=300, y=10, label="Exit")
52+
]),
53+
every_x_time_units=1,
54+
limit_duration=60,
55+
override_x_max=300,
56+
override_y_max=50,
57+
plotly_height=600,
58+
plotly_width=1200,
59+
display_stage_labels=False,
60+
# time_display_units="%M minutes",
61+
gap_between_entities=20,
62+
entity_icon_size=70,
63+
wrap_queues_at=10,
64+
simulation_time_unit="minutes",
65+
debug_write_intermediate_objects=True
66+
)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
from vidigi.logging import EventLogger
2+
from vidigi.utils import EventPosition, create_event_position_df
3+
from vidigi.animation import animate_activity_log
4+
import simpy
5+
import numpy as np
6+
7+
class Patient:
8+
def __init__(self, p_id):
9+
self.id = p_id
10+
11+
class SimpleActivityModel:
12+
def __init__(self, master_seed=42):
13+
self.env = simpy.Environment()
14+
self.patient_counter = 0
15+
self.patient_inter = 4
16+
self.logger = EventLogger(env=self.env)
17+
18+
# Seed setup using numpy's SeedSequence
19+
self.master_seed = master_seed
20+
self.seed_seq = np.random.SeedSequence(master_seed)
21+
self.rng = np.random.default_rng(self.seed_seq)
22+
23+
def generate_arrivals(self):
24+
while True:
25+
self.patient_counter += 1
26+
p = Patient(self.patient_counter)
27+
self.logger.log_arrival(entity_id=p.id)
28+
self.env.process(self.patient_journey(p))
29+
sampled_inter = self.rng.exponential(scale=self.patient_inter)
30+
yield self.env.timeout(sampled_inter)
31+
32+
def patient_journey(self, patient):
33+
self.logger.log_queue(entity_id=patient.id, event="wait_here")
34+
yield self.env.timeout(self.rng.uniform(low=1, high=20))
35+
self.logger.log_departure(entity_id=patient.id)
36+
37+
def run(self):
38+
self.env.process(self.generate_arrivals())
39+
self.env.run(until=180)
40+
41+
model = SimpleActivityModel()
42+
model.run()
43+
event_log = model.logger.to_dataframe()
44+
event_log.to_csv("test_log.csv")
45+
46+
animate_activity_log(
47+
event_log = event_log,
48+
event_position_df = create_event_position_df([
49+
EventPosition(event="wait_here", x=250 , y=25 , label="Wait Here!"),
50+
EventPosition(event="depart", x=300, y=10, label="Exit")
51+
]),
52+
every_x_time_units=1,
53+
limit_duration=60,
54+
override_x_max=300,
55+
override_y_max=50,
56+
plotly_height=600,
57+
plotly_width=1200,
58+
display_stage_labels=False,
59+
# time_display_units="%M minutes",
60+
gap_between_entities=20,
61+
entity_icon_size=70,
62+
wrap_queues_at=10,
63+
simulation_time_unit="minutes",
64+
debug_write_intermediate_objects=True
65+
)

0 commit comments

Comments
 (0)