File size: 4,595 Bytes
843a502
 
702ad4b
843a502
 
 
 
 
 
bb7886f
1ffa54d
843a502
 
 
 
 
 
 
 
9012508
843a502
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1ffa54d
 
 
843a502
 
6835edb
1ffa54d
843a502
 
1ffa54d
 
 
 
 
 
 
 
 
 
 
 
843a502
 
 
 
 
1ffa54d
 
 
 
 
 
 
 
 
 
 
 
843a502
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44a013a
 
 
 
 
843a502
 
 
 
 
1ffa54d
 
843a502
fbe4618
702ad4b
 
6835edb
 
 
6935076
 
843a502
1ffa54d
843a502
 
 
 
 
 
 
 
 
 
1ffa54d
702ad4b
1ffa54d
843a502
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import marimo

__generated_with = "0.11.2"
app = marimo.App(width="medium")


@app.cell
def _():
    import marimo as mo
    import pycek_public as cek

    lab = cek.crystal_violet(make_plots=True)
    return cek, lab, mo


@app.cell
def _(mo):
    mo.md(
        """
        # Crystal Violet Lab

        This notebook mimics a kinetics laboratory experiment, where a UV-Vis spectrophotometer is used to measure the absorbance as the reaction between crystal violet and hydroxide proceeds. 
        The absorbance versus time data can then be used to determine the rate of the reaction with respect to both crystal violet and hydroxide ions.

        ## Objectives
        1. Determine the reaction order with respect to CV
        2. Determine the reaction order with respect to hydroxide
        3. Determine the rate constant for the overall reaction
        4. Determine the activation energy


        ## Instructions
        1. Type your student ID
        2. Select the volumes of the CV solution, the hydroxide solution and DI water to use
        3. Select the temperature of the experiment
        4. Click "Run Experiment"
        5. Perform two sets of at least three experiments each:
           - constant [CV] while the [OH$^-$] is varied
           - constant [OH$^-$] while the [CV] is varied
        6. Obtain another set of data where the temperature is changed and compute the activation energy and pre-exponential factor
        ___
        """
    )
    return


@app.cell
def _(lab, mo):
    def set_ID(value):
        return cek.set_ID(mo, lab, value)

    student_ID = mo.ui.text(value="", label="Student ID:", on_change=set_ID)

    def set_fname(value):
        lab.output_file = value

    exp_ID = mo.ui.text(value="Automatic", label="Output file:", on_change=set_fname)

    cv_volume = mo.ui.number(
        start=0, stop=100, step=1, value=None, label="Volume of CV solution (mL)"
    )
    oh_volume = mo.ui.number(
        start=0, stop=100, step=1, value=None, label="Volume of OH solution (mL)"
    )
    h2o_volume = mo.ui.number(
        start=0, stop=100, step=1, value=None, label="Volume of DI water (mL)"
    )
    temperature = mo.ui.number(
        start=0, stop=100, step=1, value=25, label="Temperature (C)"
    )
    run_button = mo.ui.run_button(label="Run Experiment")
    reset_button = mo.ui.run_button(label="Reset Counter")

    # Create download button using marimo's download function

    mo.vstack(
        [
            student_ID,
            exp_ID,
            cv_volume,
            oh_volume,
            h2o_volume,
            temperature,
            run_button,
            reset_button,
        ]
    )
    return (
        cv_volume,
        exp_ID,
        h2o_volume,
        oh_volume,
        reset_button,
        run_button,
        set_ID,
        set_fname,
        student_ID,
        temperature,
    )


@app.cell
def _(
    cek,
    cv_volume,
    h2o_volume,
    lab,
    mo,
    oh_volume,
    reset_button,
    run_button,
    temperature,
):
    if reset_button.value:
        lab.ID = 0
        lab._set_filename(None)

    image = ""
    message = ""
    download_button = ""
    if run_button.value:
        mo.stop(
            not student_ID.value.isdigit(),
            mo.md(f"### Invalid Student ID: {student_ID.value}"),
        )
        
        cv_vol = cv_volume.value
        oh_vol = oh_volume.value
        h2o_vol = h2o_volume.value

        lab.set_parameters(
            volumes={"cv": cv_vol, "oh": oh_vol, "h2o": h2o_vol},
            temperature=temperature.value + 273.15,
        )
        data = lab.create_data_for_lab()
        file_content = lab.write_data_to_string()

        fname = lab.output_file
        if not fname:
            fname = lab.filename_gen.random
        if not fname.endswith('.csv'):
            fname += '.csv'
        message = f"### Running Experiment\n"
        for k, v in lab.metadata.items():
            message += f"####{k} = {v}\n"
        message += f"#### File created = {fname}\n"

        download_button = mo.download(
            file_content,
            filename=fname,
            label=f"Download {fname}",
        )

        plot = cek.plotting()
        image = plot.quick_plot(scatter=data, output="marimo")

    mo.hstack([mo.vstack([mo.md(message), download_button]), image])
    return (
        cv_vol,
        data,
        download_button,
        file_content,
        fname,
        h2o_vol,
        image,
        k,
        message,
        oh_vol,
        plot,
        v,
    )


if __name__ == "__main__":
    app.run()