Initial Configuration

import warnings
warnings.filterwarnings("ignore")

# General Purpose
import numpy as np
from matplotlib import pyplot as plt
from scipy.integrate import odeint

# Jupyter Specifics
from IPython.display import HTML
from ipywidgets.widgets import interact, IntSlider, FloatSlider, Layout

%matplotlib inline

style = {'description_width': '150px'}
slider_layout = Layout(width='99%')

Familiar Economy

def main(initial_salary, savings_ration, extraordinary_expenses, fixed_costs, days):
    saving_limit = savings_ration * initial_salary
    
    def function(capital, time):
        if capital <= saving_limit:
            out_rate = 0
        else:
            out_rate = extraordinary_expenses * (capital - saving_limit)
        return -fixed_costs - out_rate
    
    time = np.linspace(0, days, days*10)
    
    solution = odeint(function, initial_salary, time)
    
    #Graphic details
    fig, ax = plt.subplots(figsize=(15, 10))    
    
    ax.plot((0, days), (saving_limit, saving_limit), label='Saving Limit')
    ax.plot(time, solution, label='Capital(t)')
    
    if days <= 60:
        step = 1
        rotation = "horizontal"
    elif days <= 300:
        step = 5
        rotation = "vertical"
    else:
        step = 10
        rotation = "vertical"
    
    ax.set_xticklabels(np.arange(0, days + 1, step, dtype=int), rotation=rotation)
    ax.set_xticks(np.arange(0, days + 1, step))
    
    ax.set_yticks(np.arange(0, initial_salary * 1.1, initial_salary / 20))
    
    ax.set_xlim([0, days])
    ax.set_ylim([0, initial_salary * 1.1])
    ax.set_xlabel('Days')
    ax.set_ylabel('Capital $')
    ax.legend(loc='best')
    ax.grid()
    
    plt.show()

interact(main, initial_salary=IntSlider(min=0, max=25000, step=500, value=15000, description='Initial Salary', style=style, layout=slider_layout),
               savings_ration=FloatSlider(min=0, max=1, step=0.01, value=0.2, description='Savings Ratio', style=style, layout=slider_layout),
               extraordinary_expenses=FloatSlider(min=0, max=1, step=0.005, description='Extraordinary Expenses', style=style, value=0.3, layout=slider_layout),
               fixed_costs=IntSlider(min=1, max=1000, step=1, value=100, description='Fixed Costs', style=style, layout=slider_layout),
               days=IntSlider(min=1, max=600, step=5, value=30, description='Total Number of Days', style=style, layout=slider_layout)
        );

House and Air Conditionings

def main(initial_houses, initial_ac, avg_time_house, avg_time_ac, total_houses, days):

    def function(s, time):
        x, y = s
        dydt = [
            (1 / avg_time_house) * (total_houses - x), # dx/dt: Change in the House sales
            (1 / avg_time_ac) * (x - y) # dx/dt: Change in the AC sales
        ]
        return dydt
    
    time = np.linspace(0, days, days * 10)
    initial_conditions = [initial_houses, initial_ac]
    solution = odeint(function, initial_conditions, time)

    #Graphic details
    fig, ax = plt.subplots(figsize=(15, 10))
 
    ax.plot(time, solution[:, 0], label='Houses(t)')
    ax.plot(time, solution[:, 1], label='Air Conditionings(t)')
    ax.plot((0, days), (total_houses, total_houses), label='Total Houses')
    
    if days <= 60:
        step = 1
        rotation = "horizontal"
    elif days <= 300:
        step = 5
        rotation = "vertical"
    else:
        step = 10
        rotation = "vertical"
    
    ax.set_xticklabels(np.arange(0, days + 1, step, dtype=int), rotation=rotation)
    ax.set_xticks(np.arange(0, days + 1, step))
    
    ax.set_yticks(np.arange(0, total_houses * 1.1, total_houses / 20))

    ax.set_xlim([0, days])
    ax.set_ylim([0, total_houses * 1.1])
    ax.set_xlabel('Months')
    ax.set_ylabel('Units')
    ax.legend(loc='best')
    ax.grid()
    
    plt.show()

interact(main, initial_houses=IntSlider(min=0, max=2000, step=10, value=0, description='Initial sold Houses', style=style, layout=slider_layout),
               initial_ac=IntSlider(min=0, max=2000, step=10, value=0, description='Initial sold AC', style=style, layout=slider_layout),
               total_houses=IntSlider(min=1, max=2000, step=100, value=1000, description='Total Houses', style=style, layout=slider_layout),
               avg_time_house=FloatSlider(min=0.1, max=24, step=0.1, value=2, description='Time for House', style=style, layout=slider_layout),
               avg_time_ac=FloatSlider(min=0.1, max=24, step=0.1, value=4, description='Time for AC', style=style, layout=slider_layout),
               days=IntSlider(min=1, max=360, step=10, value=30, description='Total Number of Days', style=style, layout=slider_layout),
        );

Stock Control

def main(desired_stock, initial_stock, initial_request, stock_control, market_demand, provider_delay, days):
    
    def function(v0, time):
        x, y = v0
        dydt = [
            (1 / provider_delay) * y - market_demand, # dx/dt -> Change in Stock
          - (1 / provider_delay) * y + market_demand + stock_control * (desired_stock - x) # dy/dt -> Change in Requests
        ]
        return dydt
    
    time = np.linspace(0, days, days * 10)
    initial_conditions = [initial_stock, initial_request]
    solution = odeint(function, initial_conditions, time)

    #Graphic details
    fig, ax = plt.subplots(figsize=(15, 10))
 
    ax.plot(time, solution[:, 0], label='Stock(t)')
    ax.plot(time, solution[:, 1], label='Requests(t)')
    ax.plot((0, days), (desired_stock, desired_stock), label='Desired Stock')
    
    if days <= 60:
        step = 1
        rotation = "horizontal"
    elif days <= 300:
        step = 5
        rotation = "vertical"
    else:
        step = 10
        rotation = "vertical"
    
    ax.set_xticklabels(np.arange(0, days + 1, step, dtype=int), rotation=rotation)
    ax.set_xticks(np.arange(0, days + 1, step))
    
    ax.set_xlim([0, days])
    ax.set_ylim([0, max(max(solution[:, 0]), max(solution[:, 1])) * 1.05])
    ax.set_xlabel('Days')
    ax.set_ylabel('Units')
    ax.legend(loc='best')
    ax.grid()
    
    plt.show()
    

interact(main,
        desired_stock=IntSlider(min=1, max=100, step=1, value=4, description='Desired Stock', style=style, layout=slider_layout),
        initial_stock=IntSlider(min=1, max=100, step=1, value=8, description='Initial Stock', style=style, layout=slider_layout),
        initial_request=IntSlider(min=1, max=100, step=1, value=14, description='Initial Requests', style=style, layout=slider_layout),
        stock_control=FloatSlider(min=0, max=2, step=0.001, value=1.5, description='Stock Control', style=style, layout=slider_layout),
        market_demand=FloatSlider(min=0, max=24, step=0.01, value=3, description='Market Demand', style=style, layout=slider_layout),
        provider_delay=FloatSlider(min=0, max=10, step=0.1, value=4, description='Provider Delay', style=style, layout=slider_layout),
        days=IntSlider(min=1, max=360, step=10, value=50, description='Total Number of Days', style=style, layout=slider_layout),
        );

Useful life

def main(useful_life, intake_mg, intake_interval, intake_number, hours):
    
    def function(y, t):
        return - (np.log(2) / useful_life) * y # dy/dt -> Change of mg 
    
    intake_hours = [intake_interval * i for i in range(intake_number - 1)]
    initial_condition = intake_mg
    times = []
    solutions = []
    
    for intake_time in intake_hours:
        time = np.arange(intake_time, intake_time + intake_interval, 0.1)
        solution = odeint(function, initial_condition, time)
        
        initial_condition = solution[-1] + intake_mg
        
        times.extend(time)
        solutions.extend(solution)
        
    
    intake_time = intake_hours[-1] + intake_interval
    time = np.arange(intake_time, intake_time + 10 * intake_interval, 0.1)
    solution = odeint(function, initial_condition, time)
    times.extend(time)
    solutions.extend(solution)
    
    #Graphic details
    fig, ax = plt.subplots(figsize=(15, 10))
    
    plt.plot(times, solutions, label='Concentration in the Body(t)')
    
    if hours <= 60:
        step = 1
        rotation = "horizontal"
    elif hours <= 300:
        step = 5
        rotation = "vertical"
    else:
        step = 10
        rotation = "vertical"
    
    ax.set_xticklabels(np.arange(0, hours + 1, step, dtype=int), rotation=rotation)
    ax.set_xticks(np.arange(0, hours + 1, step))
    
    ax.set_xlim([0, hours])
    ax.set_ylim([0, max(solutions) * 1.05])
    ax.set_xlabel('Hours')
    ax.set_ylabel('Concentration')
    ax.legend(loc='best')
    ax.grid()
    
    plt.show()

interact(main,        
        useful_life=FloatSlider(min=0, max=24, step=0.01, value=3.8, description='Useful Life (hs)', style=style, layout=slider_layout),
        intake_mg=FloatSlider(min=0, max=1, step=0.001, value=0.01, description='Miligrams per Intake', style=style, layout=slider_layout),
        intake_interval=FloatSlider(min=0, max=24, step=0.1, value=6, description='Hours between Intakes', style=style, layout=slider_layout),
        intake_number=IntSlider(min=1, max=20, step=1, value=4, description='Number of Intakes', style=style, layout=slider_layout),
        hours=FloatSlider(min=1, max=240, step=0.5, value=40, description='Total number of Hours', style=style, layout=slider_layout),
        );

Foxes and Rabbits

def main(rabbits_birthrate, rabbits_deathrate, foxes_birthrate, foxes_deathrate, initial_rabbits, zorros_inicial, days):

    def function(s, t):
        x, y = s
        dydt = [
            rabbits_birthrate * x - rabbits_deathrate * x * y, # dx/dy -> Change in Rabbits
            foxes_birthrate * x * y - foxes_deathrate * y # dy/dt -> Change in Foxes
        ]
        
        return dydt
    
    time = np.arange(0, days, 0.01)
    initial_conditions = [initial_rabbits, zorros_inicial]
    solution = odeint(function, initial_conditions, time)

    #Graphic details
    fig, axes = plt.subplots(1, 2, figsize=(15, 10))
    
    ax = axes[0]
    
    ax.plot(time, solution[:, 0], label='Liebres(t)')
    ax.plot(time, solution[:, 1], label='Zorros(t)')
    
    if days <= 30:
        step = 1
        rotation = "horizontal"
    elif days <= 150:
        step = 5
        rotation = "vertical"
    else:
        step = 10
        rotation = "vertical"
    
    ax.set_xticklabels(np.arange(0, days + 1, step, dtype=int), rotation=rotation)
    ax.set_xticks(np.arange(0, days + 1, step))
        
    ax.set_xlim([0, days])
    ax.set_ylim([0, max(max(solution[:, 0]), max(solution[:, 1])) * 1.05])
    ax.set_xlabel('Time')
    ax.set_ylabel('Population')
    ax.legend(loc='best')
    ax.grid()
    
    
    ax = axes[1]
    
    ax.plot(solution[:, 0], solution[:, 1], label='Foxes vs Rabbits')

    ax.set_xlim([0, max(solution[:, 0]) * 1.05])
    ax.set_ylim([0, max(solution[:, 1]) * 1.05])
    ax.set_xlabel('Rabbits')
    ax.set_ylabel('Foxes')
    ax.legend(loc='best')
    ax.grid()
    
    plt.tight_layout()
    plt.show()

interact(main, rabbits_birthrate=FloatSlider(min=0, max=24, step=0.01, value=1, description='Birth Rate of Rabbits', style=style, layout=slider_layout),
               rabbits_deathrate=FloatSlider(min=0, max=24, step=0.01, value=1, description='Death Rate of Rabbits', style=style, layout=slider_layout),
               foxes_birthrate=FloatSlider(min=0, max=24, step=0.01, value=1, description='Birth Rate of Foxes', style=style, layout=slider_layout),
               foxes_deathrate=FloatSlider(min=0, max=24, step=0.01, value=1, description='Death Rate of Foxes', style=style, layout=slider_layout),
               initial_rabbits=FloatSlider(min=0 , max=100, step=1, value=2, description='Initial Rabbits', style=style, layout=slider_layout),
               zorros_inicial=FloatSlider(min=0 , max=100, step=1, value=1, description='Initial Foxes', style=style, layout=slider_layout),
               days=FloatSlider(min=0 ,max=365 , step=10, value=15, description='Total number of Days', style=style, layout=slider_layout),
        );