def on_trace_change(self, _name, _index, _mode):
        """Updates the number of plans with options dependent on number of externalities input."""
        for group in self.groups:
            group.grid_forget()
            group.destroy()
        self.groups = []
        rad_labels = [
            "Exact", "Gaussian", "Triangular", "Rectangular", "Discrete"
        ]
        figs = [
            none_dist(),
            gauss_dist(),
            tri_dist(),
            rect_dist(),
            disc_dist()
        ]
        self.choices = [[tk.StringVar() for ext in plan.exts.indiv]
                        for plan in self.data_cont.plan_list]
        rads = []
        self.ranges = []
        self.labels = []
        for plan in self.data_cont.plan_list:
            row_index = 0
            self.groups.append(ttk.LabelFrame(self, text=plan.name))
            self.groups[-1].grid(row=4 + plan.num,
                                 sticky="ew",
                                 padx=FIELDX_PADDING,
                                 pady=FIELDY_PADDING)
            rads.append([])
            self.ranges.append([])
            self.labels.append([])
            for ext in plan.exts.indiv:
                choice = plan.exts.indiv.index(ext)
                self.choices[plan.num][choice].set(ext.dist)
                titles = ttk.Label(self.groups[-1],
                                   text=ext.title + " - $" +
                                   '{:,.2f}'.format(ext.amount),
                                   font=SMALL_FONT)
                titles.grid(row=row_index,
                            column=0,
                            sticky="w",
                            padx=FIELDX_PADDING,
                            pady=FIELDY_PADDING)
                rads[plan.num].append([
                    tk.Radiobutton(self.groups[-1],
                                   variable=self.choices[plan.num][choice],
                                   value="none"),
                    tk.Radiobutton(self.groups[-1],
                                   variable=self.choices[plan.num][choice],
                                   value="gauss"),
                    tk.Radiobutton(self.groups[-1],
                                   variable=self.choices[plan.num][choice],
                                   value="tri"),
                    tk.Radiobutton(self.groups[-1],
                                   variable=self.choices[plan.num][choice],
                                   value="rect"),
                    tk.Radiobutton(self.groups[-1],
                                   variable=self.choices[plan.num][choice],
                                   value="discrete")
                ])
                self.ranges[plan.num].append([
                    tk.Entry(self.groups[-1],
                             width=int(ENTRY_WIDTH / 2),
                             font=SMALL_FONT) for i in range(6)
                ])
                self.labels[plan.num].append([])
                for col in range(5):
                    fig_label = ttk.Label(self.groups[-1])
                    fig_label.grid(row=row_index + 1, column=col)
                    fig = figs[col]
                    canvas = FigureCanvasTkAgg(fig, master=fig_label)
                    canvas.get_tk_widget().grid(row=1, column=col + 1)
                    canvas.show()
                    rads[plan.num][choice][col].grid(row=row_index + 3,
                                                     column=col)
                    rad_label = ttk.Label(self.groups[-1],
                                          text=rad_labels[col],
                                          font=SMALL_FONT)
                    rad_label.grid(row=row_index + 2, column=col)

                if self.choices[plan.num][choice].get() == "none":
                    row_index += 4
                    for entry in self.ranges[plan.num][choice]:
                        entry.grid_remove()
                elif self.choices[plan.num][choice].get() == "gauss":
                    self.labels[plan.num][choice] = [
                        tk.Label(self.groups[-1],
                                 text="Standard Deviation ($)")
                    ]
                    self.labels[plan.num][choice][0].grid(row=row_index + 4,
                                                          column=0)
                    for entry in self.ranges[plan.num][choice]:
                        entry.grid_remove()
                    self.ranges[plan.num][choice][0].grid(row=row_index + 4,
                                                          column=1)
                    row_index += 5
                elif self.choices[plan.num][choice].get() == "discrete":
                    self.labels[plan.num][choice] = [
                        tk.Label(self.groups[-1], text="Lowest Amount ($)"),
                        tk.Label(self.groups[-1], text="Middle Amount ($)"),
                        tk.Label(self.groups[-1], text="Highest Amount ($)"),
                        tk.Label(self.groups[-1],
                                 text="Likelihood of Lowest Amount (%)"),
                        tk.Label(self.groups[-1],
                                 text="Likelihood of Middle Amount (%)"),
                        tk.Label(self.groups[-1],
                                 text="Likelihood of Highest Amount (%)")
                    ]
                    for label in self.labels[plan.num][choice][0:3]:
                        label.grid(row=row_index +
                                   self.labels[plan.num][choice].index(label) +
                                   5,
                                   column=0)
                    for label in self.labels[plan.num][choice][3:6]:
                        label.grid(row=row_index +
                                   self.labels[plan.num][choice].index(label) +
                                   2,
                                   column=2)
                    for entry in self.ranges[plan.num][choice][0:3]:
                        entry.grid(row=row_index +
                                   self.ranges[plan.num][choice].index(entry) +
                                   5,
                                   column=1,
                                   padx=FIELDX_PADDING,
                                   pady=FIELDY_PADDING)
                    for entry in self.ranges[plan.num][choice][3:6]:
                        entry.grid(row=row_index +
                                   self.ranges[plan.num][choice].index(entry) +
                                   2,
                                   column=3,
                                   padx=FIELDX_PADDING,
                                   pady=FIELDY_PADDING)
                    row_index += 8
                else:
                    self.labels[plan.num][choice] = [
                        tk.Label(self.groups[-1], text="Lower Bound ($)"),
                        tk.Label(self.groups[-1], text="Upper Bound ($)")
                    ]
                    self.labels[plan.num][choice][0].grid(row=row_index + 4,
                                                          column=0)
                    self.labels[plan.num][choice][1].grid(row=row_index + 4,
                                                          column=2)
                    for entry in self.ranges[plan.num][choice]:
                        entry.grid_remove()
                    self.ranges[plan.num][choice][0].grid(row=row_index + 4,
                                                          column=1)
                    self.ranges[plan.num][choice][1].grid(row=row_index + 4,
                                                          column=3)
                    row_index += 5
                for entry in self.ranges[plan.num][choice]:
                    try:
                        text = '{:,.2f}'.format(
                            float(ext.range[self.ranges[plan.num]
                                            [choice].index(entry)]))
                    except ValueError:
                        text = ext.range[self.ranges[plan.num][choice].index(
                            entry)]
                    entry.insert(tk.END, text)
Beispiel #2
0
    def create_widgets(self, controller):
        """Widgets include: buttons, text boxes, and labels"""

        group0 = ttk.LabelFrame(self)
        group0.grid(row=0, sticky="ew", padx=FRAME_PADDING, pady=FRAME_PADDING)
        ttk.Label(group0, text="Input the project name, the list of alternatives, "
                  "the planning horizon,the calculated \n"
                  "real discount rate for discounting future costs to "
                  "present values, and hazard specifics.",
                  font=SMALL_FONT).grid(row=1, column=0, sticky="e",
                                        padx=FIELDX_PADDING, pady=FIELDY_PADDING)


        ttk.Button(group0, text="More Information",
                   command=self.show_info).grid(row=1, column=1, sticky="w",
                                                padx=FIELDX_PADDING, pady=FIELDY_PADDING)

        # ===== Project Description Specifics
        group1 = ttk.LabelFrame(self, text="Project Description")
        group1.grid(row=2, sticky="ew", padx=FRAME_PADDING, pady=FRAME_PADDING)

        ttk.Label(group1, text="Name",
                  font=SMALL_FONT).grid(row=0, column=0, sticky="e",
                                        padx=FIELDX_PADDING, pady=FIELDY_PADDING)
        self.name_ent = tk.Entry(group1, width=ENTRY_WIDTH, font=SMALL_FONT)
        self.name_ent.insert(tk.END, "<enter project name>")
        self.name_ent.grid(row=0, column=1, sticky="e", padx=FIELDX_PADDING, pady=FIELDY_PADDING)

        ttk.Label(group1, text="Planning Horizon",
                  font=SMALL_FONT).grid(row=1, column=0, sticky="e",
                                        padx=FIELDX_PADDING, pady=FIELDY_PADDING)
        self.hor_ent = tk.Entry(group1, width=ENTRY_WIDTH, font=SMALL_FONT)
        self.hor_ent.insert(tk.END, "<enter number of years for analysis>")
        self.hor_ent.grid(row=1, column=1, sticky="e", padx=FIELDX_PADDING, pady=FIELDY_PADDING)

        # ===== Project Alternatives Names
        group2 = ttk.LabelFrame(self, text="Project Alternatives")
        group2.grid(row=3, sticky="ew", padx=FRAME_PADDING, pady=FRAME_PADDING)

        self.choices = [1, 2, 3, 4, 5, 6]
        ttk.Label(group2, text="Number of Alternative Plans",
                  font=SMALL_FONT).grid(row=0, column=0, sticky="e",
                                        padx=FIELDX_PADDING, pady=FIELDY_PADDING)
        self.num_plans_ent = ttk.Combobox(group2, textvariable=self.choice_var, font=SMALL_FONT,
                                          width=ENTRY_WIDTH, values=self.choices)
        self.num_plans_ent.insert(tk.END, 0)
        self.num_plans_ent.grid(row=0, column=1, sticky="e",
                                padx=FIELDX_PADDING, pady=FIELDY_PADDING)
        self.choice_var.trace("w", self.on_trace_choice)
        # ^ Updates other widgets when this field is updated

        ttk.Label(group2, text="Base scenario",
                  font=SMALL_FONT).grid(row=1, column=0, sticky="e",
                                        padx=FIELDX_PADDING, pady=FIELDY_PADDING)
        ttk.Label(group2, text="---------------------------------------------------",
                  font=SMALL_FONT).grid(row=1, column=1, sticky="e",
                                        padx=FIELDX_PADDING, pady=FIELDY_PADDING)

        self.name_lbls = [ttk.Label(group2, text="Alternative 1", font=SMALL_FONT),
                          ttk.Label(group2, text="Alternative 2", font=SMALL_FONT),
                          ttk.Label(group2, text="Alternative 3", font=SMALL_FONT),
                          ttk.Label(group2, text="Alternative 4", font=SMALL_FONT),
                          ttk.Label(group2, text="Alternative 5", font=SMALL_FONT),
                          ttk.Label(group2, text="Alternative 6", font=SMALL_FONT)]
        for lbl in self.name_lbls:
            my_row = self.name_lbls.index(lbl) + 2
            lbl.grid(row=my_row, column=0, sticky="e", padx=FIELDX_PADDING, pady=FIELDY_PADDING)
            lbl.configure(state="disabled")
        self.name_ents = [tk.Entry(group2, textvariable=self.traces[i],
                                   width=ENTRY_WIDTH, font=SMALL_FONT) for i in range(6)]
        for ent in self.name_ents:
            my_row = self.name_ents.index(ent) + 2
            ent.insert(tk.END, "<enter plan name>")
            ent.grid(row=my_row, column=1, sticky="e", padx=FIELDX_PADDING, pady=FIELDY_PADDING)
            ent.configure(state="disabled")

        # ===== Discount Rate and Hazard Specifics
        group3 = ttk.LabelFrame(self, text="Discount Rate")
        group3.grid(row=4, sticky="ew", padx=FRAME_PADDING, pady=FRAME_PADDING)

        ttk.Label(group3, text="Real Discount Rate",
                  font=SMALL_FONT).grid(row=0, column=0, sticky="e",
                                        padx=FIELDX_PADDING, pady=FIELDY_PADDING)
        self.dis_ent = tk.Entry(group3, width=ENTRY_WIDTH, font=SMALL_FONT)
        self.dis_ent.insert(tk.END, "5.00")
        self.dis_ent.grid(row=0, column=1, sticky="e", padx=FIELDX_PADDING, pady=FIELDY_PADDING)
        ttk.Label(group3, text="%", font=SMALL_FONT).grid(row=0, column=2, sticky='w',
                                                          pady=FIELDY_PADDING)

        ttk.Button(group3, text="Restore Default",
                   command=self.restore).grid(row=2, column=0, sticky="w",
                                              padx=FIELDX_PADDING, pady=FIELDY_PADDING)

        group4 = ttk.LabelFrame(self, text="Hazard Recurrence")
        group4.grid(row=5, sticky="ew", padx=FRAME_PADDING, pady=FRAME_PADDING)
        self.recur_choice = tk.StringVar()
        self.recur_choice.set("none")
        recur_rads = [tk.Radiobutton(group4, variable=self.recur_choice, value="none"),
                      tk.Radiobutton(group4, variable=self.recur_choice, value="gauss"),
                      tk.Radiobutton(group4, variable=self.recur_choice, value="tri"),
                      tk.Radiobutton(group4, variable=self.recur_choice, value="rect"),
                      tk.Radiobutton(group4, variable=self.recur_choice, value="discrete")]
        rad_labels = ["Exact", "Gaussian", "Triangular", "Rectangular", "Discrete"]
        figs = [none_dist(), gauss_dist(), tri_dist(), rect_dist(), disc_dist()]
        for col in range(len(recur_rads)):
            fig_label = ttk.Label(group4)
            fig_label.grid(row=1, column=col)
            fig = figs[col]
            canvas = FigureCanvasTkAgg(fig, master=fig_label)
            canvas.get_tk_widget().grid(row=1, column=col+1)
            canvas.show()
            recur_rads[col].grid(row=3, column=col)
            rad_label = ttk.Label(group4, text=rad_labels[col], font=SMALL_FONT)
            rad_label.grid(row=2, column=col)
        self.recur_choice.trace("w", self.on_trace_change_recur)
        self.recur_label = [tk.Label(group4, text="Most Frequent (Years)"),
                            tk.Label(group4, text="Expected Recurrence (Years)"),
                            tk.Label(group4, text="Least Frequent (Years)")]
        self.recur_one_label = tk.Label(group4, text="Recurrence (Years)")
        self.recur_one_label.grid(row=4, column=0)
        self.recur_gauss_label = [tk.Label(group4, text="Expected Recurrence (Years)"),
                                  tk.Label(group4, text="Standard Deviation (Years)")]
        self.recur_discrete_label = [tk.Label(group4, text="Most Frequent (Years)"),
                                     tk.Label(group4, text="Middle Recurrence (Years)"),
                                     tk.Label(group4, text="Least Frequence (Years)"),
                                     tk.Label(group4, text="Likelihood of Most Frequent (%)"),
                                     tk.Label(group4, text="Likelihood of Middle Recurrence (%)"),
                                     tk.Label(group4, text="Likelihood of Least Frequent (%)")]
        self.recur_range = [tk.Entry(group4, width=int(ENTRY_WIDTH/2), font=SMALL_FONT),
                            tk.Entry(group4, width=int(ENTRY_WIDTH/2), font=SMALL_FONT),
                            tk.Entry(group4, width=int(ENTRY_WIDTH/2), font=SMALL_FONT),
                            tk.Entry(group4, width=int(ENTRY_WIDTH/2), font=SMALL_FONT),
                            tk.Entry(group4, width=int(ENTRY_WIDTH/2), font=SMALL_FONT),
                            tk.Entry(group4, width=int(ENTRY_WIDTH/2), font=SMALL_FONT)]
        self.recur_range[0].grid(row=4, column=1, padx=FIELDX_PADDING, pady=FIELDY_PADDING)

        group5 = ttk.LabelFrame(self, text="Hazard Magnitude")
        group5.grid(row=6, sticky="ew", padx=FRAME_PADDING, pady=FRAME_PADDING)
        self.mag_choice = tk.StringVar()
        self.mag_choice.set("none")
        mag_rads = [tk.Radiobutton(group5, variable=self.mag_choice, value="none"),
                    tk.Radiobutton(group5, variable=self.mag_choice, value="gauss"),
                    tk.Radiobutton(group5, variable=self.mag_choice, value="tri"),
                    tk.Radiobutton(group5, variable=self.mag_choice, value="rect"),
                    tk.Radiobutton(group5, variable=self.mag_choice, value="discrete")]
        rad_labels = ["Exact", "Gaussian", "Triangular", "Rectangular", "Discrete"]
        figs = [none_dist(), gauss_dist(), tri_dist(), rect_dist(), disc_dist()]
        for col in range(len(mag_rads)):
            fig_label = ttk.Label(group5)
            fig_label.grid(row=1, column=col)
            fig = figs[col]
            canvas = FigureCanvasTkAgg(fig, master=fig_label)
            canvas.get_tk_widget().grid(row=1, column=col+1)
            canvas.show()
            mag_rads[col].grid(row=3, column=col)
            rad_label = ttk.Label(group5, text=rad_labels[col], font=SMALL_FONT)
            rad_label.grid(row=2, column=col)
        self.mag_choice.trace("w", self.on_trace_change_mag)
        self.mag_label = [tk.Label(group5, text="Least Severe (%)"),
                          tk.Label(group5, text="Expected Magnitude (%)"),
                          tk.Label(group5, text="Most Severe (%)")]
        self.mag_one_label = tk.Label(group5, text="Magnitude (%)")
        self.mag_one_label.grid(row=4, column=0)
        self.mag_gauss_label = [tk.Label(group5, text="Expected Magnitude (%)"),
                                tk.Label(group5, text="Standard Deviation (%)")]
        self.mag_discrete_label = [tk.Label(group5, text="Least Severe (%)"),
                                   tk.Label(group5, text="Middle Severity (%)"),
                                   tk.Label(group5, text="Most severe (%)"),
                                   tk.Label(group5, text="Likelihood of Least Severe (%)"),
                                   tk.Label(group5, text="Likelihood of Middle Severity (%)"),
                                   tk.Label(group5, text="Likelihood of Most Severe (%)")]
        self.mag_range = [tk.Entry(group5, width=int(ENTRY_WIDTH/2), font=SMALL_FONT),
                          tk.Entry(group5, width=int(ENTRY_WIDTH/2), font=SMALL_FONT),
                          tk.Entry(group5, width=int(ENTRY_WIDTH/2), font=SMALL_FONT),
                          tk.Entry(group5, width=int(ENTRY_WIDTH/2), font=SMALL_FONT),
                          tk.Entry(group5, width=int(ENTRY_WIDTH/2), font=SMALL_FONT),
                          tk.Entry(group5, width=int(ENTRY_WIDTH/2), font=SMALL_FONT)]
        self.mag_range[0].grid(row=4, column=1, padx=FIELDX_PADDING, pady=FIELDY_PADDING)

        group6 = ttk.LabelFrame(self, text="Risk Preference")
        group6.grid(row=7, stick="ew", padx=FRAME_PADDING, pady=FRAME_PADDING)
        self.preference = tk.StringVar()
        self.preference.set("none")
        ttk.Label(group6, text="Define Risk Preference",
                  font=SMALL_FONT).grid(row=14, column=0, sticky="e",
                                        padx=FIELDX_PADDING, pady=FIELDY_PADDING)
        self.neutral = ttk.Radiobutton(group6, text="Risk Neutral",
                                       variable=self.preference, value="neutral")
        self.neutral.grid(row=15, column=0, sticky="w", padx=FIELDX_PADDING, pady=FIELDY_PADDING)
        self.averse = ttk.Radiobutton(group6, text="Risk Averse",
                                      variable=self.preference, value="averse")
        self.averse.grid(row=16, column=0, sticky="w", padx=FIELDX_PADDING, pady=FIELDY_PADDING)
        self.accepting = ttk.Radiobutton(group6, text="Risk Accepting",
                                         variable=self.preference, value="accepting")
        self.accepting.grid(row=17, column=0, sticky="w", padx=FIELDX_PADDING, pady=FIELDY_PADDING)

        # ===== Manueverability Buttons
        group7 = ttk.LabelFrame(self)
        group7.grid(row=8, sticky="ew", padx=FRAME_PADDING, pady=FRAME_PADDING)
            # === Places spacing so that buttons are on the bottom right
        ttk.Label(group7, text=" " * 106).grid(row=0, column=1)
        ttk.Button(group7, text="Next>>",
                   command=lambda: self.check_page(controller,
                                                   'CostPage')).grid(row=0, column=7, sticky="se",
                                                                     padx=FIELDX_PADDING,
                                                                     pady=FIELDY_PADDING)

        ttk.Button(group7, text="Menu",
                   command=lambda: self.check_page(controller,
                                                   'DirectoryPage')).grid(row=0, column=3,
                                                                          sticky="se",
                                                                          padx=FIELDX_PADDING,
                                                                          pady=FIELDY_PADDING)