Skip to content

Instantly share code, notes, and snippets.

@maxhawkins
Last active October 12, 2017 04:54
Show Gist options
  • Save maxhawkins/4d4f6e59d5017d6f48df9872c549d86d to your computer and use it in GitHub Desktop.
Save maxhawkins/4d4f6e59d5017d6f48df9872c549d86d to your computer and use it in GitHub Desktop.
Random Daily Schedule Generator
// package main provides a random daily schedule generator
package main
import (
"fmt"
"math/rand"
"strings"
"time"
)
var (
categories = []string{
"housekeeping",
"communicating",
"socializing",
"learning",
"relaxing",
"moving",
"contemplating",
"self care",
"work",
"sleeping",
}
modifiers = []string{
"easy",
"difficult",
"safe",
"adventurous",
}
// modifierProb is the likelihood that a random task will
// have a modifier from the list above
modifierProb = 0.2
// rowHeight controls the number of dots displayed after each
// task. A dot is emitted for each rowHeight in duration.
rowHeight = 15 * time.Minute
)
func main() {
rand.Seed(time.Now().UnixNano())
fmt.Println(RandSchedule().String())
}
// RandSchedule produces a randomly generated, day-long schedule
func RandSchedule() Schedule {
var schedule Schedule
var block Block
var total time.Duration
for total < 24*time.Hour {
task := randTask()
// skip if task is same as the last
if task == block.Task {
continue
}
dur := randDuration()
// trim if it makes schedule > 24h
if dur+total > 24*time.Hour {
dur = 24*time.Hour - total
}
block = Block{task, dur}
schedule = append(schedule, block)
total += dur
}
return schedule
}
func randDuration() time.Duration {
dur := time.Duration(rand.Intn(int(3*time.Hour))) + 10*time.Minute
grain := 30 * time.Second
dur = dur / grain * grain // round
return dur
}
func randTask() string {
i := rand.Intn(len(categories))
task := categories[i]
if rand.Float64() < modifierProb {
j := rand.Intn(len(modifiers))
task = modifiers[j] + " " + task
}
return task
}
// A Schedule holds a collection of time Blocks representing a
// 24 hour schedule. Assumes the sum of the block durations is 24h.
type Schedule []Block
// String returns a string representation of this schedule in tabular
// format. The number of lines is controlled by rowHeight.
//
// Example:
//
// Your schedule for today:
//
// 00:00 work (44m30s)
// .
// 00:44 moving (2h3m)
// .
// .
func (s Schedule) String() string {
str := "Your schedule for today:\n\n"
start := time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)
for _, block := range s {
startStr := start.Format("15:04")
// remove "0s" if it's a round number of minutes
durationStr := block.Duration.String()
if block.Duration%time.Minute == 0 {
durationStr = strings.Replace(durationStr, "0s", "", 1)
}
// print task name
str += fmt.Sprintf("%s %s (%s)\n", startStr, block.Task, durationStr)
// add dots to make block take up rows proportional with its length
height := int(block.Duration / rowHeight)
for i := 0; i < height-1; i++ {
str += " .\n"
}
start = start.Add(block.Duration)
}
return str
}
// Block represents a block of time dedicated to a task
type Block struct {
Task string
Duration time.Duration
}
Your schedule for today:
00:00 work (27m30s)
00:27 sleeping (15m30s)
00:43 contemplating (48m)
.
.
01:31 sleeping (2h50m)
.
.
.
.
.
.
.
.
.
.
04:21 housekeeping (2h2m30s)
.
.
.
.
.
.
.
06:23 relaxing (25m30s)
06:49 self care (2h32m30s)
.
.
.
.
.
.
.
.
.
09:21 contemplating (29m)
09:50 adventurous sleeping (3h4m)
.
.
.
.
.
.
.
.
.
.
.
12:54 moving (1h36m)
.
.
.
.
.
14:30 adventurous housekeeping (2h41m)
.
.
.
.
.
.
.
.
.
17:11 communicating (2h26m30s)
.
.
.
.
.
.
.
.
19:38 difficult housekeeping (2h30m30s)
.
.
.
.
.
.
.
.
.
22:08 sleeping (1h51m30s)
.
.
.
.
.
.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment