<jupyter_start><jupyter_text>[Open empty notebook](Empty.ipynb)  Bomb Calorimitery Virtual Experiment<jupyter_code>%%javascript
$('#appmode-leave').hide();
$('#copy-binder-link').hide();
$('#visit-repo-link').hide();
import ipywidgets as ipw
import json
import random
import time
import pandas as pd
import os
import webbrowser
import math
import numpy as np
from IPython.display import display, Markdown, FileLink, clear_output
class StopExecution(Exception):
    def _render_traceback_(self):
        pass
%%javascript
IPython.OutputArea.prototype._should_scroll = function(lines) {
   return false;
}
with open(".lab.json") as infile:
    jsdata = json.load(infile)

params = jsdata["cal1"]
t = int( time.time() * 1000.0 )
random.seed( ((t & 0xff000000) >> 24) +
             ((t & 0x00ff0000) >>  8) +
             ((t & 0x0000ff00) <<  8) +
             ((t & 0x000000ff) << 24)   )

params["roomT"] = random.gauss(298,2)
params["slope"] = (2*random.random()) / params["nTime"]

# sample properties
params["mass"] = 0.0
params["mM"] = 0. # molar mass mole/g
params["n1"] = 0  # moles of CO2 per mole of substance burnt
params["n2"] = 0  # moles of H2O per mole of substance burnt
params["dn"] = 0  # change in moles of gas
params["dH"] = 0
w = ipw.Dropdown(
    options=['None',
             'Benzoic acid', 
             'Sucrose', 
             'Naphthalene'],
    value='None',
    description='Sample:'
)

def sample_select(change):
    if change['new'] == "Benzoic acid":
        params["mM"] = 122.123
        params["n1"] = 7 
        params["n2"] = 3 
        params["dn"] = 1
        params["dH"] = -386000
        
    if change['new'] == "Sucrose":
        params["mM"] = 342.3
        params["n1"] = 12 
        params["n2"] = 11 
        params["dn"] = 0
        params["dH"] = -2221200

    if change['new'] == "Naphthalene":
        params["mM"] = 128.17
        params["n1"] = 10 
        params["n2"] = 4 
        params["dn"] = 2
        params["dH"] = -77000 

w.observe(sample_select)
def run_experiment():
    
    # Error handing
    if float(params["mM"]) < 0.1:
        with out_Error:
            print("Please select a sample to use in the experiment")
        raise StopExecution

    if params["mass"] < 0.1:
        with out_Error:
            print("Please prepare a tablet first")
        raise StopExecution

    moles = params["mass"] / 1000 / params["mM"]

    # combustion enthalpy
    # nH{co2} + mH{h2o} - H = DcH
    DcH = params["n1"]*params["dH_co2"] + params["n2"]*params["dH_h2o"] - params["dH"]
    
    dH = DcH * moles
    dnrt = moles * params["R"] * params["roomT"] * params["dn"] 
    dU = dH - dnrt
    deltaT = -dU / params["cc"] #+ params["roomT"] 
   
    res = pd.DataFrame(columns=["Time [min]" , "T [K]"])
    for i in range(0, params["nTime"]):
        var_list = []
        var_list.append(i/10)
        tempOut = params["roomT"] + random.gauss(0,params["error"]) + params["slope"] * i
        if (i > params["mixTime"]):
            tempOut = tempOut + deltaT * (1-math.exp(-(i-params["mixTime"])/params["relaxTime"] ))
            
        var_list.append(tempOut)
        res.loc[len(res)] = var_list
    
    res.to_csv(respath.value, index=False)
    local_file = FileLink(respath.value, result_html_prefix="Click here to download: ")
    with out_P:
        display(local_file)
        display(res.tail(params["nTime"]))

out_Error = ipw.Output()
out_P = ipw.Output()
out_T = ipw.Output()

# output filename
fileName = "results.csv"
respath = ipw.Text(fileName)

def reset(btn):
    if os.path.exists(respath.value):
        os.remove(respath.value)
    
    with out_Error:
        out_Error.clear_output()
        
    with out_P:
        out_P.clear_output()
        
    with out_T:
        out_T.clear_output()
    
    clear_output()
    create_ipw()

def calc(btn):
    out_P.clear_output()
    run_experiment()

def make_tablet(btn):
    out_T.clear_output()

    params["mass"] = random.gauss(1000,100)
    
    with out_T:
        print("Mass of the tablet (mg) :",params["mass"])
        

label_layout = ipw.Layout(width='300px')

# interactive buttons ---
btn_calc = ipw.Button(description="Perform Experiment", layout=label_layout)
btn_calc.on_click(calc)

btn_reset = ipw.Button(description="Reset Experiment", layout=label_layout)
btn_reset.on_click(reset)

btn_tab = ipw.Button(description="Make tablet", layout=label_layout)
btn_tab.on_click(make_tablet)

# ---
# reset(btn_reset)


# -- output widgets
def create_ipw():
    rows = []
    
    rows.append(ipw.HBox([ipw.Label('Output filename : ',layout=label_layout),respath]))
    rows.append(ipw.HBox([w]))
    rows.append(ipw.HBox([btn_tab]))
    rows.append(ipw.HBox([out_T]))
    rows.append(ipw.HBox([btn_calc,btn_reset]))
    rows.append(ipw.HBox([out_Error]))
    rows.append(ipw.HBox([out_P]))
    display(ipw.VBox(rows))

create_ipw()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15923437181836694, 'fraction_numerical': 0.027692934229281204, 'mean_word_length': 2.901509134233519, 'pattern_counts': {'":': 3, '<': 11, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '370179', 'license': 'MIT', 'n_tokens_mistral': 1845, 'n_tokens_neox': 1724, 'n_words': 352, 'path': 'week_03_bombCalorimetry/virtualExperiment.ipynb', 'repo_name': 'blake-armstrong/TeachingNotebook', 'size': '4911'}