Harnessing Python’s Power Beyond AI: Crafting Individual-Level Simulations With the SimPy Library
Federico Felizzi, PhD, MBA, ETH Zurich, Switzerland; Max Buckley, MSc, DAS, Google, Zurich, Switzerland; Noman Paracha, MSc, Bayer, Basel, Switzerland

Introduction
Modeling in health economics often requires capturing the complex dynamics and interactions of patients, providers, and resources in a healthcare system. Individual-level simulations, also known as microsimulations or individual-based models, are a powerful tool to represent the heterogeneity and variability of patient characteristics, behaviors, and outcomes, as well as the stochasticity and uncertainty of events and decisions. Individual-level simulations enable detailed insights into the performance and efficiency of different interventions, policies, or scenarios, and they help identify potential bottlenecks, trade-offs, and optimal strategies.
However, individual-level simulations also pose technical and methodological difficulties. Challenges include the need for large and reliable data sources, the calibration and validation of model parameters and assumptions, and the computational complexity and scalability of the models.1,2 In this article, we discuss how object-oriented programming (OOP) and Python can facilitate the development and implementation of individual-level simulations and overcome some of the limitations identified by the recommended tools (Figure).3
Figure. Comparison between currently recommended modeling software tools (left panel) including SIMUL8, Excel, TreeAge, and R, versus emerging programming frameworks (right panel) such as Python, TensorFlow, SimPy, and PyTorch that unlock new opportunities for healthcare simulation modeling. Adapted from Reference 3.

Object-Oriented Programming for Individual-Level Simulations
OOP is a programming paradigm that organizes data and behavior into reusable units called objects. Objects encapsulate attributes (data) and methods (functions) that define their state and functionality. Objects are instantiation of classes; classes are blueprints or templates for creating objects with the same structure and behavior. Classes can inherit from other classes, meaning that they can extend or override the attributes and methods of their parent classes while still being compatible with code written to handle the parent class. This allows for code reuse and abstraction, as well as capturing both the hierarchical and compositional relationships present between different types of entities.
OOP is particularly relevant for individual-level simulations because it can naturally represent the entities and processes involved in a healthcare system, such as patients, providers, resources, events, and actions. Each type of entity can be modeled as a class, with its own attributes and methods that describe its characteristics and behavior. For example, a patient class can have attributes such as age, gender, diagnosis, and treatment history, and methods such as generate_event, update_state, and record_outcome. A provider object can have attributes such as capacity, availability, and cost, and methods such as schedule_appointment, provide_service, and collect_fee. A resource object can have attributes such as location, quantity, and quality, and methods such as allocate, consume, and replenish. Events and actions can be modeled as methods that change the state or attributes of one or more objects, or trigger other events or actions. A specific healthcare system can be analyzed in depth. We have implemented basic scripts in which we model a referral system from generalist doctors to specialists, in which bottlenecks causing a long waiting time are created.4
Using OOP, patient-level simulations can be built as collections of interacting objects that mimic the real-world dynamics and behaviors of a healthcare system. OOP enables the capturing of common characteristics and variability of different entities, while allowing for specialization and customization of each object or class. OOP enables the uniform treatment of objects of different classes with the same parent class or implementation; by using a technique called polymorphism, we can call the same method on different types of patients, providers, or resources with different results for each based on their specific subtype. OOP promotes modularity, readability, and maintainability of the code, as well as facilitating the testing and debugging of the model.
Python for Individual-Level Simulations
Python, a widely used programming language known for its simplicity and versatility, serves as a powerful tool for developing individual-level simulations. Its appeal lies in several key attributes. Python stands out from C++ and Java (both primarily OOP languages) by supporting both OOP and functional programming natively. In contrast, R, while offering object-oriented systems such as S3, S4, and RC, is fundamentally a functional programming language. R’s approach to OOP introduces several challenges. Users must navigate multiple OOP systems, each with its own conventions and trade-offs, creating a lack of standardization and interoperability. Systems like S3 are simple but lack encapsulation, while more formal systems like S4 and RC come with steep learning curves and rigid structures. Additionally, performance bottlenecks from dynamic dispatch and limited debugging support make OOP in R less intuitive compared to other languages. Python, with its seamless integration of OOP and functional programming paradigms, provides a more user-friendly and versatile experience, bridging paradigms without the complexities seen in R.
Python has a clear and flexible syntax, which helps developers write code that is brief and easy to understand. This simplicity improves the creation of simulation models that are both graceful and readable, making the development process better. Additionally, the availability of generative AI tools such as ChatGPT or Claude can assist developers, including those less experienced with Python, by providing explanations, debugging support, and generating code based on prompts. However, while such tools can lower the barrier to entry for beginners, it is crucial to emphasize the importance of understanding the underlying logic and assumptions of the generated code to ensure the accuracy and reliability of simulation models. Rather than replacing coding expertise, generative AI serves as a supplementary tool that supports learning and accelerates the development process when used responsibly.
The strength of Python also lies in its vibrant and expansive community of users and developers. This ecosystem contributes to a vast repository of libraries, modules, and frameworks tailored to diverse domains, including scientific computing, data analysis, and simulation modeling. SimPy5 can be easily integrated with other Python libraries such as SciPy for scientific programming, Pandas for manipulating structured data, Scikit-Learn for machine learning, and Matplotlib for visualizing data.
SimPy “Simulation in Python” is a discrete event simulation framework. SimPy allows defining the entities and processes of a system as objects and creating an environment that manages the simulation clock and the event queue. SimPy also provides features such as resources, containers, and stores, which can be used to model the availability and allocation of different types of resources in a system.
"Python, with its seamless integration of object-oriented programming and functional programming paradigms, provides a more user-friendly and versatile experience, bridging paradigms without the complexities seen in R."
Creating a Simulation
SimPy enables individual-level simulations through a sequence of steps. Start by creating classes and objects that represent different components of the healthcare system—patients, providers, resources, events, and actions. These constructs contain attributes and behaviors that are critical for the simulation’s operation.
After laying the groundwork, the next step is to create a simulation environment in SimPy, which serves as the stage for managing time progression and event sequencing. SimPy, as a framework, provides a structured architecture for modeling simulations, unlike standalone libraries that offer specific tools. Within this framework, you define processes—represented as functions or methods—that generate events, influence object states, and trigger subsequent actions.
To set up the simulation, specify initial conditions and parameters, such as patient demographics, resource availability, and event probabilities. As the simulation unfolds, time advances, events occur, and the system’s dynamics evolve. Finally, analyze the outputs—like patient outcomes, resource usage, and system performance—using Python libraries to gain insights into the simulated healthcare environment.
Challenges in Parameter Estimation
Python, along with its associated ecosystem, empowers simulations to integrate machine learning and statistical methods, enhancing their ability to process data from diverse sources and estimate parameters for complex models (Table). Machine learning, in particular, enables dynamic simulations to achieve greater fidelity by improving parameter estimation and facilitating automated updates with real-time data feeds.1 This synergy ensures that simulations remain responsive to the rapidly evolving nature of information generated by healthcare systems.
Table. Relevant Python libraries and their use6-8

Simulations are essential for analyzing healthcare bottlenecks, where demand exceeds supply, leading to delays, inefficiencies, and higher costs. By modeling interactions like event sequencing and resource availability, they offer insights into system dynamics and enable scenario testing. Integrating machine learning enhances these capabilities, supporting dynamic resource allocation in crises and tailoring treatment pathways in personalized medicine. This synergy also addresses challenges like nonlinear data dependencies and complex intervention modeling, unlocking new solutions for healthcare analysis.
As the fields of machine learning and simulation modeling continue to merge,9 their potential to revolutionize areas such as chronic disease management, epidemiological forecasting, and resource optimization grows, offering profound advancements in healthcare systems analysis.
Lessons Learned
Individual-level simulations are a powerful tool for modeling the complex interactions between patients, providers, and resources in healthcare systems. Python, with its object-oriented programming capabilities and extensive libraries, facilitates the development and implementation of these simulations, offering intuitive ways to represent system entities and processes. It also supports data extraction, parameter estimation, and validation using machine learning and statistical methods, enhancing the accuracy and robustness of simulations. These models can identify bottlenecks and evaluate strategies to address them, aiding in policy and decision-making. To demonstrate this, we have developed a GitHub repository4 showcasing a simulation of a healthcare bottleneck, illustrating the practical application of these techniques. Furthermore, Python’s growing adoption in health economic modeling, as seen in its use for interactive applications like Dash,10 underscores its relevance for conducting rigorous analyses aligned with health technology assessment methodologies, such as those endorsed by NICE.11
References
- Marshall DA, Burgos-Liz L, IJzerman MJ, et al. Applying dynamic simulation modeling methods in health care delivery research—the SIMULATE checklist: report of the ISPOR Simulation Modeling Emerging Good Practices Task Force. Value Health. 2015;18(1):5-16. doi:10.1016/j.jval.2014.12.001
- Karnon J, Stahl J, Brennan A, Caro JJ, Mar J, Möller J. Modeling using discrete event simulation: a report of the ISPOR-SMDM Modeling Good Research Practices Task Force-4. Value Health. 2012;15(6):821-827. doi:10.1016/j.jval.2012.04.013
- Patient-level simulation TSD. University of Sheffield. https://www.sheffield.ac.uk/nice-dsu/tsds/patient-level-simulation. Accessed April 19, 2024.
- Felizzi. felizzi/PLS_Simpy: VO_release_0.1. Published January 2, 2025. doi:10.5281/ZENODO.14589302
- Overview. SimPy. https://simpy.readthedocs.io/en/latest/. Accessed April 26, 2024.
- Monod M, Krusche P, Cao Q, et al. TorchSurv: a lightweight package for deep survival analysis. Published April 17, 2024. doi:10.48550/arXiv.2404.10761
- Paszke A, Gross S, Massa F, et al. PyTorch: an imperative style, high-performance deep learning library. Published December 3, 2019. doi:10.48550/arXiv.1912.01703
- Abadi M, Agarwal A, Barham P, et al. TensorFlow: large-scale machine learning on heterogeneous distributed systems. Published March 16, 2016. doi:10.48550/arXiv.1603.04467
- Maftouni M, Ghaffarzadegan N, Kong Z. A deep learning technique for parameter estimation in system dynamics models. Published May 7, 2023. doi:10.2139/ssrn.4440489
- Kaur R, Singh B, Pandey S. Leveraging Python Dash and R Shiny for advanced health economic model development. ISPOR—International Society For Pharmacoeconomics and Outcomes Research. https://www.ispor.org/heor-resources/presentations-database/presentation/euro2024-4015/147388. Published December 2024. Accessed January 2, 2025.
- NICE health technology evaluations: the manual. NICE: National Institute for Health and Care Excellence. https://www.nice.org.uk/process/pmg36/chapter/introduction-to-health-technology-evaluation. Published January 31, 2022. Updated October 31, 2023. Accessed January 2, 2025.