Skip to content

Commit

Permalink
Merge pull request #24 from Myoldmopar/UpdateTkSheet
Browse files Browse the repository at this point in the history
Update tk sheet to 7
  • Loading branch information
Myoldmopar committed Apr 23, 2024
2 parents 519a855 + e83cce8 commit 6795af4
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 226 deletions.
2 changes: 1 addition & 1 deletion energyplus_pet/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
NAME = "energyplus_pet"
NICE_NAME = "EnergyPlus P.E.T."
VERSION = "0.50"
VERSION = "0.60"
7 changes: 5 additions & 2 deletions energyplus_pet/equipment/base.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from abc import abstractmethod
from math import sqrt
from typing import Callable, Dict, List, Tuple

from numpy import sqrt, diag, average
from scipy.optimize import curve_fit

from energyplus_pet.equipment.equip_types import EquipType
Expand Down Expand Up @@ -256,7 +256,10 @@ def do_one_curve_fit(
)
raw_parameters = curve_fit_response[0]
calculated_parameters = list(raw_parameters)
average_err_one_sigma = average(sqrt(diag(curve_fit_response[1])))
diagonal = curve_fit_response[1].diagonal()
square_roots = [sqrt(d) for d in diagonal]
average_err_one_sigma = sum(square_roots) / len(square_roots)
# average_err_one_sigma = average(sqrt(diag(curve_fit_response[1])))
return calculated_parameters, average_err_one_sigma

@staticmethod
Expand Down
274 changes: 108 additions & 166 deletions energyplus_pet/forms/base_data_form.py

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions energyplus_pet/forms/catalog_plot.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from enum import Enum, auto
import numpy as np
from tkinter import Toplevel, Frame # containers
from tkinter import Button, Label # widgets
from tkinter import TOP, X, BOTH, ALL # appearance stuff
Expand Down Expand Up @@ -52,7 +51,7 @@ def __init__(self, parent_window, cdm: CatalogDataManager, eq: BaseEquipment):
plot_notebook.add(plot_frame, text=pd[0])
fig = Figure(figsize=(7, 5))
a = fig.add_subplot(111)
a.plot(np.array(pd[1]), np.array(pd[2]))
a.plot(pd[1], pd[2])
a.set_title("Catalog Data Display", fontsize=16)
a.set_ylabel(f"[{pd[3]}]", fontsize=14)
a.set_xlabel("Catalog Data Points (no order)", fontsize=14)
Expand Down
3 changes: 1 addition & 2 deletions energyplus_pet/forms/comparison_plot.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from enum import auto, Enum

import numpy as np
from tkinter import Frame, Toplevel, TOP, BOTH, Tk, Label, X, Button
from tkinter.ttk import Notebook, Separator

Expand Down Expand Up @@ -61,7 +60,7 @@ def __init__(self, parent_window: Tk, _: CatalogDataManager, equip_instance: Bas
line_arg = '--'
else:
raise EnergyPlusPetException('bad line type')
a.plot(np.array(pd[3]), label=pd[0], linestyle=line_arg, color=pd[2])
a.plot(pd[3], label=pd[0], linestyle=line_arg, color=pd[2])
a.legend()
a.set_title(plot_title, fontsize=16)
a.set_xlabel("Catalog Data Points (no order)")
Expand Down
97 changes: 51 additions & 46 deletions energyplus_pet/forms/correction_detail_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def __init__(self, parent_window, _cf: CorrectionFactor, eq: BaseEquipment, cf_n
elif _cf.correction_type == CorrectionFactorType.Replacement:
Label(self, text=f"""Entering correction data for ~~ {_cf.name} ~~
This correction factor requires {_cf.num_corrections} replacement values for both dry and wet bulb temps.
This correction factor requires {_cf.num_corrections} replacement values for the specified independent variable.
The correction factor requires multiplier values for the following {len(_cf.columns_to_modify)} column(s):
{dep_column_names}""").pack(side=TOP, fill=X, anchor=W, expand=False, padx=p, pady=p)
Expand Down Expand Up @@ -125,23 +125,21 @@ def __init__(self, parent_window, _cf: CorrectionFactor, eq: BaseEquipment, cf_n
column_titles.append(eq.headers().name_array()[mod_column])
num_columns_in_table = len(column_titles)
num_rows_in_table = self.completed_factor.num_corrections # no need to add a header or anything here
pretend_data = []
for row in range(num_rows_in_table):
this_row = []
for col in range(num_columns_in_table):
this_row.append(0.0)
pretend_data.append(this_row)
self._num_bad_cells = 0
self.table = Sheet(self.tabular_frame)
self.table.set_sheet_data(pretend_data)
self.table.headers(column_titles)
self.table = Sheet(
self.tabular_frame,
expand_sheet_if_paste_too_big=False,
startup_select=(1, 1, 1, 1, "cells"),
align="c",
header_align="c",
headers=column_titles,
data=[[0.0 for _ in range(num_columns_in_table)] for _ in range(num_rows_in_table)]
)
self.table.enable_bindings()
self.table.set_options(expand_sheet_if_paste_too_big=False)
self.table.hide(canvas="row_index")
self.table.hide(canvas="top_left")
self.table.set_all_cell_sizes_to_text(redraw=True)
# https://github.com/ragardner/tksheet/blob/master/DOCUMENTATION.md#25-example-custom-right-click-and-text-editor-functionality
self.table.extra_bindings("end_edit_cell", func=self._cell_edited)
self.table.edit_validation(self._cell_edited)
# self.table.extra_bindings([("end_edit_cell", self._cell_edited)])
self.table.extra_bindings("end_paste", func=self._cells_pasted)
self.table.pack(side=TOP, expand=True, fill=BOTH, padx=p, pady=p)
self.table.select_cell(row=0, column=0)
Expand Down Expand Up @@ -173,6 +171,10 @@ def __init__(self, parent_window, _cf: CorrectionFactor, eq: BaseEquipment, cf_n
# set up keybinding and flags
self.bind('<Key>', self._handle_button_pressed)

self.table.focus()
self.table.see()
self.table.redraw()

# finalize UI operations
self.grab_set()
self.transient(parent_window)
Expand All @@ -189,35 +191,38 @@ def _handle_button_pressed(self, event):
self._cells_pasted()

def _cell_edited(self, event):
row = event.row
column = event.column
# first check the current value to see if it was already bad -- it will be the old value in the cell
current_value = self.table.get_cell_data(row, column)
try:
float(current_value)
was_good = True
except ValueError:
was_good = False
try:
float(event.text)
self.table.highlight_cells(row, column, bg='white')
# if it was good already, and good now, we are done
# if it was bad, and now good, decrement the counter
if not was_good:
self._num_bad_cells -= 1
except ValueError:
self.table.highlight_cells(row, column, bg='pink')
# if it was bad already, and bad now, we are done
# if it was good, and now bad, increment the counter
if was_good:
self._num_bad_cells += 1
for (row, column), old_value in event.cells.table.items():
# first check the current value to see if it was already bad -- it will be the old value in the cell
try:
float(old_value)
was_good = True
except ValueError:
was_good = False
try:
float(event.value)
self.table.highlight_cells(row, column, bg='white')
# if it was good already, and good now, we are done
# if it was bad, and now good, decrement the counter
if not was_good:
self._num_bad_cells -= 1
except KeyError:
attrs = ", ".join(event.keys())
print(f"Could not access value attribute on event. Available attributes include: {attrs}")
except ValueError:
self.table.highlight_cells(row, column, bg='pink')
# if it was bad already, and bad now, we are done
# if it was good, and now bad, increment the counter
if was_good:
self._num_bad_cells += 1
self.table.redraw()
return event.value

def _cells_pasted(self, _=None):
self._num_bad_cells = 0
for row in range(self.table.total_rows()):
for column in range(self.table.total_columns()):
try:
float(self.table.get_cell_data(row, column))
float(self.table.data[row][column])
self.table.highlight_cells(row, column, bg='white')
except ValueError:
self._num_bad_cells += 1
Expand All @@ -229,7 +234,7 @@ def _table_data_all_good(self) -> bool:
def any_blank_cells(self):
for row in range(self.table.total_rows()):
for col in range(self.table.total_columns()):
if self.table.get_cell_data(row, col) == '':
if self.table.data[row][col] == '':
return True
return False

Expand Down Expand Up @@ -282,7 +287,7 @@ def _done_or_conform(self):
return
for r in range(self.table.total_rows()):
for c in range(self.table.total_columns()):
value = self.table.get_cell_data(r, c)
value = self.table.data[r][c]
if value == '':
message_window = PetMessageForm(
self,
Expand All @@ -295,23 +300,23 @@ def _done_or_conform(self):
# for regular correction factors, read the first column of data into the base correction of the CF
if self.completed_factor.correction_type != CorrectionFactorType.CombinedDbWb:
self.completed_factor.base_correction = [
float(self.table.get_cell_data(row, 0)) for row in range(self.completed_factor.num_corrections)
float(self.table.data[row][0]) for row in range(self.completed_factor.num_corrections)
]
last_column_read = 0
else: # for db/wb, read the first column into the db array and the second column into the wb array
self.completed_factor.base_correction_db = [
float(self.table.get_cell_data(row, 0)) for row in range(self.completed_factor.num_corrections)
float(self.table.data[row][0]) for row in range(self.completed_factor.num_corrections)
]
self.completed_factor.base_correction_wb = [
float(self.table.get_cell_data(row, 1)) for row in range(self.completed_factor.num_corrections)
float(self.table.data[row][1]) for row in range(self.completed_factor.num_corrections)
]
last_column_read = 1
# then iterate over the mod column ids of the CF and read the data into lists and then into the CF map
for equipment_column_index in self.completed_factor.columns_to_modify:
last_column_read += 1
this_column = []
for row in range(self.table.total_rows()):
this_column.append(float(self.table.get_cell_data(row, last_column_read)))
this_column.append(float(self.table.data[row][last_column_read]))
self.completed_factor.mod_correction_data_column_map[equipment_column_index] = this_column
output_message = ""
db = self.equipment_instance.headers().get_db_column()
Expand Down Expand Up @@ -343,7 +348,7 @@ def conform_units(self):
self.cancel()
return
for r in range(self.table.total_rows()):
cell_value = float(self.table.get_cell_data(r, 0))
cell_value = float(self.table.data[r][0])
unit_value = unit_instance_factory(cell_value, self.replacement_column_unit_type)
unit_value.units = current_db_unit_id
unit_value.convert_to_calculation_unit()
Expand All @@ -359,7 +364,7 @@ def conform_units(self):
self.cancel()
return
for r in range(self.table.total_rows()):
cell_value = float(self.table.get_cell_data(r, 0))
cell_value = float(self.table.data[r][0])
unit_value = unit_instance_factory(cell_value, UnitType.Temperature)
unit_value.units = current_db_unit_id
unit_value.convert_to_calculation_unit()
Expand All @@ -374,7 +379,7 @@ def conform_units(self):
self.cancel()
return
for r in range(self.table.total_rows()):
cell_value = float(self.table.get_cell_data(r, 1))
cell_value = float(self.table.data[r][1])
unit_value = unit_instance_factory(cell_value, UnitType.Temperature)
unit_value.units = current_wb_unit_id
unit_value.convert_to_calculation_unit()
Expand Down
8 changes: 4 additions & 4 deletions energyplus_pet/forms/header_preview.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from tkinter import Toplevel, Button, Frame, Label, HORIZONTAL, TOP, X
from tkinter.ttk import Separator

from pyperclip import copy

from energyplus_pet.equipment.base import BaseEquipment


Expand Down Expand Up @@ -47,10 +45,12 @@ def __init__(self, parent_window, equipment: BaseEquipment):
self.transient(parent_window)

def _copy(self):
copy(self._summary)
self.clipboard_clear()
self.clipboard_append(self._summary)

def _copy_csv(self):
copy(self._csv)
self.clipboard_clear()
self.clipboard_append(self._csv)

def _done(self):
self.grab_release()
Expand Down
5 changes: 2 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@
# so here we are with matplotlib. And once we have matplotlib, we already get numpy, so there's no reason to not
# use numpy for arrays. If I can ever find a really lightweight plot libraries, I'll try to remove matplotlib and numpy
matplotlib
numpy
scipy
pyperclip
tksheet
tksheet==7.1.8
pillow>=8.0.0

# for building documentation
Expand All @@ -19,6 +17,7 @@ sphinx_rtd_theme
nose
coverage
coveralls # really just for github, but it's fine
flake8

# for building wheels, mostly from github, but it's fine
wheel
Expand Down

0 comments on commit 6795af4

Please sign in to comment.