Sleepcalc a sleep calculator

GS (20170605) Sleepcalc finds the right times to go to sleep or to wake up according sleep cycles and these informations :

  • It takes the average human about 15 minutes to fall asleep
  • A good night's sleep consists of 5-6 complete sleep cycles (or a 4-5 sleep cycles with a 90-minutes nap)
  • If you wake up in the middle of a sleep cycle you will feel tired and groggy
  • If you wake up at one of these times, you will be fit and cheerful

sleepcal-img


Jeff Smith 2019-04-23 : Below is an online demo using CloudTk

# sleepcalc.tcl
# Author:      Gerard Sookahet
# Date:        04 June 2017
# Version:     0.1
# Description: Find the right times to go to sleep or to wake up according sleep cycles
# References: http://www.glenrhodes.com/132/
#             http://sleepyti.me/

bind all <Escape> {exit}

option add *Button.relief flat
option add *Button.foreground white
option add *Button.background blue
option add *Button.width 14
option add *Label.foreground lightblue
option add *Label.background black
option add *Label.width 16
option add *Entry.relief flat
option add *Entry.background lightblue
option add *Entry.width 2
option add *Text.foreground lightgreen
option add *Text.background black

proc Init { t } {
    global lh1 lm1 lh2 lm2
    global tcycle mincycle maxcycle ttosleep

 set lh1 0
 set lm1 00
 set lh2 [string trimleft [clock format [clock seconds] -format %H] 0]
 set lm2 [clock format [clock seconds] -format %M]

 set tcycle 90 ;   # minutes per sleep cycle
 set mincycle 4 ;  # minimum number of sleep cycles
 set maxcycle 8 ;  # maximum number of sleep cycles
 set ttosleep 15 ; # minutes to fall asleep

 $t delete 1.0 end
}

proc BedWaketimes {n bwtime} {
 set times [list]
 for {set cycle $::mincycle} {$cycle <= $::maxcycle} {incr cycle} {
    set sleep_duration [expr {$::ttosleep + $cycle*$::tcycle}]
    set t [clock format [clock add $bwtime [expr {$n*$sleep_duration - 60}] minutes] -format %H:%M]
    lappend times $t $cycle $sleep_duration
    puts "BWTIMES: $times"
 }
 return $times
}

proc DisplayInfo {t s times} {
 if {$s eq "wake"} then {
   set times [lsort -stride 3 -index 2 -decreasing $times]
   $t insert end "\n\u263c To wake up at "
   $t insert end [append a $::lh1 : $::lm1] highlight1
   $t insert end "\nYou should try to fall asleep at one of the following times:\n"
 } else {
   $t insert end "\n\u263e If you go to sleep at "
   $t insert end [append a $::lh2 : $::lm2] highlight1
   $t insert end "\nYou should try to wake up at one of the following times:\n"
 }
 foreach {h c d} $times {
        set d1 [clock format [expr {$d*60}] -format "%Hh%Mmn" -gmt 1]
        $t insert end "$h " highlight1
        $t insert end "with $c cycles " highlight2
        $t insert end "for $d1\n" highlight1
 }
 $t see end
}

proc hm2s {h m} { expr {$h*3600 + $m*60} }

proc About {} {
 set w .about
 catch {destroy $w}
 toplevel $w
 .about configure -bg black
 wm title $w "About Sleepcalc"
 set txt "Sleepcalc - (v0.1 - June 2017) - Gerard Sookahet\n
Sleepcalc finds the right times to go to sleep or to wake up according sleep cycles and  these informations :\n
- It takes the average human about 15 minutes to fall asleep\n
- A good night's sleep consists of 5-6 complete sleep cycles (or a 4-5 sleep cycles with a 90-minutes nap)\n
- If you wake up in the middle of a sleep cycle you will feel tired and groggy\n
- If you wake up at one of these times, you will be fit and cheerful\n\n
 \u2605 \u2605 Sweet dreams \u2605 \u2605"

 message $w.msg -justify left -aspect 250 -relief flat -bg black -fg lightblue -text $txt
 button $w.bquit -text " OK " -command {destroy .about}
 pack $w.msg $w.bquit
}

wm geometry . +100+1
. configure -bg black
wm title . "Sleepcalc"

set lh {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24}
set lm {00 05 10 15 20 25 30 35 40 45 50 55}

set f1 [frame .f1 -relief flat -bg black]
set f2 [frame .f2 -relief flat -bg black]
set f3 [frame .f3 -relief flat -bg black]
set f4 [frame .f4 -relief flat -bg black]
set f5 [frame .f5 -relief flat -bg black]
pack $f1 $f2 $f3 $f4 $f5 -pady 2

label $f1.l -text "To wake up at "
ttk::combobox $f1.cbh -values $lh -width 3 -textvariable lh1
ttk::combobox $f1.cbm -values $lm -width 3 -textvariable lm1
button $f1.b -text Calculate -command {DisplayInfo $::t wake [BedWaketimes -1 [hm2s $::lh1 $::lm1]]}
pack {*}[winfo children $f1] -side left -padx 2

label $f2.l -text "If you go to sleep at "
ttk::combobox $f2.cbh -values $lh -width 3 -textvariable lh2
ttk::combobox $f2.cbm -values $lm -width 3 -textvariable lm2
button $f2.b -text Calculate -command {DisplayInfo $::t bed [BedWaketimes 1 [hm2s $::lh2 $::lm2]]}
pack {*}[winfo children $f2] -side left -padx 2

set t [text $f3.t -width 50 -height 12 -bg darkblue -wrap word -yscrollcommand "$f3.sb set"]
$t tag configure highlight1 -background orange -foreground blue -font consolas
$t tag configure highlight2 -background coral -foreground blue -font consolas
scrollbar $f3.sb -bg blue -command "$f3.t yview"

pack $f3.sb -side right -fill y
pack $t -expand yes -fill both

label $f4.l1 -text "Cycle duration (min)"
entry $f4.e1 -textvariable tcycle
label $f4.l2 -text "Time to sleep (min)"
entry $f4.e2 -textvariable ttosleep
label $f4.l3 -text "Min/Max cycles" -width 12
entry $f4.e3 -textvariable mincycle
entry $f4.e4 -textvariable maxcycle
pack {*}[winfo children $f4] -side left -padx 2

button $f5.b1 -text Reset -command {Init $::t}
button $f5.b2 -text About -command {About}
button $f5.b3 -text Exit  -command {exit}
pack {*}[winfo children $f5] -side left -padx 2 -pady 2

Init $t