From 6a74c5b65f8b258257bc348f923c336f76ddff45 Mon Sep 17 00:00:00 2001 From: v13 Date: Fri, 13 Aug 2010 09:49:22 +0000 Subject: [PATCH] Use a larger size hint for main widget. Allow for configurable menstruation duration and ovulation day. Provide configuration options for those parameters. Improve help to describe those options. --- trunk/setup.py | 2 +- trunk/src/algo.py | 72 ++++++++++++++++++++++++++++++++++++--------------- trunk/src/config.py | 36 ++++++++++++++++---------- trunk/src/graph.py | 2 +- trunk/src/win.py | 51 ++++++++++++++++++++++++++++-------- 5 files changed, 115 insertions(+), 48 deletions(-) diff --git a/trunk/setup.py b/trunk/setup.py index a42ceb1..b42984c 100755 --- a/trunk/setup.py +++ b/trunk/setup.py @@ -26,7 +26,7 @@ i18n_qm_files=["i18n/maegirls_el.qm"] setup( name='maegirls', - version='1.2', + version='1.3', description="MaeGirls", author="Stefanos Harhalakis", author_email="v13@v13.gr", diff --git a/trunk/src/algo.py b/trunk/src/algo.py index 06209bd..3078483 100755 --- a/trunk/src/algo.py +++ b/trunk/src/algo.py @@ -24,33 +24,56 @@ __version__ = "$Id: 0.py 2265 2010-02-21 19:16:26Z v13 $" import time +def today(): + t=time.time() - time.timezone + day=int(t/86400) + + return(day) + +# Defaults for a girl +defaults={ + 'cycle': 28, # Cycle length + 'menstr': 5, # Duration of menstruation + 'ovday': -14, # When ovulation happens. Positive: This number + # of days after the start of the cycle. + # Negative: This number of days before the end + # of the cycle. + 'day0': today() + } + class Algo(object): def __init__(self): t=today() - self.setReference(t, 28) + self.setReference(t, defaults) # set day "day" as the reference day of starting period cycle # day is int(time.time()/86400) # cycle is the cycle width in days, starting from 0 - def setReference(self, day, cycle): + def setReference(self, day, cfg): + self.cfg=cfg self.refday=day - self.cycle=cycle # Convert an arbitary day to a day in cycle def dayInCycle(self, day): - d=(day-self.refday) % self.cycle + d=(day-self.refday) % self.cfg['cycle'] if d<0: - d+=self.cycle + d+=self.cycleLength() return(d) def cycleLength(self): - return(self.cycle) + return(self.cfg['cycle']) def currentDayInCycle(self): d=today() return(self.dayInCycle(d)) + def menstruationDuration(self): + return(self.cfg['menstr']) + + def ovulationDay(self): + return(self.cfg['ovday']) + # Return: # ret={ # 'status': ['ok', 'red'] @@ -63,28 +86,41 @@ class Algo(object): def status(self, day): d=self.dayInCycle(day) - ovbefore=14 + cycle=self.cycleLength() - if d<5: + #ovbefore=14 + ovday=self.ovulationDay() + if ovday>0: + ovstart=ovday-3 + ovmid=ovday + ovend=ovday+1 + else: + ovstart=cycle+ovday-3 + ovmid=cycle+ovday + ovend=cycle+ovday+1 + + menstr=self.menstruationDuration() + + if d=self.cycle-7: + elif d>=cycle-7: ret={ 'status': 'blue', - 'day': 7+d-self.cycle, + 'day': 7+d-cycle, 'len': 7, } - elif d>self.cycle-ovbefore-4 and d<=self.cycle-ovbefore: + elif d>=ovstart and d<=ovmid: ret={ 'status': 'green', - 'day': d-self.cycle+ovbefore+3, + 'day': d-ovstart, 'len': 4, } - elif d>self.cycle-16 and d<=self.cycle-ovbefore+1: + elif d>ovmid and d<=ovend: ret={ 'status': 'green', 'day': 2, @@ -94,17 +130,11 @@ class Algo(object): ret={ 'status': 'ok', 'day': d, - 'len': self.cycle + 'len': cycle } return(ret) -def today(): - t=time.time() - time.timezone - day=int(t/86400) - - return(day) - # vim: set ts=8 sts=4 sw=4 noet formatoptions=r ai nocindent: diff --git a/trunk/src/config.py b/trunk/src/config.py index ca82155..725f44e 100755 --- a/trunk/src/config.py +++ b/trunk/src/config.py @@ -28,7 +28,7 @@ import pickle import time import algo -version="1.2" +version="1.3" try: home=os.environ['HOME'] @@ -37,27 +37,34 @@ except: fn="%s/.maegirls" % (home, ) -# Defaults for a girl -defaults={ - 'cycle': 28, - 'day0': algo.today(), - } - # Default config defaultcfg={ - 'ver': 1, # Configuration version + 'ver': 2, # Configuration version 'girls': { # List of configured girls - 'default': defaults + 'default': algo.defaults }, 'cur': "default", # Current girl } +def upgradeConfig(cfg): + """ Upgrade the loaded config to the latest version """ + + if cfg['ver']==1: + cfg['ver']=2 + for i in cfg['girls']: + girl=cfg['girls'][i] + girl['menstr']=algo.defaults['menstr'] + girl['ovday']=algo.defaults['ovday'] + + return(cfg) + def loadConfig(): try: f=file(fn, "r") st=f.read() f.close() ret=pickle.loads(st) + ret=upgradeConfig(ret) except: ret={} @@ -66,6 +73,7 @@ def loadConfig(): return(ret) def sanitize_before_store(cfg0): + """ Ensure that Qt strings (keys) are converted to standard strings """ cfg={ 'ver': cfg0['ver'], 'cur': str(cfg0['cur']), @@ -79,7 +87,7 @@ def sanitize_before_store(cfg0): return(cfg) def storeConfig(cfg0): - cfg0['ver']=1 + cfg0['ver']=2 cfg=sanitize_before_store(cfg0) # print "store:", cfg st=pickle.dumps(cfg) @@ -99,14 +107,14 @@ def storeGirl(name, dt): cfg['girls'][name]={ 'cycle': dt['cycle'], 'day0': dt['day0'], + 'ovday': dt['ovday'], + 'menstr': dt['menstr'], } storeConfig(cfg) def newGirl(name): - global defaults - - storeGirl(name, defaults) + storeGirl(name, algo.defaults) def loadGirls(): cfg=loadConfig() @@ -122,7 +130,7 @@ def loadGirl(name): if all.has_key(name): ret=all[name] else: - ret=defaults + ret=algo.defaults return(ret) diff --git a/trunk/src/graph.py b/trunk/src/graph.py index b476513..23d55c1 100755 --- a/trunk/src/graph.py +++ b/trunk/src/graph.py @@ -278,7 +278,7 @@ class DaysGraph(QWidget): self.last_y=pos.y() def sizeHint(self): - return(QSize(100,50)) + return(QSize(400,200)) # vim: set ts=8 sts=4 sw=4 noet formatoptions=r ai nocindent: diff --git a/trunk/src/win.py b/trunk/src/win.py index dd1521c..2837fd6 100755 --- a/trunk/src/win.py +++ b/trunk/src/win.py @@ -43,10 +43,18 @@ class ConfigDialog(QDialog): self.editName=QLineEdit(self) self.editCycle=QSpinBox(self) self.editCurrent=QSpinBox(self) + self.editMenstr=QSpinBox(self) + self.editOvday=QSpinBox(self) + self.editCycle.setRange(10,50) self.editCurrent.setRange(1,50) + self.editMenstr.setRange(3,7) + self.editOvday.setRange(-30,+30) + self.editCurrent.setWrapping(True) self.editCycle.setSuffix(self.tr(" days")) + self.editMenstr.setSuffix(self.tr(' days')) + self.editOvday.setSuffix(self.tr(' days')) self.editCycle.valueChanged.connect(self.slotEditCycleChanged) @@ -56,6 +64,8 @@ class ConfigDialog(QDialog): l1.addRow(self.tr("Name:"), self.editName) l1.addRow(self.tr("Cycle length:"), self.editCycle) l1.addRow(self.tr("Current day in cycle:"), self.editCurrent) + l1.addRow(self.tr("Duration of menstruation:"), self.editMenstr) + l1.addRow(self.tr("Ovulation day:"), self.editOvday) self.l0.addLayout(l1) @@ -79,6 +89,8 @@ class ConfigDialog(QDialog): self.name=str(self.editName.text()) self.cycle=self.editCycle.value() self.current=self.editCurrent.value()-1 + self.menstr=self.editMenstr.value() + self.ovday=self.editOvday.value() self.accept() @@ -91,6 +103,8 @@ class ConfigDialog(QDialog): self.editName.setText(dt['name']) self.editCycle.setValue(dt['cycle']) self.editCurrent.setValue(dt['day0']+1) + self.editMenstr.setValue(dt['menstr']) + self.editOvday.setValue(dt['ovday']) class MyMsgDialog(QDialog): """ @@ -200,27 +214,37 @@ class HelpDialog(MyMsgDialog): txt=self.tr("""

MaeGirls shows information about women's cycle using some generic -guidelines: It assumes that ovulation happens 14 days before the start -of the next period and that the period cycle is constant. Also, it assumes -that sperm can live for 4 days, while an egg can live for 2 days. +guidelines: By default it assumes that ovulation happens 14 days before the +start of the next period and that the period cycle is constant. Also, it +assumes that sperm can live for 4 days, while an egg can live for 2 days. + +

Using the configure menu you can change the duration of the cycle, +the duration of the menstruation and the day the ovulation happens. When +specifying the ovulation you can use negative numbers to indicate the number +of days before the end of the period, or positive numbers to indicate the +number of days after the beginning of the period. Default value for ovulation +is -14. + +

MaeGirls supports tracking of multiple women. While there have been a lot +of negative comments for this option, I find it useful even for women. +Please don't complain or give negative feedback for an option that you're not +forced to use.

-WARNING!!! This is not always correct. There are FAR TOO MANY exceptions -to the above rules!!! You MUST consult a doctor in order to get accurate -predictions!!! +WARNING!!! The prediction is not always correct. There are FAR TOO MANY +exceptions to the above rules!!! You MUST consult a doctor in order to get +accurate predictions!!! Use the program at your own risk!!!

Assuming that you understand the risks of blindly trusting this program, you become entitled to read the graph as follows:

In red: The days that menstruation -happens, assumed to last 5 days. +happens. Default: 5 days.

In green: The fertile days as described above.

In blue: The days of PMS (Premenstrual Syndrome), assumed to last 7 days.

Navigation is easy: Use left-right finger movement to move the calendar view. Use up-down finger movement to zoom in/out. - -

This program supports the "monitoring" of the cycle of multiple girls/women. """) self.setWindowTitle(self.tr("Help")) @@ -378,7 +402,8 @@ class MaeGirls(QMainWindow): def setGirl(self, name): cfg=config.loadGirl(name) self.girl=name - self.algo.setReference(cfg['day0'], cfg['cycle']) + #self.algo.setReference(cfg['day0'], cfg['cycle']) + self.algo.setReference(cfg['day0'], cfg) self.update() self.updateTitle() @@ -389,7 +414,9 @@ class MaeGirls(QMainWindow): dt={ 'name': self.girl, 'cycle': self.algo.cycleLength(), - 'day0': self.algo.currentDayInCycle() + 'day0': self.algo.currentDayInCycle(), + 'menstr': self.algo.menstruationDuration(), + 'ovday': self.algo.ovulationDay() } self.dlgConfig.initValues(dt) @@ -405,6 +432,8 @@ class MaeGirls(QMainWindow): dt={ 'cycle': self.dlgConfig.cycle, 'day0': day0, + 'ovday': self.dlgConfig.ovday, + 'menstr': self.dlgConfig.menstr, } config.storeGirl(name, dt) -- 1.7.9.5