Spaces:
Sleeping
Sleeping
varadpuntambekar
commited on
Commit
•
fd5261f
1
Parent(s):
af73b50
Initial commit with right files
Browse files- .gitignore +160 -0
- LICENSE +121 -0
- OOP_ED_v2.0_gr.py +603 -0
- packages.txt +0 -0
.gitignore
ADDED
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Byte-compiled / optimized / DLL files
|
2 |
+
__pycache__/
|
3 |
+
*.py[cod]
|
4 |
+
*$py.class
|
5 |
+
|
6 |
+
# C extensions
|
7 |
+
*.so
|
8 |
+
|
9 |
+
# Distribution / packaging
|
10 |
+
.Python
|
11 |
+
build/
|
12 |
+
develop-eggs/
|
13 |
+
dist/
|
14 |
+
downloads/
|
15 |
+
eggs/
|
16 |
+
.eggs/
|
17 |
+
lib/
|
18 |
+
lib64/
|
19 |
+
parts/
|
20 |
+
sdist/
|
21 |
+
var/
|
22 |
+
wheels/
|
23 |
+
share/python-wheels/
|
24 |
+
*.egg-info/
|
25 |
+
.installed.cfg
|
26 |
+
*.egg
|
27 |
+
MANIFEST
|
28 |
+
|
29 |
+
# PyInstaller
|
30 |
+
# Usually these files are written by a python script from a template
|
31 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
32 |
+
*.manifest
|
33 |
+
*.spec
|
34 |
+
|
35 |
+
# Installer logs
|
36 |
+
pip-log.txt
|
37 |
+
pip-delete-this-directory.txt
|
38 |
+
|
39 |
+
# Unit test / coverage reports
|
40 |
+
htmlcov/
|
41 |
+
.tox/
|
42 |
+
.nox/
|
43 |
+
.coverage
|
44 |
+
.coverage.*
|
45 |
+
.cache
|
46 |
+
nosetests.xml
|
47 |
+
coverage.xml
|
48 |
+
*.cover
|
49 |
+
*.py,cover
|
50 |
+
.hypothesis/
|
51 |
+
.pytest_cache/
|
52 |
+
cover/
|
53 |
+
|
54 |
+
# Translations
|
55 |
+
*.mo
|
56 |
+
*.pot
|
57 |
+
|
58 |
+
# Django stuff:
|
59 |
+
*.log
|
60 |
+
local_settings.py
|
61 |
+
db.sqlite3
|
62 |
+
db.sqlite3-journal
|
63 |
+
|
64 |
+
# Flask stuff:
|
65 |
+
instance/
|
66 |
+
.webassets-cache
|
67 |
+
|
68 |
+
# Scrapy stuff:
|
69 |
+
.scrapy
|
70 |
+
|
71 |
+
# Sphinx documentation
|
72 |
+
docs/_build/
|
73 |
+
|
74 |
+
# PyBuilder
|
75 |
+
.pybuilder/
|
76 |
+
target/
|
77 |
+
|
78 |
+
# Jupyter Notebook
|
79 |
+
.ipynb_checkpoints
|
80 |
+
|
81 |
+
# IPython
|
82 |
+
profile_default/
|
83 |
+
ipython_config.py
|
84 |
+
|
85 |
+
# pyenv
|
86 |
+
# For a library or package, you might want to ignore these files since the code is
|
87 |
+
# intended to run in multiple environments; otherwise, check them in:
|
88 |
+
# .python-version
|
89 |
+
|
90 |
+
# pipenv
|
91 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
92 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
93 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
94 |
+
# install all needed dependencies.
|
95 |
+
#Pipfile.lock
|
96 |
+
|
97 |
+
# poetry
|
98 |
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
99 |
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
100 |
+
# commonly ignored for libraries.
|
101 |
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
102 |
+
#poetry.lock
|
103 |
+
|
104 |
+
# pdm
|
105 |
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
106 |
+
#pdm.lock
|
107 |
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
108 |
+
# in version control.
|
109 |
+
# https://pdm.fming.dev/#use-with-ide
|
110 |
+
.pdm.toml
|
111 |
+
|
112 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
113 |
+
__pypackages__/
|
114 |
+
|
115 |
+
# Celery stuff
|
116 |
+
celerybeat-schedule
|
117 |
+
celerybeat.pid
|
118 |
+
|
119 |
+
# SageMath parsed files
|
120 |
+
*.sage.py
|
121 |
+
|
122 |
+
# Environments
|
123 |
+
.env
|
124 |
+
.venv
|
125 |
+
env/
|
126 |
+
venv/
|
127 |
+
ENV/
|
128 |
+
env.bak/
|
129 |
+
venv.bak/
|
130 |
+
|
131 |
+
# Spyder project settings
|
132 |
+
.spyderproject
|
133 |
+
.spyproject
|
134 |
+
|
135 |
+
# Rope project settings
|
136 |
+
.ropeproject
|
137 |
+
|
138 |
+
# mkdocs documentation
|
139 |
+
/site
|
140 |
+
|
141 |
+
# mypy
|
142 |
+
.mypy_cache/
|
143 |
+
.dmypy.json
|
144 |
+
dmypy.json
|
145 |
+
|
146 |
+
# Pyre type checker
|
147 |
+
.pyre/
|
148 |
+
|
149 |
+
# pytype static type analyzer
|
150 |
+
.pytype/
|
151 |
+
|
152 |
+
# Cython debug symbols
|
153 |
+
cython_debug/
|
154 |
+
|
155 |
+
# PyCharm
|
156 |
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
157 |
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
158 |
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
159 |
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
160 |
+
#.idea/
|
LICENSE
ADDED
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Creative Commons Legal Code
|
2 |
+
|
3 |
+
CC0 1.0 Universal
|
4 |
+
|
5 |
+
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
6 |
+
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
7 |
+
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
8 |
+
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
9 |
+
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
10 |
+
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
11 |
+
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
12 |
+
HEREUNDER.
|
13 |
+
|
14 |
+
Statement of Purpose
|
15 |
+
|
16 |
+
The laws of most jurisdictions throughout the world automatically confer
|
17 |
+
exclusive Copyright and Related Rights (defined below) upon the creator
|
18 |
+
and subsequent owner(s) (each and all, an "owner") of an original work of
|
19 |
+
authorship and/or a database (each, a "Work").
|
20 |
+
|
21 |
+
Certain owners wish to permanently relinquish those rights to a Work for
|
22 |
+
the purpose of contributing to a commons of creative, cultural and
|
23 |
+
scientific works ("Commons") that the public can reliably and without fear
|
24 |
+
of later claims of infringement build upon, modify, incorporate in other
|
25 |
+
works, reuse and redistribute as freely as possible in any form whatsoever
|
26 |
+
and for any purposes, including without limitation commercial purposes.
|
27 |
+
These owners may contribute to the Commons to promote the ideal of a free
|
28 |
+
culture and the further production of creative, cultural and scientific
|
29 |
+
works, or to gain reputation or greater distribution for their Work in
|
30 |
+
part through the use and efforts of others.
|
31 |
+
|
32 |
+
For these and/or other purposes and motivations, and without any
|
33 |
+
expectation of additional consideration or compensation, the person
|
34 |
+
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
35 |
+
is an owner of Copyright and Related Rights in the Work, voluntarily
|
36 |
+
elects to apply CC0 to the Work and publicly distribute the Work under its
|
37 |
+
terms, with knowledge of his or her Copyright and Related Rights in the
|
38 |
+
Work and the meaning and intended legal effect of CC0 on those rights.
|
39 |
+
|
40 |
+
1. Copyright and Related Rights. A Work made available under CC0 may be
|
41 |
+
protected by copyright and related or neighboring rights ("Copyright and
|
42 |
+
Related Rights"). Copyright and Related Rights include, but are not
|
43 |
+
limited to, the following:
|
44 |
+
|
45 |
+
i. the right to reproduce, adapt, distribute, perform, display,
|
46 |
+
communicate, and translate a Work;
|
47 |
+
ii. moral rights retained by the original author(s) and/or performer(s);
|
48 |
+
iii. publicity and privacy rights pertaining to a person's image or
|
49 |
+
likeness depicted in a Work;
|
50 |
+
iv. rights protecting against unfair competition in regards to a Work,
|
51 |
+
subject to the limitations in paragraph 4(a), below;
|
52 |
+
v. rights protecting the extraction, dissemination, use and reuse of data
|
53 |
+
in a Work;
|
54 |
+
vi. database rights (such as those arising under Directive 96/9/EC of the
|
55 |
+
European Parliament and of the Council of 11 March 1996 on the legal
|
56 |
+
protection of databases, and under any national implementation
|
57 |
+
thereof, including any amended or successor version of such
|
58 |
+
directive); and
|
59 |
+
vii. other similar, equivalent or corresponding rights throughout the
|
60 |
+
world based on applicable law or treaty, and any national
|
61 |
+
implementations thereof.
|
62 |
+
|
63 |
+
2. Waiver. To the greatest extent permitted by, but not in contravention
|
64 |
+
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
65 |
+
irrevocably and unconditionally waives, abandons, and surrenders all of
|
66 |
+
Affirmer's Copyright and Related Rights and associated claims and causes
|
67 |
+
of action, whether now known or unknown (including existing as well as
|
68 |
+
future claims and causes of action), in the Work (i) in all territories
|
69 |
+
worldwide, (ii) for the maximum duration provided by applicable law or
|
70 |
+
treaty (including future time extensions), (iii) in any current or future
|
71 |
+
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
72 |
+
including without limitation commercial, advertising or promotional
|
73 |
+
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
74 |
+
member of the public at large and to the detriment of Affirmer's heirs and
|
75 |
+
successors, fully intending that such Waiver shall not be subject to
|
76 |
+
revocation, rescission, cancellation, termination, or any other legal or
|
77 |
+
equitable action to disrupt the quiet enjoyment of the Work by the public
|
78 |
+
as contemplated by Affirmer's express Statement of Purpose.
|
79 |
+
|
80 |
+
3. Public License Fallback. Should any part of the Waiver for any reason
|
81 |
+
be judged legally invalid or ineffective under applicable law, then the
|
82 |
+
Waiver shall be preserved to the maximum extent permitted taking into
|
83 |
+
account Affirmer's express Statement of Purpose. In addition, to the
|
84 |
+
extent the Waiver is so judged Affirmer hereby grants to each affected
|
85 |
+
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
86 |
+
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
87 |
+
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
88 |
+
maximum duration provided by applicable law or treaty (including future
|
89 |
+
time extensions), (iii) in any current or future medium and for any number
|
90 |
+
of copies, and (iv) for any purpose whatsoever, including without
|
91 |
+
limitation commercial, advertising or promotional purposes (the
|
92 |
+
"License"). The License shall be deemed effective as of the date CC0 was
|
93 |
+
applied by Affirmer to the Work. Should any part of the License for any
|
94 |
+
reason be judged legally invalid or ineffective under applicable law, such
|
95 |
+
partial invalidity or ineffectiveness shall not invalidate the remainder
|
96 |
+
of the License, and in such case Affirmer hereby affirms that he or she
|
97 |
+
will not (i) exercise any of his or her remaining Copyright and Related
|
98 |
+
Rights in the Work or (ii) assert any associated claims and causes of
|
99 |
+
action with respect to the Work, in either case contrary to Affirmer's
|
100 |
+
express Statement of Purpose.
|
101 |
+
|
102 |
+
4. Limitations and Disclaimers.
|
103 |
+
|
104 |
+
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
105 |
+
surrendered, licensed or otherwise affected by this document.
|
106 |
+
b. Affirmer offers the Work as-is and makes no representations or
|
107 |
+
warranties of any kind concerning the Work, express, implied,
|
108 |
+
statutory or otherwise, including without limitation warranties of
|
109 |
+
title, merchantability, fitness for a particular purpose, non
|
110 |
+
infringement, or the absence of latent or other defects, accuracy, or
|
111 |
+
the present or absence of errors, whether or not discoverable, all to
|
112 |
+
the greatest extent permissible under applicable law.
|
113 |
+
c. Affirmer disclaims responsibility for clearing rights of other persons
|
114 |
+
that may apply to the Work or any use thereof, including without
|
115 |
+
limitation any person's Copyright and Related Rights in the Work.
|
116 |
+
Further, Affirmer disclaims responsibility for obtaining any necessary
|
117 |
+
consents, permissions or other rights required for any use of the
|
118 |
+
Work.
|
119 |
+
d. Affirmer understands and acknowledges that Creative Commons is not a
|
120 |
+
party to this document and has no duty or obligation with respect to
|
121 |
+
this CC0 or use of the Work.
|
OOP_ED_v2.0_gr.py
ADDED
@@ -0,0 +1,603 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
+
"""
|
3 |
+
Created on Mon Apr 22 10:55:25 2024
|
4 |
+
|
5 |
+
@author: varad
|
6 |
+
"""
|
7 |
+
#OOP model for a real ED with 3 processes and 3 resources
|
8 |
+
#import libraries
|
9 |
+
import simpy
|
10 |
+
import matplotlib
|
11 |
+
import matplotlib.pyplot as plt
|
12 |
+
import math
|
13 |
+
import numpy as np
|
14 |
+
import pandas as pd
|
15 |
+
import random
|
16 |
+
import csv
|
17 |
+
import gradio as gr
|
18 |
+
import plotly.graph_objects as go
|
19 |
+
|
20 |
+
class g (object):
|
21 |
+
'''
|
22 |
+
A class that holds all the global variables that will be passed into the different processes.
|
23 |
+
It's easier to change the global variables here rather than change them in the process code as it could lead to errors
|
24 |
+
'''
|
25 |
+
#service times (these are more or less constant and hence won't be changed through user input, although it is possible to change them too,
|
26 |
+
#but for the sake of this program, they won't be changed)
|
27 |
+
ed_inter_arrival = 6 #mins
|
28 |
+
mean_registeration = 2 #mins
|
29 |
+
mean_triage = 6 #mins
|
30 |
+
mean_acu_ass = 60 #mins
|
31 |
+
mean_ed_ass = 30 #mins
|
32 |
+
|
33 |
+
#resources (this will need to me moved from a static variable to a variable within the ED class as it will then be fed into the gradio app
|
34 |
+
#as variables to be modified through user input)
|
35 |
+
receptionist = 1
|
36 |
+
nurse = 2
|
37 |
+
ed_doc = 2
|
38 |
+
acu_doc = 1
|
39 |
+
|
40 |
+
#simulation variables
|
41 |
+
number_of_runs = 100
|
42 |
+
warmup_time = 1440 #24 hours and 60 minutes per hour
|
43 |
+
run_time = 100 # mins
|
44 |
+
|
45 |
+
class ed_patient (object):
|
46 |
+
'''
|
47 |
+
Defines the patient characteristics. Could be interesting if we have different types of patients
|
48 |
+
But for this exercise we have only one type of patient that is a regular patient that has a 20% chance
|
49 |
+
of going to the ACU. Also important to store patient level variables to then summarize and plot
|
50 |
+
'''
|
51 |
+
def __init__(self, uhid):
|
52 |
+
self.id = uhid
|
53 |
+
|
54 |
+
#declaring these variables as they will be recorded and manipulated with later
|
55 |
+
self.time_entered_in_system = 0
|
56 |
+
self.q_reception = 0
|
57 |
+
self.service_reception = 0
|
58 |
+
self.q_nurse = 0
|
59 |
+
self.service_nurse = 0
|
60 |
+
self.q_edd_ass = 0
|
61 |
+
self.ed_ass_time = 0
|
62 |
+
self.acu_ass_time = 0
|
63 |
+
self.q_acu_ass = 0
|
64 |
+
self.time_exit_system = 0
|
65 |
+
self.tot_system_time = 0
|
66 |
+
|
67 |
+
class ED_sim (object):
|
68 |
+
'''
|
69 |
+
This is the actual clinic where everything is simulated.
|
70 |
+
'''
|
71 |
+
def __init__(self, run_number,receptionist = 3, nurse = 2, ed_doc = 2, acu_doc = 1 ):
|
72 |
+
#declaring the environment
|
73 |
+
self.env = simpy.Environment()
|
74 |
+
|
75 |
+
|
76 |
+
|
77 |
+
#declaring resource capacity as variables to later be changed through gradio inputs
|
78 |
+
self.rec_no = receptionist
|
79 |
+
self.nurse_no = nurse
|
80 |
+
self.ed_doc_no = ed_doc
|
81 |
+
self.acu_doc_no = acu_doc
|
82 |
+
|
83 |
+
|
84 |
+
self.patient_counter = 0
|
85 |
+
#declaring resources
|
86 |
+
self.receptionist = simpy.Resource(self.env, capacity = self.rec_no)
|
87 |
+
self.nurse = simpy.Resource(self.env, capacity = self.nurse_no)
|
88 |
+
self.ed_doc = simpy.Resource(self.env, capacity = self.ed_doc_no)
|
89 |
+
self.acu_doc = simpy.Resource(self.env, capacity = self.acu_doc_no)
|
90 |
+
self.run_number = run_number + 1
|
91 |
+
|
92 |
+
#initiating a dataframe with required columns
|
93 |
+
self.individual_level_results = pd.DataFrame({
|
94 |
+
"UHID" :[],
|
95 |
+
"Time_entered_in_system" : [],
|
96 |
+
"Q_time_receptionist":[],
|
97 |
+
"Q_time_nurse":[],
|
98 |
+
"Q_time_acu_doc":[],
|
99 |
+
"Q_time_ed_doc":[],
|
100 |
+
"Service_time_receptionist":[],
|
101 |
+
"Service_time_nurse":[],
|
102 |
+
"Service_time_acu_doc":[],
|
103 |
+
"Service_time_ed_doc":[],
|
104 |
+
"Time_exit_system":[],
|
105 |
+
"Total time in System":[]
|
106 |
+
})
|
107 |
+
self.individual_level_results.set_index('UHID', inplace= True) #sets the index to UHID which is just 1,2,3,4 etc
|
108 |
+
|
109 |
+
#declaring mean variables for or KPIs to be calculated at the end of one run
|
110 |
+
self.Mean_Q_Rec_time = 0
|
111 |
+
self.Mean_Q_Nurse_time = 0
|
112 |
+
self.Mean_Q_ED_time = 0
|
113 |
+
self.Mean_Q_ACU_time = 0
|
114 |
+
self.Rec_utilize = 0
|
115 |
+
self.Nurse_utilize = 0
|
116 |
+
self.ED_doc_utilize = 0
|
117 |
+
self.ACU_doc_utilize = 0
|
118 |
+
|
119 |
+
|
120 |
+
|
121 |
+
def generate_ed_arrivals(self):
|
122 |
+
while True:
|
123 |
+
self.patient_counter += 1 #this is also the UHID of the patient
|
124 |
+
|
125 |
+
ed_pt = ed_patient(self.patient_counter)
|
126 |
+
|
127 |
+
ed_pt.time_entered_in_system = self.env.now #Used to calculate total time spent in the system
|
128 |
+
|
129 |
+
#Patient goes to registeration
|
130 |
+
self.env.process(self.registration(ed_pt))
|
131 |
+
|
132 |
+
#print(self.individual_level_results)
|
133 |
+
#draws a random value from an exponential distribution with lambda = interarrival time
|
134 |
+
ed_arrival_time = random.expovariate(1/g.ed_inter_arrival)
|
135 |
+
|
136 |
+
yield self.env.timeout(ed_arrival_time)
|
137 |
+
|
138 |
+
|
139 |
+
def registration(self, patient):
|
140 |
+
|
141 |
+
start_q_rec = self.env.now
|
142 |
+
|
143 |
+
with self.receptionist.request() as req:
|
144 |
+
yield req
|
145 |
+
|
146 |
+
end_q_rec = self.env.now
|
147 |
+
|
148 |
+
#storing patient level values in patient level variables
|
149 |
+
patient.q_reception = end_q_rec - start_q_rec
|
150 |
+
|
151 |
+
#patient goes to triage
|
152 |
+
self.env.process(self.triage(patient))
|
153 |
+
|
154 |
+
#register_time = random.triangular(0,g.mean_registeration, 2*g.mean_registeration)
|
155 |
+
register_time = random.expovariate(1/g.mean_registeration)
|
156 |
+
|
157 |
+
patient.service_reception = register_time
|
158 |
+
|
159 |
+
|
160 |
+
|
161 |
+
yield self.env.timeout(register_time)
|
162 |
+
|
163 |
+
def triage (self, patient):
|
164 |
+
start_q_nurse = self.env.now
|
165 |
+
with self.nurse.request() as req:
|
166 |
+
yield req
|
167 |
+
|
168 |
+
end_q_nurse = self.env.now
|
169 |
+
|
170 |
+
patient.q_nurse = end_q_nurse - start_q_nurse
|
171 |
+
|
172 |
+
#patient goes either to ACU or to ED based on probability
|
173 |
+
if random.random() > 0.2: #80% chance that the patient goes to ED
|
174 |
+
self.env.process(self.ed_ass(patient))
|
175 |
+
else:
|
176 |
+
self.env.process(self.acu_ass(patient))
|
177 |
+
|
178 |
+
|
179 |
+
triage_time = random.triangular(g.mean_triage/2, g.mean_triage, g.mean_triage*2 )
|
180 |
+
|
181 |
+
patient.service_nurse = triage_time
|
182 |
+
|
183 |
+
|
184 |
+
|
185 |
+
yield self.env.timeout(triage_time)
|
186 |
+
|
187 |
+
def ed_ass (self, patient):
|
188 |
+
start_ed_q = self.env.now
|
189 |
+
with self.ed_doc.request() as req:
|
190 |
+
yield req
|
191 |
+
end_ed_q = self.env.now
|
192 |
+
patient.q_edd_ass = end_ed_q - start_ed_q
|
193 |
+
|
194 |
+
|
195 |
+
ed_ass_time = random.triangular(g.mean_ed_ass/2, g.mean_ed_ass, g.mean_ed_ass*2)
|
196 |
+
patient.ed_ass_time = ed_ass_time
|
197 |
+
|
198 |
+
|
199 |
+
|
200 |
+
yield self.env.timeout(ed_ass_time)
|
201 |
+
|
202 |
+
patient.time_exit_system = self.env.now
|
203 |
+
|
204 |
+
patient.tot_system_time = patient.time_exit_system - patient.time_entered_in_system
|
205 |
+
|
206 |
+
ED_sim.add_to_df(self, patient)
|
207 |
+
|
208 |
+
|
209 |
+
def acu_ass (self, patient):
|
210 |
+
start_acu_q = self.env.now
|
211 |
+
|
212 |
+
with self.acu_doc.request() as req:
|
213 |
+
yield req
|
214 |
+
|
215 |
+
end_acu_q = self.env.now
|
216 |
+
patient.q_acu_ass = end_acu_q - start_acu_q
|
217 |
+
|
218 |
+
acu_ass_time = random.triangular(g.mean_acu_ass/2, g.mean_acu_ass, g.mean_acu_ass*2)
|
219 |
+
|
220 |
+
patient.acu_ass_time = acu_ass_time
|
221 |
+
yield self.env.timeout(acu_ass_time)
|
222 |
+
|
223 |
+
patient.time_exit_system = self.env.now
|
224 |
+
|
225 |
+
patient.tot_system_time = patient.time_exit_system - patient.time_entered_in_system
|
226 |
+
ED_sim.add_to_df(self, patient)
|
227 |
+
|
228 |
+
|
229 |
+
def add_to_df(self, patient):
|
230 |
+
'''
|
231 |
+
Basically takes all the variables and adds them to the dataframe without having to enter them manually with
|
232 |
+
12 line codes in every function
|
233 |
+
'''
|
234 |
+
df_to_add = pd.DataFrame({
|
235 |
+
"UHID" :[patient.id],
|
236 |
+
"Time_entered_in_system" : [patient.time_entered_in_system],
|
237 |
+
"Q_time_receptionist":[patient.q_reception],
|
238 |
+
|
239 |
+
#using zeros as placeholders
|
240 |
+
"Q_time_nurse":[patient.q_nurse],
|
241 |
+
"Q_time_acu_doc":[patient.q_acu_ass],
|
242 |
+
"Q_time_ed_doc":[patient.q_edd_ass],
|
243 |
+
"Service_time_receptionist":[patient.service_reception],
|
244 |
+
"Service_time_nurse":[patient.service_nurse],
|
245 |
+
"Service_time_acu_doc":[patient.acu_ass_time],
|
246 |
+
"Service_time_ed_doc":[patient.ed_ass_time],
|
247 |
+
"Time_exit_system" :[patient.time_exit_system],
|
248 |
+
"Total time in System":[patient.tot_system_time]
|
249 |
+
})
|
250 |
+
|
251 |
+
df_to_add.set_index('UHID', inplace=True)
|
252 |
+
self.individual_level_results = self.individual_level_results._append(df_to_add)
|
253 |
+
#print(self.individual_level_results)
|
254 |
+
|
255 |
+
|
256 |
+
def mean_calculator (self):
|
257 |
+
'''
|
258 |
+
calculates the average statistic for each individual run for all the different KPIs and maybe stores it in a global database
|
259 |
+
'''
|
260 |
+
#mean queuing times
|
261 |
+
self.Mean_Q_Rec_time = self.individual_level_results['Q_time_receptionist'].mean()
|
262 |
+
self.Mean_Q_Nurse_time = self.individual_level_results['Q_time_nurse'].mean()
|
263 |
+
self.Mean_Q_ED_time = self.individual_level_results['Q_time_ed_doc'].mean()
|
264 |
+
self.Mean_Q_ACU_time = self.individual_level_results['Q_time_acu_doc'].mean()
|
265 |
+
|
266 |
+
#%resource utilisation
|
267 |
+
self.Rec_utilize = self.individual_level_results[
|
268 |
+
'Service_time_receptionist'].sum()/(g.run_time*self.rec_no)
|
269 |
+
self.Nurse_utilize = self.individual_level_results['Service_time_nurse'].sum()/(g.run_time*self.nurse_no)
|
270 |
+
self.ED_doc_utilize = self.individual_level_results['Service_time_ed_doc'].sum()/(g.run_time*self.ed_doc_no)
|
271 |
+
self.ACU_doc_utilize = self.individual_level_results['Service_time_acu_doc'].sum()/(g.run_time*self.acu_doc_no)
|
272 |
+
|
273 |
+
|
274 |
+
|
275 |
+
def export_row_to_csv(self):
|
276 |
+
'''
|
277 |
+
Writes the results of an individual run as a row in a csv file in the desired folder
|
278 |
+
'''
|
279 |
+
|
280 |
+
with open (r"C:\Users\varad\Desktop\Education Material\Mathematical Modelling\HSMA\HSMA_modelling_ED\trial_results.csv",'a') as f:
|
281 |
+
writer = csv.writer(f, delimiter = ',')
|
282 |
+
row_to_add = [self.run_number,
|
283 |
+
self.Mean_Q_Rec_time,
|
284 |
+
self.Mean_Q_Nurse_time,
|
285 |
+
self.Mean_Q_ED_time,
|
286 |
+
self.Mean_Q_ACU_time,
|
287 |
+
self.Rec_utilize,
|
288 |
+
self.Nurse_utilize,
|
289 |
+
self.ED_doc_utilize,
|
290 |
+
self.ACU_doc_utilize]
|
291 |
+
writer.writerow(row_to_add)
|
292 |
+
|
293 |
+
|
294 |
+
def run (self):
|
295 |
+
'''
|
296 |
+
suns the simulation program
|
297 |
+
'''
|
298 |
+
self.env.process(self.generate_ed_arrivals())
|
299 |
+
self.env.run(until = g.run_time)
|
300 |
+
#print(self.individual_level_results)
|
301 |
+
self.individual_level_results.to_csv(r"C:\Users\varad\Desktop\Education Material\Mathematical Modelling\HSMA\HSMA_modelling_ED\individual_results.csv")
|
302 |
+
self.mean_calculator()
|
303 |
+
self.export_row_to_csv()
|
304 |
+
|
305 |
+
class summary_statistics(object):
|
306 |
+
'''
|
307 |
+
This object calculates the mean, median or other summary statistics from a dataframe that has means of individual runs
|
308 |
+
So this object calculates the means of means
|
309 |
+
'''
|
310 |
+
def __init__(self):
|
311 |
+
self.total_mean_df = pd.DataFrame({
|
312 |
+
"Median_q_rec_time":[],
|
313 |
+
"25_q_rec_time":[],
|
314 |
+
"75_q_rec_time":[],
|
315 |
+
|
316 |
+
"Median_q_nurse_time":[],
|
317 |
+
"25_q_nurse_time":[],
|
318 |
+
"75_q_nurse_time":[],
|
319 |
+
|
320 |
+
"Median_q_ed_doc_time":[],
|
321 |
+
"25_q_ed_doc_time":[],
|
322 |
+
"75_q_ed_doc_time":[],
|
323 |
+
|
324 |
+
"Median_q_acu_doc_time":[],
|
325 |
+
"25_q_acu_doc_time":[],
|
326 |
+
"75_q_acu_doc_time":[],
|
327 |
+
|
328 |
+
"Median_%_utilize_rec":[],
|
329 |
+
|
330 |
+
"Median_%_utilize_nurse":[],
|
331 |
+
|
332 |
+
|
333 |
+
"Median_%_utilize_ed_doc":[],
|
334 |
+
|
335 |
+
|
336 |
+
"Median_%_utilize_acu_doc":[],
|
337 |
+
|
338 |
+
})
|
339 |
+
filepath = r"C:\Users\varad\Desktop\Education Material\Mathematical Modelling\HSMA\HSMA_modelling_ED\trial_results.csv"
|
340 |
+
self.dataframe = pd.read_csv(filepath)
|
341 |
+
|
342 |
+
def mean_of_means(self):
|
343 |
+
|
344 |
+
median_q_rec = self.dataframe["Mean_Q_Rec_time"].median()
|
345 |
+
twofive_q_rec = self.dataframe["Mean_Q_Rec_time"].quantile(0.25)
|
346 |
+
sevfive_q_rec = self.dataframe["Mean_Q_Rec_time"].quantile(0.75)
|
347 |
+
|
348 |
+
median_q_nurse = self.dataframe["Mean_Q_Nurse_time"].median()
|
349 |
+
twofive_q_nurse = self.dataframe["Mean_Q_Nurse_time"].quantile(0.25)
|
350 |
+
sevfive_q_nurse = self.dataframe["Mean_Q_Nurse_time"].quantile(0.75)
|
351 |
+
|
352 |
+
median_q_ed_doc = self.dataframe["Mean_Q_ED_time"].median()
|
353 |
+
twofive_q_ed_doc = self.dataframe["Mean_Q_ED_time"].quantile(0.25)
|
354 |
+
sevfive_q_ed_doc = self.dataframe["Mean_Q_ED_time"].quantile(0.75)
|
355 |
+
|
356 |
+
median_q_acu_doc = self.dataframe["Mean_Q_ACU_time"].median()
|
357 |
+
twofive_q_acu_doc = self.dataframe["Mean_Q_ACU_time"].quantile(0.25)
|
358 |
+
sevfive_q_acu_doc = self.dataframe["Mean_Q_ACU_time"].quantile(0.75)
|
359 |
+
|
360 |
+
median_rec_uti = self.dataframe["Rec_%_utilize"].median()
|
361 |
+
median_nurse_uti = self.dataframe["Nurse_%_utilize"].median()
|
362 |
+
median_ed_doc_uti = self.dataframe["ED_doc_%_utilize"].median()
|
363 |
+
median_acu_doc_uti = self.dataframe["ACU_doc_%_utilize"].median()
|
364 |
+
|
365 |
+
|
366 |
+
print("Results of " + str(g.number_of_runs) + " runs")
|
367 |
+
print("-------------")
|
368 |
+
|
369 |
+
self.total_mean_df = pd.DataFrame({
|
370 |
+
"Median_q_rec_time":[median_q_rec],
|
371 |
+
"25_q_rec_time":[twofive_q_rec],
|
372 |
+
"75_q_rec_time":[sevfive_q_rec],
|
373 |
+
|
374 |
+
"Median_q_nurse_time":[median_q_nurse],
|
375 |
+
"25_q_nurse_time":[twofive_q_nurse],
|
376 |
+
"75_q_nurse_time":[sevfive_q_nurse],
|
377 |
+
|
378 |
+
"Median_q_ed_doc_time":[median_q_ed_doc],
|
379 |
+
"25_q_ed_doc_time":[twofive_q_ed_doc],
|
380 |
+
"75_q_ed_doc_time":[sevfive_q_ed_doc],
|
381 |
+
|
382 |
+
"Median_q_acu_doc_time":[median_q_acu_doc],
|
383 |
+
"25_q_acu_doc_time":[twofive_q_acu_doc],
|
384 |
+
"75_q_acu_doc_time":[sevfive_q_acu_doc],
|
385 |
+
|
386 |
+
"Median_%_utilize_rec":[median_rec_uti],
|
387 |
+
|
388 |
+
|
389 |
+
"Median_%_utilize_nurse":[median_nurse_uti],
|
390 |
+
|
391 |
+
|
392 |
+
"Median_%_utilize_ed_doc":[median_ed_doc_uti],
|
393 |
+
|
394 |
+
|
395 |
+
"Median_%_utilize_acu_doc":[median_acu_doc_uti],
|
396 |
+
|
397 |
+
})
|
398 |
+
|
399 |
+
print(self.total_mean_df)
|
400 |
+
|
401 |
+
with open (r"C:\Users\varad\Desktop\Education Material\Mathematical Modelling\HSMA\HSMA_modelling_ED\mean_per_lambda.csv",'a') as f:
|
402 |
+
writer = csv.writer(f, delimiter = ',')
|
403 |
+
row_to_add = [g.ed_inter_arrival,
|
404 |
+
median_q_rec,
|
405 |
+
twofive_q_rec,
|
406 |
+
sevfive_q_rec,
|
407 |
+
|
408 |
+
median_q_nurse,
|
409 |
+
twofive_q_nurse,
|
410 |
+
sevfive_q_nurse,
|
411 |
+
|
412 |
+
median_q_ed_doc,
|
413 |
+
twofive_q_ed_doc,
|
414 |
+
sevfive_q_ed_doc,
|
415 |
+
|
416 |
+
median_q_acu_doc,
|
417 |
+
twofive_q_acu_doc,
|
418 |
+
sevfive_q_acu_doc,
|
419 |
+
|
420 |
+
median_rec_uti,
|
421 |
+
median_nurse_uti,
|
422 |
+
median_ed_doc_uti,
|
423 |
+
median_acu_doc_uti
|
424 |
+
]
|
425 |
+
writer.writerow(row_to_add)
|
426 |
+
|
427 |
+
def file_opener():
|
428 |
+
'''
|
429 |
+
Adds one row to the filename that is passed to it
|
430 |
+
'''
|
431 |
+
#This is not the most compulsory function here as the above function will also create a file if it does not exist already
|
432 |
+
|
433 |
+
with open (r"C:\Users\varad\Desktop\Education Material\Mathematical Modelling\HSMA\HSMA_modelling_ED\trial_results.csv",'w') as f:
|
434 |
+
writer = csv.writer(f, delimiter = ',')
|
435 |
+
columns_headers = ["Run_Number",
|
436 |
+
"Mean_Q_Rec_time",
|
437 |
+
"Mean_Q_Nurse_time",
|
438 |
+
"Mean_Q_ED_time",
|
439 |
+
"Mean_Q_ACU_time",
|
440 |
+
"Rec_%_utilize",
|
441 |
+
"Nurse_%_utilize",
|
442 |
+
"ED_doc_%_utilize",
|
443 |
+
"ACU_doc_%_utilize"]
|
444 |
+
writer.writerow(columns_headers)
|
445 |
+
|
446 |
+
with open (r"C:\Users\varad\Desktop\Education Material\Mathematical Modelling\HSMA\HSMA_modelling_ED\mean_per_lambda.csv",'w') as f:
|
447 |
+
writer = csv.writer(f, delimiter = ',')
|
448 |
+
columns_headers = ["Pt Interarrival Time (lambda)",
|
449 |
+
"Median_Q_Rec_time",
|
450 |
+
"25_Q_rec_time",
|
451 |
+
"75_Q_rec_time",
|
452 |
+
|
453 |
+
"Median_Q_Nurse_time",
|
454 |
+
"25_Q_Nurse_time",
|
455 |
+
"75_Q_Nurse_time",
|
456 |
+
|
457 |
+
"Median_Q_ED_time",
|
458 |
+
"25_Q_ED_time",
|
459 |
+
"75_Q_ED_time",
|
460 |
+
|
461 |
+
"Median_Q_ACU_time",
|
462 |
+
"25_Q_ACU_time",
|
463 |
+
"75_Q_ACU_time",
|
464 |
+
|
465 |
+
"Median_Rec_%_utilize",
|
466 |
+
"Median_Nurse_%_utilize",
|
467 |
+
"Median_ED_doc_%_utilize",
|
468 |
+
"Median_ACU_doc_%_utilize"]
|
469 |
+
|
470 |
+
writer.writerow(columns_headers)
|
471 |
+
|
472 |
+
def Plotter():
|
473 |
+
filepath = r"C:\Users\varad\Desktop\Education Material\Mathematical Modelling\HSMA\HSMA_modelling_ED\mean_per_lambda.csv"
|
474 |
+
df_to_plot = pd.read_csv(filepath)
|
475 |
+
|
476 |
+
figure = plt.subplots()
|
477 |
+
plt.plot(df_to_plot["Pt Interarrival Time (lambda)"], df_to_plot['Median_Q_Rec_time'], color = 'green', linestyle = '-', label = 'Queue for reception')
|
478 |
+
plt.plot(df_to_plot["Pt Interarrival Time (lambda)"], df_to_plot['Median_Q_Nurse_time'], color = 'blue', linestyle = ':', label = 'Queue for nurses')
|
479 |
+
plt.plot(df_to_plot["Pt Interarrival Time (lambda)"], df_to_plot['Median_Q_ED_time'], color = 'red', linestyle = '--', label = 'Queue for ED_doc')
|
480 |
+
plt.plot(df_to_plot["Pt Interarrival Time (lambda)"], df_to_plot['Median_Q_ACU_time'], color = 'black', linestyle = '-.', label = 'Queue for ACU_doc')
|
481 |
+
|
482 |
+
plt.xlabel("Pt interarrival time (min)")
|
483 |
+
plt.ylabel("Time in minutes")
|
484 |
+
plt.title("Queuing times for the Emergency room")
|
485 |
+
|
486 |
+
plt.text(3,10,"Rec = 1, Nur = 2, ED_doc = 2, ACU_doc = 1")
|
487 |
+
plt.legend()
|
488 |
+
|
489 |
+
|
490 |
+
|
491 |
+
figure = plt.subplots()
|
492 |
+
plt.plot(df_to_plot["Pt Interarrival Time (lambda)"], df_to_plot['Median_Rec_%_utilize'], color = 'green', linestyle = '-', label = '% utilise of reception')
|
493 |
+
plt.plot(df_to_plot["Pt Interarrival Time (lambda)"], df_to_plot['Median_Nurse_%_utilize'], color = 'blue', linestyle = ':', label = '% utilise of nurses')
|
494 |
+
plt.plot(df_to_plot["Pt Interarrival Time (lambda)"], df_to_plot['Median_ED_doc_%_utilize'], color = 'red', linestyle = '--', label = '%utilise of ED_doc')
|
495 |
+
plt.plot(df_to_plot["Pt Interarrival Time (lambda)"], df_to_plot['Median_ACU_doc_%_utilize'], color = 'black', linestyle = '-.', label = '%utilise of ACU_doc')
|
496 |
+
|
497 |
+
plt.xlabel("Pt interarrival time (min)")
|
498 |
+
plt.ylabel("Time in minutes")
|
499 |
+
plt.title("Percentage utlisation for the Emergency room different HR")
|
500 |
+
|
501 |
+
plt.text(3,10,"Rec = 1, Nur = 2, ED_doc = 2, ACU_doc = 1")
|
502 |
+
plt.legend()
|
503 |
+
|
504 |
+
|
505 |
+
return figure
|
506 |
+
|
507 |
+
def plotly_plotter():
|
508 |
+
'''
|
509 |
+
Uses the Plotly library to plot the graphs as the plotly library is web application friendly
|
510 |
+
'''
|
511 |
+
filepath = r"C:\Users\varad\Desktop\Education Material\Mathematical Modelling\HSMA\HSMA_modelling_ED\mean_per_lambda.csv"
|
512 |
+
df_to_plot = pd.read_csv(filepath)
|
513 |
+
|
514 |
+
fig = go.Figure()
|
515 |
+
fig.add_trace(go.Scatter(x = df_to_plot["Pt Interarrival Time (lambda)"], y = df_to_plot['Median_Rec_%_utilize'], name='Receptionist utilization%'))
|
516 |
+
fig.add_trace(go.Scatter(x = df_to_plot["Pt Interarrival Time (lambda)"], y = df_to_plot['Median_Nurse_%_utilize'], name='Nurse utilization%'))
|
517 |
+
fig.add_trace(go.Scatter(x = df_to_plot["Pt Interarrival Time (lambda)"], y = df_to_plot['Median_ED_doc_%_utilize'], name='ED Doc utilization%'))
|
518 |
+
fig.add_trace(go.Scatter(x = df_to_plot["Pt Interarrival Time (lambda)"], y = df_to_plot['Median_ACU_doc_%_utilize'], name='ACU Doc utilization%'))
|
519 |
+
fig.update_layout(title = "% utilization of different HR")
|
520 |
+
#fig.show()
|
521 |
+
|
522 |
+
return fig
|
523 |
+
|
524 |
+
|
525 |
+
|
526 |
+
def main(receptionist, nurse, ed_doc, acu_doc):
|
527 |
+
'''
|
528 |
+
this is going to to be the main function that gradio will operate on
|
529 |
+
It will take input parameters as model parameters which will be modified by the users
|
530 |
+
It will output a plot or a set of plots which will then be plotted in a given block in gradio
|
531 |
+
'''
|
532 |
+
file_opener()
|
533 |
+
for l in range(1,11):
|
534 |
+
print("Pt interarrival time = ", l)
|
535 |
+
for run in range (g.number_of_runs):
|
536 |
+
print(f"Run {run + 1} of {g.number_of_runs}")
|
537 |
+
my_ED_model = ED_sim(run, receptionist, nurse, ed_doc, acu_doc)
|
538 |
+
my_ED_model.run()
|
539 |
+
g.ed_inter_arrival = l
|
540 |
+
my_sum_stats = summary_statistics()
|
541 |
+
my_sum_stats.mean_of_means()
|
542 |
+
return plotly_plotter()
|
543 |
+
|
544 |
+
def get_data_gradio():
|
545 |
+
filepath = r"C:\Users\varad\Desktop\Education Material\Mathematical Modelling\HSMA\HSMA_modelling_ED\mean_per_lambda.csv"
|
546 |
+
return pd.read_csv(filepath)
|
547 |
+
|
548 |
+
|
549 |
+
|
550 |
+
#main()
|
551 |
+
|
552 |
+
|
553 |
+
|
554 |
+
with gr.Blocks() as demo:
|
555 |
+
gr.Markdown(r"A Discrete Event Simulation run of an imaginary Emergency Room")
|
556 |
+
gr.Image(r"C:\Users\varad\Desktop\Education Material\Mathematical Modelling\HSMA\HSMA_modelling_ED\Ed_process_map.png")
|
557 |
+
with gr.Row():
|
558 |
+
gr.HighlightedText(label = "Modify these parameters (number of different human resources) using the sliders below")
|
559 |
+
with gr.Row():
|
560 |
+
receptionist = gr.Slider(minimum=1, maximum=10,label = "No of Receptionists")
|
561 |
+
nurse = gr.Slider(minimum=1, maximum=10, label = "No of Nurses")
|
562 |
+
with gr.Row():
|
563 |
+
ed_doc = gr.Slider(minimum=1, maximum=10, label = "No of ED doctors")
|
564 |
+
acu_doc = gr.Slider(minimum=1, maximum=10,label = "No of ACU Doctors")
|
565 |
+
|
566 |
+
|
567 |
+
with gr.Row():
|
568 |
+
btn = gr.Button(value = "Run the Simulation")
|
569 |
+
|
570 |
+
|
571 |
+
with gr.Row():
|
572 |
+
output = gr.Plot(label = "Simulation Run")
|
573 |
+
btn.click(main,[receptionist,nurse,ed_doc,acu_doc], output)
|
574 |
+
demo.launch(share = True)
|
575 |
+
|
576 |
+
|
577 |
+
|
578 |
+
|
579 |
+
|
580 |
+
|
581 |
+
|
582 |
+
|
583 |
+
|
584 |
+
|
585 |
+
|
586 |
+
|
587 |
+
|
588 |
+
|
589 |
+
|
590 |
+
|
591 |
+
|
592 |
+
|
593 |
+
|
594 |
+
|
595 |
+
|
596 |
+
|
597 |
+
|
598 |
+
|
599 |
+
|
600 |
+
|
601 |
+
|
602 |
+
|
603 |
+
|
packages.txt
ADDED
Binary file (2.14 kB). View file
|
|