def __init__(self, db, top_set, e1rm, date, lift, fatigue, cur_workout): super().__init__() self.drop_sets = pd.DataFrame() self._db = db self._top_set = top_set self._e1rm = e1rm self._lift = lift self._date = date self._fatigue = fatigue self._fatigue_e1rm = e1rm * (1 - (self._fatigue / 100.0)) self._drop_reps = None self._drop_rpe = None self._drop_weight = None self._num_drop_sets = 3 self._cur_drop_type = DropTypes.Drop self._cur_workout = cur_workout self._rpe_table_model = RpeTableModel(self._db, self._fatigue_e1rm) self._stats_table_model = StatsTableModel(self._db)
class DialogDrop(Ui_dialog_drop): values_changed = Signal() def __init__(self, db, top_set, e1rm, date, lift, fatigue, cur_workout): super().__init__() self.drop_sets = pd.DataFrame() self._db = db self._top_set = top_set self._e1rm = e1rm self._lift = lift self._date = date self._fatigue = fatigue self._fatigue_e1rm = e1rm * (1 - (self._fatigue / 100.0)) self._drop_reps = None self._drop_rpe = None self._drop_weight = None self._num_drop_sets = 3 self._cur_drop_type = DropTypes.Drop self._cur_workout = cur_workout self._rpe_table_model = RpeTableModel(self._db, self._fatigue_e1rm) self._stats_table_model = StatsTableModel(self._db) def setupUi(self, dialog_drop): super().setupUi(dialog_drop) self.drop_type.addItems([dt.name for dt in DropTypes]) self.rpe_table.setModel(self._rpe_table_model) self.stats_table.setModel(self._stats_table_model) self.top_set.setText(analysis.set_to_str(self.top_set)) self.connect_signals() def connect_signals(self): self.drop_type.currentTextChanged.connect(self._drop_type_changed) self.fatigue_spin.valueChanged.connect(self._fatigue_changed) self.num_sets.valueChanged.connect(self._num_drop_sets_changed) self.rpe_table.clicked.connect(self._drop_set_selected) self.values_changed.connect(self._update_values) self.values_changed.connect(self._update_rpe_table) self.values_changed.connect(self._update_stats_table) self.values_changed.connect(self._update_sets_list) @pyqtSlot() def _update_values(self): self._fatigue_e1rm = self._e1rm * (1 - (self._fatigue/100.0)) if self._drop_reps and self._drop_rpe: self._drop_weight = self._fatigue_e1rm * analysis.rpe_table.ix[self._drop_reps, self._drop_rpe] self.drop_sets = self._make_sets() @pyqtSlot() def _update_sets_list(self): self.drop_sets_list.clear() if not self.drop_sets.empty: for row in self.drop_sets.itertuples(index=False): set_str = '{}x{}'.format(row.Weight, row.Reps) if pd.notnull(row.RPE): set_str += '@{}'.format(row.RPE) self.drop_sets_list.addItem(set_str) @pyqtSlot() def _update_stats_table(self): updated_workout = self._cur_workout.append(self.drop_sets) self._stats_table_model.update(cur_workout=updated_workout, cur_lift=self._lift) @pyqtSlot() def _update_rpe_table(self): self._rpe_table_model.update(self._fatigue_e1rm, self._cur_drop_type) @pyqtSlot() def _drop_set_selected(self, index): if not index.isValid(): return try: drop_set_str = index.data().split('(')[0].strip() self.drop_set.setText(drop_set_str) parser = re.match(r'(\d+)x(\d+)@(\d+\.\d+)', drop_set_str) self._drop_weight, self._drop_reps, self._drop_rpe = parser.groups() self._drop_weight = int(self._drop_weight) self._drop_reps = int(self._drop_reps) self._drop_rpe = round(float(self._drop_rpe) * 2.0) / 2.0 self.values_changed.emit() except (ValueError, TypeError) as err: log_err(err, "Couldn't parse drop_set from RPE table: {}".format(drop_set_str)) @pyqtSlot(int) def _num_drop_sets_changed(self, num): if num and num > 0: self._num_drop_sets = num self.values_changed.emit() @pyqtSlot() def _drop_type_changed(self): new_drop_type = self.drop_type.currentText().lower() if new_drop_type == self._cur_drop_type.value: return False else: if new_drop_type == DropTypes.Drop.value: self._cur_drop_type = DropTypes.Drop elif new_drop_type == DropTypes.Repeat.value: self._cur_drop_type = DropTypes.Repeat elif new_drop_type == DropTypes.Manual.value: self._cur_drop_type = DropTypes.Manual self.values_changed.emit() return True @pyqtSlot(int) def _fatigue_changed(self, new_fatigue=None): if not new_fatigue: new_fatigue = self.fatigue_spin.value() if new_fatigue and new_fatigue > 0: if new_fatigue == self._fatigue: return else: self._fatigue = new_fatigue self.values_changed.emit() def _make_sets(self): if self._cur_drop_type == DropTypes.Drop: drop_sets = self._make_sets_drop() elif self._cur_drop_type == DropTypes.Repeat: drop_sets = self._make_sets_repeat() elif self._cur_drop_type == DropTypes.Manual: drop_sets = self._make_sets_manual() else: drop_sets = pd.DataFrame() return drop_sets def _make_sets_drop(self): if not self._drop_weight and self._drop_reps and self._num_drop_sets and self._drop_rpe: return pd.DataFrame() sets_str = '{}x{}x{}@{}'.format(self._drop_weight, self._drop_reps, self._num_drop_sets, self._drop_rpe) sets_tup = analysis.parse_sets(sets_str, self._e1rm) return self._db.make_workout(self._lift, sets_tup, self._date) def _make_sets_repeat(self): if not self._drop_reps and self._drop_rpe and self._fatigue: return pd.DataFrame() start_rpe = analysis.rpe_table.ix[self._drop_reps, self._drop_rpe] desired_end_rpe = start_rpe + (self._fatigue / 100.0) if desired_end_rpe > analysis.rpe_table.ix[self._drop_reps].max(): log_warn('Cannot achieve desired fatigue with given starting set') end_rpe_idx = np.argmin(np.abs(desired_end_rpe - analysis.rpe_table.ix[self._drop_reps])) end_rpe = analysis.rpe_table.ix[self._drop_reps, end_rpe_idx] sets_str = '{}x{}x{}@{}'.format(self._drop_weight, self._drop_reps, self._num_drop_sets, end_rpe) sets_tup = analysis.parse_sets(sets_str, self._e1rm) return self._db.make_workout(self._lift, sets_tup, self._date) def _make_sets_manual(self): sets_str = self.drop_set.text() sets_tup = analysis.parse_sets(sets_str, self._e1rm) return self._db.make_workout(self._lift, sets_tup, self._date)