Introduction to simulation.

Downloads

Powerpoint

Examples

Interest.py

import matplotlib.pyplot as plt

### GLOBAL VARIABLES AND CONSTANTS
# 
#

DELAY = 20

INITIAL_STATE = 100
INTEREST = 3
YEARS = 5


### HELPER FUNCTIONS
#
#

def show_line(length=30):
    print('+'+'-'*length+'+')
    
    
def do_nothing():
    pass
    
    
### SIMULATION - BACKEND
#
#
    
def next_period(previous, interest):
    """ calculates the stock value for the next time period """
    
    result = round(previous + previous * interest / 100, 2)
    return result
  
    
def simulate(initial_state, interest, years):
    """ run simulation according to the given parameters
    initial_state: initial stock value
    interest: flow (increase)
    years: duration of the simulation """
    
    periods = [0]
    savings = [initial_state]
    for i in range(years):
        new_state = next_period(savings[i],interest)
        periods.append(i+1)
        savings.append(new_state)
    
    return periods, savings


def print_sim(periods, savings):
    """ print simulation results to the standard output (console) """
    
    show_line()
    if len(periods) == len(savings):
        print("PERIOD \t STATE")
        for i in periods:
            print("%3d: \t %3.2f" % (i, savings[i]))

    
def plot_sim(periods, savings):
    """ plot simulation results using matplotlib
    note: display will be auto-closed after DELAY seconds to avoid concurency issues """
    
    if len(periods) == len(savings):
        plt.bar(periods, savings, align='center')
        
        # note: to prevent blocking call from plt.show(), we use plt.draw() and then close it after DELAY
        plt.draw()
        plt.waitforbuttonpress(DELAY)
        plt.close()



### MENU - FRONTEND
#
#
 
def show_variables():
    show_line()
    print("SIMULATION PARAMETERS")
    print()
    print("savings  = %d%s" % (INITIAL_STATE,u"\N{euro sign}"))
    print("interest = %.2f%%" % (INTEREST))
    print("years    = %d" % (YEARS))
    print()
    print("press any key")
    input()

    
def change_savings():
    global INITIAL_STATE
    
    show_line()
    print("Input new savings value:")
    INITIAL_STATE = float(input())


def change_interest():
    global INTEREST
    
    show_line()
    print("Input new interest perentage:")
    INTEREST = float(input())


def change_duration():
    global YEARS
    
    show_line()
    print("Input the number of years:")
    YEARS = int(input())
    
    
def show_menu_options():
    show_line()
    print("\t\tMAIN MENU")
    print()
    print("(1) show sim. parameters")
    print("(2) change savings")
    print("(3) change interest")
    print("(4) change simulation duration")
    print()
    print("(R) RUN SIMULATION")
    print()
    print("(Q) quit program")

    
def input_command():
    show_line()
    print()
    print("Please input your choice:")
    choice = input()
    return choice

    
def run_program():
    running = True
    while running:        
        show_menu_options()
        choice = input_command()
        
        valid = {'1', '2', '3', '4', 'R', 'Q'}
        while choice.upper() not in valid:
            show_menu_options()
            choice = input_command()
            
        if choice == '1':
            show_variables()
        elif choice == '2':
            change_savings()
            show_variables()
        elif choice == '3':
            change_interest()
            show_variables()
        elif choice == '4':
            change_duration()
            show_variables()
        elif choice.upper() == 'R':
            periods, states = simulate(INITIAL_STATE, INTEREST, YEARS)
            print_sim(periods, states)
            plot_sim(periods, states)
            
        elif choice.upper() == 'Q':
            running = False
        else:
            print("Debug: This line should not trigger!")
            
    show_line()
    print("Thank you for using InterestSim!")

        
    
### EXTRA
#   Examples: using simulation to answer "what-if" questions
#

def goal_double(initial_state, interest):
    """ answers how many time periods are needed to double the investment
    with the given interest """
    
    state = initial_state
    target = state * 2
    year = 0
    while state < target:
        state = next_period(state, interest)
        year += 1
        
    # either return value or print all (time) steps of the simulation
    #return year
    
    p,s = simulate(initial_state, interest, year)
    print_sim(p,s)
    plot_sim(p,s)
    
    
def goal_target(initial_state, interest, target):
    """ answers how many time periods are needed to reach a certain goal
    (target) with the given interest """
    
    state = initial_state
    year = 0
    while state < target:
        state = next_period(state, interest)
        year += 1
    
    # either return value or print all (time) steps of the simulation    
    #return year
    
    p,s = simulate(initial_state, interest, year)
    print_sim(p,s)
    plot_sim(p,s)
    
    
    
### MAIN
#
#

if __name__ == "__main__":
    run_program()

Demograph.py

import matplotlib.pyplot as plt

### GLOBAL VARIABLES AND CONSTANTS
#
#

DELAY = 20

INITIAL_STATE = 17180000
NATALITY = 1.09
MORTALITY = 3.8
DURATION = 20

#IMMIGRATION_RATE = 0.19  (extra: add implement imigartion rate to increase the stock)


### HELPER FUNCTIONS
#
#

def show_line(length=60):
    print('+'+'-'*length+'+')
    
    
def do_nothing():
    pass
    
    
### SIMULATION - BACKEND
#
#
    
def next_period(state, decrease, increase):
    """ calculates the stock value for the next time period """
    
    res = state - decrease + increase
    if res < 0:
        res = 0
    return res

    
def get_inflow(state, natality_rate):
    return round(state * natality_rate / 100)


def get_outflow(state, mortality_rate):
    return round(state * mortality_rate / 100)

    
def simulate(initial_state, natality_rate, mortality_rate, duration):
    """ run simulation according to the given parameters
    initial_state: initial stock value
    natality_rate: flow (increase)
    mortality_rate: flow (decrease)
    duration: duration of the simulation """
    
    # create lists to store results
    periods = [0]
    population = [initial_state]
    mortality = []
    natality = [0]
    
    # run simulation (duration) times
    for i in range(duration):
        inflow = get_inflow(population[i], natality_rate)
        outflow = get_outflow(population[i], mortality_rate)
        
        # get value for the next time period
        new_state = next_period(population[i], outflow, inflow)
        
        # add results to lists
        periods.append(i+1)
        population.append(new_state)
        mortality.append(outflow)
        natality.append(inflow)
    
    # note: for period t inflow t already happened, while mortality t yet has to happen
    # hence natality and mortality will not have the same length; this is an adjustment
    # for plotting
    mortality.append(0)
    
    return periods, population, natality, mortality


def print_sim(periods, population, births, deaths):
    """ print simulation results to the standard output (console) """
    
    show_line()
    if len(periods) == len(population):
        print("PERIOD \t POPULATION \t\t BIRTHS \t\t DEATHS")
        for i in periods:
            print("%3d: \t %10d \t\t %8d \t\t %8d" % (i, population[i], births[i], deaths[i]))

    

def plot_sim(periods, population, births, deaths):
    """ plot simulation results using matplotlib
    note: display will be auto-closed after DELAY seconds to avoid concurency issues """
    
    # local variables to adjust bar chart
    bar_width = 0.4
    pos1 = [i-bar_width/2 for i in periods]
    pos2 = [i+bar_width/2 for i in periods]
    
    if len(periods) == len(population):
        # set 2 subplots, one above the other
        fig, ax = plt.subplots(2)

        # subplot 1 - stock value (population)
        ax[0].plot(periods, population, label='population')
        ax[0].legend()
        ax[0].set_xticks(periods)
        ax[0].set_xticklabels(periods)

        # subplot 2 - flow values
        ax[1].bar(pos1, births, bar_width, color = 'g', align='center', label='births')
        ax[1].bar(pos2, deaths, bar_width, color = 'b', align='center', label='deaths')
        ax[1].legend()
        ax[1].set_xticks(periods)
        ax[1].set_xticklabels(periods)
        
        # draw and delayed close to prevent concurency issues
        plt.draw()
        plt.waitforbuttonpress(DELAY)
        plt.close()


### MENU - FRONTEND
#
#
 

def show_variables():
    show_line()
    print("SIMULATION PARAMETERS")
    print()
    print("population     = %d" % (INITIAL_STATE))
    print("natality rate  = %.2f%%" % (NATALITY))
    print("mortality rate = %.2f%%" % (MORTALITY))
    print("sim. duration  = %d" % (DURATION))
    print()
    print("press any key")
    input()


def change_population():
    global INITIAL_STATE
    
    show_line()
    print("Input new value for the initial population:")
    INITIAL_STATE = int(input())

def change_natality():
    global NATALITY
    
    show_line()
    print("Input new natality percentage:")
    NATALITY = float(input())

def change_mortality():
    global MORTALITY
    
    show_line()
    print("Input new mortality percentage:")
    MORTALITY = float(input())


def change_duration():
    global DURATION
    
    show_line()
    print("Input the number of years:")
    DURATION = int(input())
    
    
def show_menu_options():
    show_line()
    print("\t\tMAIN MENU")
    print()
    print("(1) show sim. parameters")
    print("(2) change population")
    print("(3) change natality rate")
    print("(4) change mortality rate")
    print("(5) change simulation duration")
    print()
    print("(R) RUN SIMULATION")
    print()
    print("(Q) quit program")

    
def input_command():
    show_line()
    print()
    print("Please input your choice:")
    choice = input()
    return choice

    
def run_program():
    running = True
    while running:        
        show_menu_options()
        choice = input_command()
        
        valid = {'1', '2', '3', '4', '5', 'R', 'Q'}
        while choice.upper() not in valid:
            show_menu_options()
            choice = input_command()
            
        if choice == '1':
            show_variables()
        elif choice == '2':
            change_population()
            show_variables()
        elif choice == '3':
            change_natality()
            show_variables()
        elif choice == '4':
            change_mortality()
            show_variables()
        elif choice == '5':
            change_duration()
            show_variables()
        elif choice.upper() == 'R':
            per, pop, born, died = simulate(INITIAL_STATE, NATALITY, MORTALITY, DURATION)
            print_sim(per, pop, born, died)
            plot_sim(per, pop, born, died)
            
        elif choice.upper() == 'Q':
            running = False
        else:
            print("Debug: This line should not trigger!")
            
    show_line()
    print("Thank you for using DemographicSim!")
        
    
### EXTRA
#
#

# if you need values only without menu and graphics, call simulate directly
"""
t, p, n, m = simulate(INITIAL_STATE, NATALITY, MORTALITY, DURATION)
t2, p2, n2, m2 = simulate(INITIAL_STATE, 4, 2.8, DURATION)
"""
    

    
### MAIN
#
#

if __name__ == "__main__":
    run_program()