Another tool I feel would be useful, while it is written for me you could find it useful as well.
Granted there is no indication exactly "what" the pills are we track, I know what I am tracking and you know what you might want to track in such a way.
Right now the program does not create the specified folder I use to store a simple text file in, so you will have to do that manually.
I will be breaking down the code bit by bit.
It is a go program.
package main
import (
"flag"
"fmt"
"os"
"time"
"strconv"
)
These are the imports.
As always I am mostly using the standard library, that is really a good reason to use go.
Okay so the program is just a moderately sized main function.
func main() {
pill_dispense := ? // set the amount you get per dispense, it will tell you how many pills you have left.
pill_bool_ptr := flag.Bool("pill", false, "Whether or not a pill was taken")
pill_count_ptr := flag.Int("count", 0, "Set the current counter to the correct amount")
flag.Parse()
the ? is just for personal information reason, it is a simple int the amount of pills you might receive at a time, so you know what is left.
the pill_bool_ptr
if the program is called with -pill
it will increment the counter with 1. Though the code for this is later in the code
pill_count_ptr
allows the count to be set with -count {num}
.
The one thing I did not write into the program at this moment is the when count hits dispense it should reset.
content, _ := os.ReadFile("/home/tobi/.cache/pills/content.dat")
time_now := time.Now()
date_str := fmt.Sprintf("%d-%d-%d", time_now.Year(), time_now.Month(), time_now.Day())
var intchar int64
so os.ReadFile
returns the content of the file and an error, however since I would write if err != nil { panic(err) }
and I assume that is the default behavior, I can just put in the underscore, the error case is only important if you do not want to panic on error (I think), I could be wrong. In which case I should change this code.
In a lot of cases when I write small software for cli for myself just panic on error seems to be the most reasonable solution. Though I have had a few cases where the errors needed to be handled in a different way, so it needs thought, whether it is a case of panic on error, or something that needs to be handled.
The rest of the code in this block is pretty standard, get the time for now, formatting a string. A cool thing here would be that if the string in fmt.Sprintf
was "%d-%s-%d"
The month would print something like Jul
or Dec
, I think that is pretty cool.
My dates are mostly written in the YYYY-MM-DD format, which is actually the ISO standard. Almost like binary numbers least significant digit all the way to the right.
for _, char := range content {
chara := fmt.Sprintf("%c", char)
intchar, _ = strconv.ParseInt(chara, 10, 64)
if *pill_bool_ptr {
intchar = intchar + 1
}
if *pill_count_ptr > 0 {
intchar = int64(*pill_count_ptr)
}
}
Hmm this code might not be the greatest thing ever, now it is small amounts of data (up to 10 characters), so it will be very quick. But doing the work over all elements is bad, now my data is not going to grow so it is fine.
chara is converted from a byte to a char the %c
is the format for character. since the byte code 51 is not exactly very enlightening, the number 3 is better.
Then after the character is converted to a string, it can be made into a int64 since the parseint insist that is the type to use.
the if cases is what handles the behavior expected from the flags from the start of the program.
frankly pretty simple.
data_str := fmt.Sprintf("%s: %d", date_str, intchar)
os.WriteFile("/home/tobi/.cache/pills/content.dat", []byte(data_str), 0222)
fmt.Println("Pills left: ", pill_dispense-int(intchar))
}
The final part of the program, creating the data_str, then writing it to the file as a sequence of bytes.
Then finally printing the remaining pills.
Taking the code in the blocks and changing the one ? to a sensible value you have a program.
and it is explained.
Thanks for your contribution to the STEMsocial community. Feel free to join us on discord to get to know the rest of us!
Please consider delegating to the @stemsocial account (85% of the curation rewards are returned).
You may also include @stemsocial as a beneficiary of the rewards of this post to get a stronger support.