From d84f880c331f1ed3851afe392f758ae47cc171c3 Mon Sep 17 00:00:00 2001 From: Wojciech Wojnowski <wojciech.wojnowski@pg.edu.pl> Date: Thu, 14 Oct 2021 09:43:29 +0000 Subject: [PATCH] Update main.py --- main.py | 386 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 214 insertions(+), 172 deletions(-) diff --git a/main.py b/main.py index 6e62803..8772888 100644 --- a/main.py +++ b/main.py @@ -2,6 +2,7 @@ W.Wojnowski 2021 ''' # imports: +import ast import tkinter as tk from tkinter import ttk from tkinter import messagebox @@ -28,7 +29,7 @@ colors = { 'background': '#dfe4ea', 'accent': '#70a1ff', 'text': 'black' - } +} # configure the background: root.configure(bg=colors['background'], padx=8, pady=8) @@ -95,6 +96,19 @@ s.theme_create("AGREE_2.0_theme", parent="alt", settings={ "foreground": [("active", colors['text'])], 'indicatorcolor': [('selected', colors['accent'])] }}, + 'TCheckbutton': { + 'configure': { + 'focuscolor': colors['foreground'], + 'background': colors['foreground'], + 'foreground': colors['text'], + 'indicatorcolor': colors['background']}, + "map": { + "background": [("active", colors['accent']), + ("pressed", colors['accent']), + ("disabled", colors['accent'])], + "foreground": [("active", colors['text'])], + 'indicatorcolor': [('selected', colors['accent'])] + }}, 'TMenubutton': { 'configure': { 'background': colors['accent'], @@ -171,13 +185,13 @@ def reset_scores(): criterion.optionvar_b.set('Select') criteria[0].radiovar.set(1) - criteria[1].radiovar.set(4) - criteria[2].radiovar.set(5) - criteria[3].radiovar.set(2) + criteria[1].radiovar.set(5) + criteria[2].radiovar.set(2) + criteria[3].radiovar.set(4) criteria[4].radiovar.set(4) - criteria[5].radiovar.set(4) - criteria[6].radiovar.set(3) - criteria[7].radiovar.set(1) + criteria[5].radiovar.set(3) + criteria[6].radiovar.set(1) + criteria[7].radiovar.set(4) criteria[8].radiovar.set(3) criteria[9].radiovar.set(4) @@ -307,13 +321,13 @@ for i in range(1, 11): # assign the default weights (this could be done using itemgetter or itertools.compress, but # that would require importing additional packages): criteria[0].radiovar.set(1) -criteria[1].radiovar.set(4) -criteria[2].radiovar.set(5) -criteria[3].radiovar.set(2) +criteria[1].radiovar.set(5) +criteria[2].radiovar.set(2) +criteria[3].radiovar.set(4) criteria[4].radiovar.set(4) -criteria[5].radiovar.set(4) -criteria[6].radiovar.set(3) -criteria[7].radiovar.set(1) +criteria[5].radiovar.set(3) +criteria[6].radiovar.set(1) +criteria[7].radiovar.set(4) criteria[8].radiovar.set(3) criteria[9].radiovar.set(4) @@ -335,7 +349,6 @@ def clear_frame(frame): global right_frame right_frame = tk.Frame(root, bd=1, padx=2, pady=2, width=500, height=500, bg=colors['foreground']) right_frame.pack(side='right', anchor='n') - print('clear frame done') # connect a float in range 0.0 : 1.0 to a colour in a spectrum from red to yellow to green @@ -419,7 +432,7 @@ def create_plot(event=None): plot_widget = canvas.get_tk_widget() plot_widget.pack(side='top') - print('final score: %s' % calculate_score()) + # print('final score: %s' % calculate_score()) # start the GUI with a default plot @@ -454,13 +467,11 @@ class Report: self.pdf.cell(100, 12, datetime.now().strftime("%d/%m/%Y %H:%M:%S")) self.pdf.ln(30) - def fieldColor(score): x = colorMapper(score)[0] * 255 y = colorMapper(score)[1] * 255 z = colorMapper(score)[2] * 255 self.pdf.set_fill_color(x, y, z) - print(x, y, z) def create_header(): self.pdf.set_font('Helvetica', 'B', 10) @@ -498,26 +509,27 @@ class Report: ('Sample preparation placement: ' + self.criteria[0].optionvar.get())) create_report_field('2.', self.tabs[1], self.criteria[1], - ('Mass [g] or volume [mL] of waste: ' + self.criteria[1].valuevar.get())) + ('Mass [g] or volume [mL] of problematic materials: ' + self.criteria[1].valuevar.get())) create_report_field('3.', self.tabs[2], self.criteria[2], - ('Mass [g] or volume [mL] of problematic materials: ' + self.criteria[2].valuevar.get())) + (self.criteria[2].optionvar.get())) create_report_field('4.', self.tabs[3], self.criteria[3], - (self.criteria[3].optionvar.get())) + ('Mass [g] or volume [mL] of waste: ' + self.criteria[3].valuevar.get())) create_report_field('5.', self.tabs[4], self.criteria[4], ('Mass [g] or volume [mL] of the sample: ' + self.criteria[4].valuevar.get())) create_report_field('6.', self.tabs[5], self.criteria[5], - ('Approximate energy consumption per analysis [W]: ' + self.criteria[5].valuevar.get())) + ('Hourly sample throughput: ' + self.criteria[5].valuevar.get())) create_report_field('7.', self.tabs[6], self.criteria[6], - ('Hourly sample throughput: ' + self.criteria[6].valuevar.get())) + ('No. of sample prep. steps: ' + self.criteria[6].optionvar_a.get() + + '; degree if automation: ' + self.criteria[6].optionvar_b.get())) create_report_field('8.', self.tabs[7], self.criteria[7], - ('No. of sample prep. steps: ' + self.criteria[7].optionvar_a.get() + - '; degree if automation: ' + self.criteria[7].optionvar_b.get())) + ('Approximate energy consumption per analysis [W]: ' + + str(round(float(self.criteria[7].valuevar.get()), 2)))) create_report_field('9.', self.tabs[8], self.criteria[8], (self.criteria[8].optionvar.get())) @@ -559,11 +571,19 @@ dropdown1['menu'].config(background=colors['background'], dropdown1.grid(column=0, row=3, padx=8, pady=8, sticky='w') -# # --------------------------- TAB2 --------------------------- -tab2 = Tab(tab_no='2', title='Waste', - text1='In analytical chemistry, all material inputs, including ' - 'the sample preparation stage, can be treated as waste.', - text2='Input mass [g] or volume [mL] of waste:', criterion=criteria[1]) +# --------------------------- TAB2 --------------------------- +tab2 = Tab(tab_no='2', title='Hazardous materials', + text1='The use of toxic materials, including the use of acids and bases ' + 'for derivatization and digestion, should be avoided.', + text2='Input mass [g] or volume [mL] of problematic substances:', + criterion=criteria[1]) + +label_tab2 = ttk.Label(tab2.frame, text='Include substances that are toxic via one of exposure pathways or ' + 'labeled as bioaccumulative, persistent, highly flammable, highly ' + 'oxidizable, explosive, or corrosive.', + wraplength=280) +label_tab2.grid(column=0, row=4, sticky='w') + # create a frame to pack the entry into in order to get a border for the entry: f2 = tk.Frame(tab2.frame, border=2, background=colors['accent']) f2.grid(column=0, row=3, padx=8, pady=8, sticky='w') @@ -576,13 +596,13 @@ def calc_crit_2(event=None): try: if criteria[1].valuevar.get() == 'Input': criteria[1].textvar.set(1.0) - elif float(criteria[1].valuevar.get()) >= 50: + elif float(criteria[1].valuevar.get()) >= 10: criteria[1].textvar.set(0) - elif float(criteria[1].valuevar.get()) <= 0.1: + elif float(criteria[1].valuevar.get()) <= 0.01: criteria[1].textvar.set(1.0) else: criteria[1].textvar.set( - abs(-0.174 * log(float(criteria[1].valuevar.get())) + 0.6125)) + abs(-0.147 * log(float(criteria[1].valuevar.get())) + 0.3299)) except ValueError: messagebox.showerror(title='Value error', message='The amount has to be a float or an integer, e.g. 0.14 or 21.') @@ -593,71 +613,63 @@ entry2.bind('<Return>', calc_crit_2) ttk.Button(tab2.frame, text='Set', command=calc_crit_2, width=8).grid(column=0, row=3, padx=80, pady=8, sticky='w') # --------------------------- TAB3 --------------------------- -tab3 = Tab(tab_no='3', title='Hazardous materials', - text1='The use of toxic materials, including the use of acids and bases ' - 'for derivatization and digestion, should be avoided.', - text2='Input mass [g] or volume [mL] of problematic substances:', - criterion=criteria[2]) - -label_tab3 = ttk.Label(tab3.frame, text='Include substances that are toxic via one of exposure pathways or ' - 'labeled as bioaccumulative, persistent, highly flammable, highly ' - 'oxidizable, explosive, or corrosive.', - wraplength=280) -label_tab3.grid(column=0, row=4, sticky='w') - -# create a frame to pack the entry into in order to get a border for the entry: -f3 = tk.Frame(tab3.frame, border=2, background=colors['accent']) -f3.grid(column=0, row=3, padx=8, pady=8, sticky='w') -# create the entry and pack it in the frame -entry3 = ttk.Entry(f3, textvariable=criteria[2].valuevar, width=10, style='AGREE_2.0_theme') -entry3.pack() - - -def calc_crit_3(event=None): - try: - if criteria[2].valuevar.get() == 'Input': - criteria[2].textvar.set(1.0) - elif float(criteria[2].valuevar.get()) >= 10: - criteria[2].textvar.set(0) - elif float(criteria[2].valuevar.get()) <= 0.01: - criteria[2].textvar.set(1.0) - else: - criteria[2].textvar.set( - abs(-0.147 * log(float(criteria[2].valuevar.get())) + 0.3299)) - except ValueError: - messagebox.showerror(title='Value error', - message='The amount has to be a float or an integer, e.g. 0.14 or 21.') - create_plot() - - -entry3.bind('<Return>', calc_crit_3) -ttk.Button(tab3.frame, text='Set', command=calc_crit_3, width=8).grid(column=0, row=3, padx=80, pady=8, sticky='w') - -# --------------------------- TAB4 --------------------------- -tab4 = Tab(tab_no='4', title='Sustainability and renewability of materials', +tab3 = Tab(tab_no='3', title='Sustainability and renewability of materials', text1='The application of materials from sustainable or renewable sources ' 'should be prioritized.', text2='Ratio of the mass of sustainable and renewable materials to the total ' - 'mass of materials used:', criterion=criteria[3]) + 'mass of materials used:', criterion=criteria[2]) -tab4_choices = {'No reagents or only sustainable and renewable materials are used': 1.0, +tab3_choices = {'No reagents or only sustainable and renewable materials are used': 1.0, '> 75% of reagents and materials are sustainable or renewable': 0.75, '50-75% of reagents and materials are sustainable or renewable': 0.50, '25-50% of reagents and materials are sustainable or renewable': 0.25, '< 25% of reagents and materials are sustainable or renewable': 0} -dropdown4 = ttk.OptionMenu(tab4.frame, criteria[3].optionvar, criteria[3].optionvar.get(), *tab4_choices.keys(), - command=lambda x: change_dropdown(criteria[3], tab4_choices)) +dropdown3 = ttk.OptionMenu(tab3.frame, criteria[2].optionvar, criteria[2].optionvar.get(), *tab3_choices.keys(), + command=lambda x: change_dropdown(criteria[2], tab3_choices)) # the ttk style for OptionMenu does not include a style for the tk dropdown menu, # so this has to be configured separately: -dropdown4['menu'].config(background=colors['background'], +dropdown3['menu'].config(background=colors['background'], activeborderwidth=5, activebackground=colors['accent'], activeforeground=colors['text'], foreground=colors['text']) -dropdown4.grid(column=0, row=3, padx=8, pady=8, sticky='w') +dropdown3.grid(column=0, row=3, padx=8, pady=8, sticky='w') + +# --------------------------- TAB4 --------------------------- +tab4 = Tab(tab_no='4', title='Waste', + text1='In analytical chemistry, all material inputs, including ' + 'the sample preparation stage, can be treated as waste.', + text2='Input mass [g] or volume [mL] of waste:', criterion=criteria[3]) +# create a frame to pack the entry into in order to get a border for the entry: +f4 = tk.Frame(tab4.frame, border=2, background=colors['accent']) +f4.grid(column=0, row=3, padx=8, pady=8, sticky='w') +# create the entry and pack it in the frame +entry4 = ttk.Entry(f4, textvariable=criteria[3].valuevar, width=10, style='AGREE_2.0_theme') +entry4.pack() -# # --------------------------- TAB5 --------------------------- + +def calc_crit_4(event=None): + try: + if criteria[3].valuevar.get() == 'Input': + criteria[3].textvar.set(1.0) + elif float(criteria[3].valuevar.get()) >= 50: + criteria[3].textvar.set(0) + elif float(criteria[3].valuevar.get()) <= 0.1: + criteria[3].textvar.set(1.0) + else: + criteria[3].textvar.set( + abs(-0.174 * log(float(criteria[3].valuevar.get())) + 0.6125)) + except ValueError: + messagebox.showerror(title='Value error', + message='The amount has to be a float or an integer, e.g. 0.14 or 21.') + create_plot() + + +entry4.bind('<Return>', calc_crit_4) +ttk.Button(tab4.frame, text='Set', command=calc_crit_4, width=8).grid(column=0, row=3, padx=80, pady=8, sticky='w') + +# --------------------------- TAB5 --------------------------- tab5 = Tab(tab_no='5', title='Size economy of the sample', text1='Smaller sample sizes should be favoured, as long as sample representativeness is assured', text2='Input mass [g] or volume [mL] of the sample:', @@ -690,10 +702,9 @@ entry5.bind('<Return>', calc_crit_5) ttk.Button(tab5.frame, text='Set', command=calc_crit_5, width=8).grid(column=0, row=3, padx=80, pady=8, sticky='w') # --------------------------- TAB6 --------------------------- -# remember to include a drop-down list of generic requirements for typical devices! -tab6 = Tab(tab_no='6', title='Energy consumption', - text1='The power consumption per analysis should be minimized.', - text2='Input the energy consumption [W] per analysis:', +tab6 = Tab(tab_no='6', title='Smaple throughput', + text1='Sample throughput determines the overall duration of the sample preparation stage.', + text2='Input the number of samples that can be prepared in one hour:', criterion=criteria[5]) f6 = tk.Frame(tab6.frame, border=2, background=colors['accent']) @@ -706,13 +717,13 @@ def calc_crit_6(event=None): try: if criteria[5].valuevar.get() == 'Input': criteria[5].textvar.set(1.0) - elif float(criteria[5].valuevar.get()) / 1000 >= 0.5: # /1000 to input W instead of kW - criteria[5].textvar.set(0) - elif float(criteria[5].valuevar.get()) / 1000 <= 0.01: + elif float(criteria[5].valuevar.get()) >= 70: criteria[5].textvar.set(1.0) + elif float(criteria[5].valuevar.get()) <= 1.0: + criteria[5].textvar.set(0.0) else: criteria[5].textvar.set( - abs(-0.264 * log(float(criteria[5].valuevar.get()) / 1000) + 0.1606)) + abs(0.2361 * log(float(criteria[5].valuevar.get())) - 0.0068)) except ValueError: messagebox.showerror(title='Value error', message='The amount has to be a float or an integer, e.g. 0.14 or 21.') @@ -722,80 +733,20 @@ def calc_crit_6(event=None): entry6.bind('<Return>', calc_crit_6) ttk.Button(tab6.frame, text='Set', command=calc_crit_6, width=8).grid(column=0, row=3, padx=80, pady=8, sticky='w') -label_tab6 = ttk.Label(tab6.frame, text='If more than one sample is prepared with the sample preparation ' - 'device, the energetic requirement for the device is divided ' - 'by the number of samples.', - wraplength=280) -label_tab6.grid(column=0, row=4, sticky='w') - -label_tab6_2 = ttk.Label(tab6.frame, text='Alternatively, select one of the listed generic devices for ' - 'a coarse estimate:', - wraplength=280) -label_tab6_2.grid(column=0, row=5, sticky='w') - -tab6_choices = {'A': 1.0, - 'B': 0.75, - 'C': 0.50, - 'D': 0.25, - 'E': 0} -dropdown6 = ttk.OptionMenu(tab6.frame, criteria[5].optionvar, criteria[5].optionvar.get(), *tab6_choices.keys(), - command=lambda x: change_dropdown(criteria[5], tab6_choices)) -# the ttk style for OptionMenu does not include a style for the tk dropdown menu, -# so this has to be configured separately: -dropdown6['menu'].config(background=colors['background'], - activeborderwidth=5, - activebackground=colors['accent'], - activeforeground=colors['text'], - foreground=colors['text']) - -dropdown6.grid(column=0, row=6, padx=8, pady=8, sticky='w') - # --------------------------- TAB7 --------------------------- -tab7 = Tab(tab_no='7', title='Smaple throughput', - text1='Sample throughput determines the overall duration of the sample preparation stage.', - text2='Input the number of samples that can be prepared in one hour:', - criterion=criteria[6]) - -f7 = tk.Frame(tab7.frame, border=2, background=colors['accent']) -f7.grid(column=0, row=3, padx=8, pady=8, sticky='w') -entry7 = ttk.Entry(f7, textvariable=criteria[6].valuevar, width=10, style='AGREE_2.0_theme') -entry7.pack() - - -def calc_crit_7(event=None): - try: - if criteria[6].valuevar.get() == 'Input': - criteria[6].textvar.set(1.0) - elif float(criteria[6].valuevar.get()) >= 70: - criteria[6].textvar.set(1.0) - elif float(criteria[6].valuevar.get()) <= 1.0: - criteria[6].textvar.set(0.0) - else: - criteria[6].textvar.set( - abs(0.2361 * log(float(criteria[6].valuevar.get())) - 0.0068)) - except ValueError: - messagebox.showerror(title='Value error', - message='The amount has to be a float or an integer, e.g. 0.14 or 21.') - create_plot() - - -entry7.bind('<Return>', calc_crit_7) -ttk.Button(tab7.frame, text='Set', command=calc_crit_7, width=8).grid(column=0, row=3, padx=80, pady=8, sticky='w') - -# --------------------------- TAB8 --------------------------- -tab8 = Tab(tab_no='8', title='Automation', +tab7 = Tab(tab_no='7', title='Integration and automation', text1='Sample preparation should be simplified and automated if possible.', text2='1. Select the number of discrete steps in the sample preparation procedure:', - criterion=criteria[7]) + criterion=criteria[6]) -tab8a_choices = {'2 steps or fewer': 1.0, +tab7a_choices = {'2 steps or fewer': 1.0, '3 steps': 0.75, '4 steps': 0.50, '5 steps': 0.25, '6 steps or more': 0} -def calc_crit_8(event=None): +def calc_crit_7(event=None): # create temporary variables for each dropdown: a = tk.StringVar() b = tk.StringVar() @@ -803,51 +754,143 @@ def calc_crit_8(event=None): a.set('1.0') b.set('1.0') - if criteria[7].optionvar_a.get() != 'Select': - a.set(tab8a_choices[criteria[7].optionvar_a.get()]) + if criteria[6].optionvar_a.get() != 'Select': + a.set(tab7a_choices[criteria[6].optionvar_a.get()]) - if criteria[7].optionvar_b.get() != 'Select': - b.set(tab8b_choices[criteria[7].optionvar_b.get()]) + if criteria[6].optionvar_b.get() != 'Select': + b.set(tab7b_choices[criteria[6].optionvar_b.get()]) - criteria[7].textvar.set(str(float(a.get()) * float(b.get()))) - print(a.get(), b.get(), criteria[7].textvar.get()) + criteria[6].textvar.set(str(float(a.get()) * float(b.get()))) create_plot() -dropdown8a = ttk.OptionMenu(tab8.frame, criteria[7].optionvar_a, criteria[7].optionvar_a.get(), *tab8a_choices.keys(), - command=calc_crit_8) +dropdown7a = ttk.OptionMenu(tab7.frame, criteria[6].optionvar_a, criteria[6].optionvar_a.get(), *tab7a_choices.keys(), + command=calc_crit_7) # the ttk style for OptionMenu does not include a style for the tk dropdown menu, # so this has to be configured separately: -dropdown8a['menu'].config(background=colors['background'], +dropdown7a['menu'].config(background=colors['background'], activeborderwidth=5, activebackground=colors['accent'], activeforeground=colors['text'], foreground=colors['text']) -dropdown8a.grid(column=0, row=3, padx=8, pady=8, sticky='w') +dropdown7a.grid(column=0, row=3, padx=8, pady=8, sticky='w') -label_tab8 = ttk.Label(tab8.frame, text='2. Select the degree of automation:', +label_tab7 = ttk.Label(tab7.frame, text='2. Select the degree of automation:', wraplength=280) -label_tab8.grid(column=0, row=4, sticky='w') +label_tab7.grid(column=0, row=4, sticky='w') -tab8b_choices = {'Fully automated systems': 1.0, +tab7b_choices = {'Fully automated systems': 1.0, 'Semi-automated systems': 0.50, 'Manual systems': 0.25} -dropdown8b = ttk.OptionMenu(tab8.frame, criteria[7].optionvar_b, criteria[7].optionvar_b.get(), *tab8b_choices.keys(), - command=calc_crit_8) +dropdown7b = ttk.OptionMenu(tab7.frame, criteria[6].optionvar_b, criteria[6].optionvar_b.get(), *tab7b_choices.keys(), + command=calc_crit_7) -dropdown8b['menu'].config(background=colors['background'], +dropdown7b['menu'].config(background=colors['background'], activeborderwidth=5, activebackground=colors['accent'], activeforeground=colors['text'], foreground=colors['text']) -dropdown8b.grid(column=0, row=5, padx=8, pady=8, sticky='w') +dropdown7b.grid(column=0, row=5, padx=8, pady=8, sticky='w') + +# --------------------------- TAB8 --------------------------- +# remember to include a drop-down list of generic requirements for typical devices! +tab8 = Tab(tab_no='8', title='Energy consumption', + text1='The power consumption per analysis should be minimized.', + text2='Input the energy consumption [W] per sample, accounting for the sample throughput:', + criterion=criteria[7]) + +f8 = tk.Frame(tab8.frame, border=2, background=colors['accent']) +f8.grid(column=0, row=3, padx=8, pady=8, sticky='w') +entry8 = ttk.Entry(f8, textvariable=criteria[7].valuevar, width=10, style='AGREE_2.0_theme') +entry8.pack() + + +def calc_crit_8(event=None): + try: + if criteria[7].valuevar.get() == 'Input': + criteria[7].textvar.set(1.0) + elif float(criteria[7].valuevar.get()) / 1000 >= 0.5: # /1000 to input W instead of kW + criteria[7].textvar.set(0) + elif float(criteria[7].valuevar.get()) / 1000 <= 0.01: + criteria[7].textvar.set(1.0) + else: + criteria[7].textvar.set( + abs(-0.264 * log(float(criteria[7].valuevar.get()) / 1000) + 0.1606)) + except ValueError: + messagebox.showerror(title='Value error', + message='The amount has to be a float or an integer, e.g. 0.14 or 21.') + create_plot() + + +entry8.bind('<Return>', calc_crit_8) +ttk.Button(tab8.frame, text='Set', command=calc_crit_8, width=8).grid(column=0, row=3, padx=80, pady=8, sticky='w') + +# label_tab8 = ttk.Label(tab8.frame, text='If more than one sample is prepared with the sample preparation ' +# 'device, the energetic requirement for the device is divided ' +# 'by the number of samples.', +# wraplength=280) +# label_tab8.grid(column=0, row=4, sticky='w') + +label_tab8_2 = ttk.Label(tab8.frame, text='Alternatively, select one or several generic devices for ' + 'a rough estimate based on the throughput provided in Criterion #6:', + wraplength=280) +label_tab8_2.grid(column=0, row=5, sticky='w') + +multiselect_menu8 = ttk.Menubutton(tab8.frame, text='Select used devices') +multiselect_menu8.grid(column=0, row=6, padx=8, pady=8, sticky='w') + + +class Device: + def __init__(self, name, wattage): + self.name = name + self.wattage = wattage + self.state = tk.IntVar() + + +# Modify this function to calculate the score: +def crit_8_rough_estimate(): + comb_wattage = 0 + for instrument in instruments: + if instrument.state.get(): + comb_wattage += instrument.wattage + else: + pass + if criteria[5].valuevar.get() == 'Input': + messagebox.showerror(title='Value error', + message='Please fill in the throughput value in Criterion #6.') + else: + criteria[7].valuevar.set(comb_wattage / float(criteria[5].valuevar.get())) + calc_crit_8() + + +# open an external list of sample prep instruments and corresponding wattage {'Freeze dryer: 1000,} +def load_dict(): + dict_of_devices = open('list_of_devices.config', 'r').read() + dvcs = ast.literal_eval(dict_of_devices) + return dvcs + + +devices = load_dict() + +# create a list of objects of the Devices class from the external dictionary +instruments = [] +for device in devices: + instruments.append(Device(name=device, wattage=devices[device])) + +multiselect_menu8.menu = tk.Menu(multiselect_menu8, tearoff=0) +multiselect_menu8['menu'] = multiselect_menu8.menu + +for instrument in instruments: + multiselect_menu8.menu.add_checkbutton(label=instrument.name, variable=instrument.state, + command=crit_8_rough_estimate, + background=colors['background'], activebackground=colors['accent']) # --------------------------- TAB9 --------------------------- -tab9 = Tab(tab_no='9', title='Analytical instrumentation for final determination', +tab9 = Tab(tab_no='9', title='Post-sample preparation configuration for analysis', text1='The prepared sample matrix should be compatible with the analytical instrument, ' 'which in turn affects the overall environmental impact of the procedure.', text2='Select the final determination technique or its closest analogue:', @@ -910,4 +953,3 @@ def main(): main() - -- GitLab