Python: Biorhythm Implementation
June 26, 2019 | Python | 2 Comments
1 Background and Introduction
Sigmund Freud and Wilhelm Fliess, in late 1800 were working on a research to emphasis that mental and physical fitness has a distinguishable pattern. As a result of that, they could came up with a conclusion that human life has two cycle in their lives, 23 days and 28 days, where 23 days cycle is subjected men and 28 days cycle is subjected to women.
Followed by these findings and additional researches which conducted by scientist later on, it was happened to found that human physical strength and well-being seems to showing 23 days cycle, emotional potentials showing 28 days cycle and intellectual well-being showing 33 days cycle.
Theses patterns could demonstrate by sin or cosine function.

t=Number days count from the birth
Physical (Py) =

Emotional (Ey) =

Intellectual (Iy) =

Though in 80’s Biorhythms were so much popular, later on, most of the studies showed that this concept is not valid. Either way to overcome the negative potentials, self-confident is the key.

2 Classes and Functions
In this section, shall we discuss the class and function on our sample code.
2.1 Biorhythm
Main purposes of this class is to facilitate users to create the Biorhythm objects and using these objects derive the data sets to draw the Biorhythm graph in three major aspect. Further in class constuctor there are two default values are defined for user’s convenience.
2.1.1 dateReformat
As the default date format, within this class, it has used “DD/MM/YYYY”. Either user’s input or system derived dates should be stored and used in a standardize format. This function cast/convert and return date string to date object which ought to be used in other functions.
2.1.2 countDates
By providing two argument (Date one, Date two), calling party can derive how many days are there in between mentioned dates.
2.1.3 physicalRhythm

The function to calculate physical well being functional data set. This function use following algorithm to calculate the dataset for physical well-being.
Further this will return a python dictionary, particular date as the key and the well being ratio as the value.
2.1.4 intellectualRhythm
The function to calculate intellectual well being functional data set. This function use following algorithm to calculate the dataset for intellectual well-being.

Further this will return a python dictionary, particular date as the key and the well being ratio as the value.
2.1.5 emotionalRhythm
The function to calculate emotional well being functional data set. This function use following algorithm to calculate the dataset for emotional well-being.

Further this will return a python dictionary, particular date as the key and the well being ratio as the value.
2.1.6 compositRhythm
Based on above three major calculation this function calculate the mean value for given date and return as a python dictionary.
Since this function is not a major priority, if any error occurs when processing the composite dataset, these errors will be discarded. Further, to use this function all the other data sets should be created prematurely.
2.2 Plots
This class is to create a multiple line plot by using any number of data sets provided. This class has only one constructor. As the first argument, user can pass, general data related to the graph using python dictionary.
<Variable Name >={‘title’: “<Title of the graph>” #Mandatory
,’axis_X’: “<Description for X axis” #Mandatory
,’axis_Y’: “<Description for Y axis” #Mandatory
,’figSize’:[<Length: Horizontal>,<Length: Vatical>] #Optional
,‘grid’:<Show grid in the graph True/False> #Optional
,’toggleAxis’:<Change X and Y axis True/False> #Optional
}

As the last argument (non-keyworded variable length argument), the constructor accepts, any number datasets (as python dictionaries) to create the graph.
<Variable Name>= {‘<Name of the Line graph 1>’: {‘axis_X’:<Data set for X axis>, ‘axis_Y’:<Data set for Y axis>},
.
.
‘<Name of the Line graph n>‘: {‘axis_X’:<Data set for X axis>, ‘axis_Y’:<Data set for Y axis>}, ….}

2.3 Runner Program
This program integrates above two class to draw the biorhythm plot. In case of a interactive user input, it is required to uncomment line number 11 to 15 and comment line 18 and 19.
3 pseudo codes
3.1 biorhythm
Start
Get date of birth
Get targeted date
Get date count (from the target date)
Covert Date string to Date Object
PHYSICAL
From “target date” to “target date + date count”
Calculate Physical well-being ratio
sin(2πt/23)
Return Data dictionary [Key=> date,Value=>ratio]
INTELLECTUAL
From “target date” to “target date + date count”
Calculate Intellectual well-being ratio
sin(2πt/28)
Return Data dictionary [Key=> date,Value=>ratio]
EMOTIONAL
From “target date” to “target date + date count”
Calculate Emotional well-being ratio
sin(2πt/33)
Return Data dictionary [Key=> date,Value=>ratio]
COMPOSITE
Until last element of physical well-being Data set
Calculate the mean values for similar indexes; Physical, Emotional, Intellectual data sets
Store and return a Data Dictionary [Key=> date, Value=>relevant mean value]
Exit
3.2 Plots
Start
Get general details of the graph
Get datasets
Until last dataset read all the datasets
If toggle flag is flagged
Until last dataset read all the datasets
Store values for X axis
Store values for Y axis
Toggle X and Y axis
Rotate X axis label for 60 degree
If toggle flag is not flagged
Until last dataset read all the datasets
Store values for X axis
Store values for Y axis
If grid flag is flagged
Show grids on the plot
If custom figure size is provided
Set dimension of the plot
Set the title
Set the legends
Draw the plot
Exit
3.3 Execution (Runner)
Start
Provide User name
Create Biorhythm object [birthday, target date, date count]
Set and configure graph properties => Dataset #1
Configure data sets => Dataset #2
Create Plot object using Dataset #1 and #2
Exit
4 bio.py
# -*- coding: utf-8 -*-
#import datetime
import math
from datetime import date
import datetime
import statistics
import sys
class Biorhythm:
def __init__(self,birthday,startDate=str(datetime.date.today().strftime('%d/%m/%Y')),length=30):
self.emotional = {} # emotional well-being list
self.intellectual = {} # intellectual well-being list
self.composit = {}
self.physical = {}
self.startDate=startDate
self.birthday=birthday
self.length=length
def dateReformat(self,dateStr): #Covert to system redable date format
try:
reformatedDate = datetime.datetime.strptime(dateStr,'%d/%m/%Y') # convert to format datetime.date(year, month, day)
return reformatedDate.date()
except:
sys.exit("Please insert a valid date[DD/MM/YYYY]")
def countDates(self,firstDate,lastDate):
try:
splitedFirstDate=firstDate.split('/')
splitedLastDate=lastDate.split('/')
return (date(int(splitedFirstDate[2]),int(splitedFirstDate[1]),int(splitedFirstDate[0]))-date(int(splitedLastDate[2]),int(splitedLastDate[1]),int(splitedLastDate[0]))).days
except:
sys.exit("Something went wrong when couting the dates.")
def physicalRhythm(self):
date=self.dateReformat(self.startDate) - datetime.timedelta(days=4)
try:
for datePointer in range(int(self.countDates(self.birthday,self.startDate))-4,self.countDates(self.birthday,self.startDate)+self.length):
# self.physical[date.strftime('%d/%m/%Y-%a')] = math.sin(2*math.pi*datePointer/23)
self.physical[date] = math.sin(2*math.pi*datePointer/23)
date += datetime.timedelta(days=1)
return self.physical
except:
sys.exit("Something went wrong! Please insert valid data followed by the format.")
def intellectualRhythm(self):
date=self.dateReformat(self.startDate) - datetime.timedelta(days=4)
try:
for datePointer in range(int(self.countDates(self.birthday,self.startDate))-4,self.countDates(self.birthday,self.startDate)+self.length):
# self.intellectual[date.strftime('%d/%m/%Y-%a')]=math.sin(2*math.pi*datePointer/28)
self.intellectual[date]=math.sin(2*math.pi*datePointer/28)
date += datetime.timedelta(days=1)
return self.intellectual
except:
sys.exit("Something went wrong! Please insert valid data followed by the format.")
def emotionalRhythm(self):
date=self.dateReformat(self.startDate) - datetime.timedelta(days=4)
try:
for datePointer in range(int(self.countDates(self.birthday,self.startDate))-4,self.countDates(self.birthday,self.startDate)+self.length):
# self.emotional[date.strftime('%d/%m/%Y-%a')]=math.sin(2*math.pi*datePointer/33)
self.emotional[date]=math.sin(2*math.pi*datePointer/33)
date += datetime.timedelta(days=1)
return self.emotional
except:
sys.exit("Something went wrong! Please insert valid data followed by the format.")
def compositRhythm(self):
try:
for physicalElement_key,physicalElement_value in self.physical.items():
tmpList=[physicalElement_value,self.intellectual[physicalElement_key],self.emotional[physicalElement_key]]
self.composit[physicalElement_key]=statistics.mean(tmpList)
tmpList.clear()
return self.composit
except:
pass
5 plots.py
from tqdm import tqdm
#from matplotlib.pyplot import figure
import matplotlib.pyplot as plt
class Plots:
def __init__(self,plotDisc,*args):
if ('toggleAxis' in plotDisc.keys() and plotDisc['toggleAxis']):
plt.xlabel(plotDisc['axis_Y'])
plt.ylabel(plotDisc['axis_X'])
for dataSet in tqdm(args):
for key, val in dataSet.items():
plt.plot(val['axis_Y'], val['axis_X'], label = key)
plt.xticks(rotation=60)
else:
plt.xlabel(plotDisc['axis_X'])
plt.ylabel(plotDisc['axis_Y'])
for dataSet in tqdm(args):
for key, val in dataSet.items():
plt.plot(val['axis_X'], val['axis_Y'], label = key)
#Show/Hide Grid
if ('grid' in plotDisc.keys() and plotDisc['grid']):
plt.grid('on')
#Set Plot size
if ('figSize' in plotDisc.keys()):
plt.rcParams["figure.figsize"] = plotDisc['figSize']
#Hide Axis
if ('hideAxis_X' in plotDisc.keys() and plotDisc['hideAxis_X']):
frame = plt.gca()
frame.axes.get_xaxis().set_ticks([])
if ('hideAxis_Y' in plotDisc.keys() and plotDisc['hideAxis_Y']):
frame = plt.gca()
frame.axes.get_yaxis().set_ticks([])
#Set Plot title and Legend
plt.title(plotDisc['title'])
plt.legend()
#Set tick Limit
if ('tickLimit_X' in plotDisc.keys()):
plt.locator_params(nbins=plotDisc['tickLimit_X'],axis='x')
if ('tickLimit_Y' in plotDisc.keys()):
plt.locator_params(nbins=plotDisc['tickLimit_Y'],axis='y')
#Draw plot
plt.show()
6 runner.py
from plots import Plots
from bio import Biorhythm
bio=Biorhythm("10/2/1993" #Mandatory
,"1/8/1990" #Optional
,100 #Optional
)
user="binbash"
#Data set to make the graph
dataSet = {'physical': {'axis_X':list(bio.physicalRhythm().values()), 'axis_Y':list(bio.physicalRhythm().keys())}
,'emotional': {'axis_X':list(bio.emotionalRhythm().values()), 'axis_Y':list(bio.emotionalRhythm().keys())}
,'intellectual': {'axis_X':list(bio.intellectualRhythm().values()), 'axis_Y':list(bio.intellectualRhythm().keys())}
,'composit': {'axis_X':list(bio.compositRhythm().values()), 'axis_Y':list(bio.compositRhythm().keys())}
}
#Change properties of the graph
plotDisc={'title':'{}\'s-Biorhythm'.format(user) #Mandatary
,'axis_X':'Well-Being' #Mandatary
,'axis_Y':'Date' #Mandatary
,'figSize':[20,5] #Optional
,'grid':True #Optional
,'toggleAxis':True #Optional
,'hideAxis_X':False #Optional
,'hideAxis_Y':False #Optional
# ,'tickLimit_X':1 #Optional
# ,'tickLimit_Y':8 #Optional
}
plts=Plots(plotDisc,dataSet)
7 Reference
3.7.3 Documentation. (2019). Retrieved from https://docs.python.org/3/
Hunter, J., Dale, D., Droettboom, M., & Firing, E. (2019). matplotlib.pyplot.show — Matplotlib 3.1.0 documentation. Retrieved from https://matplotlib.org/api/_as_gen/matplotlib.pyplot.show.html
Zundel, J. (2019). Biorhythms: Definition, History & Calculation | Study.com. Retrieved from https://study.com/academy/lesson/biorhythms-definition-history-calculation.html
Biorhythm, Classes, Dataset, math, matplotlib.pyplot, OOP, Plots, Programming, Python, tqdm
2 Comments
GreggInfok
Хорошая статья
Jamessnano
You’re a very helpful web site; couldn’t make it without ya!