Calculating weekdays and dates with Go
Terminal with Mouse Input
The MouseLeft
event comes up if the user clicks and releases the left mouse button. The payload enclosed with the event indicates the coordinates at which the mouse pointer was located at the time of the click. Line 47 needs to dynamically convert the event received as a generic interface{}
type to a ui.Mouse
type; it then uses Y
to access the (vertical) y-value of the click position.
The wdayPick()
function in line 86 determines the clicked weekday. It can do that because the program knows from the UI layout that Sunday is at the click position with a y-value of 4
, Monday at 5
, and so on through Saturday at position 10
. The function discards any other position, returning an error, so that the main program simply ignores the click.
If the user has done their mental arithmetic correctly and selected the right weekday, the condition in line 53 is true, and the BorderStyle.Fg
attribute sets the weekday widget's frame to green. The following call to randDate()
in line 56 fetches a new date task, and the success counter wins
is incremented by one. However, if the user guesses wrong, line 59 colors the widget's frame red and sets wins
back to zero. Life can be hard!
To refresh the success counter graphically, the call to displayTask()
in line 63 changes the widget's contents, and the call ui.Render()
with both widgets as parameters updates the current status in the terminal. To make sure that the red or green border that provides user feedback only appears briefly and then disappears again, line 65 starts a Go routine that runs in parallel; it first sleeps for 200ms thanks to time.After()
, then resets the window's frame to the original White
(which actually looks gray), and displays the whole thing with ui.Render()
. That's how dynamics come into play, thanks simply to the standard parallelism features built into Go.
Text in Color
The text displayed in the widgets can also be colored using termui if so desired – not with an attribute like the widget borders, but using special tags in the text string on display. The date to be calculated appears in black thanks to this, and the number of successfully completed tasks in green; lines 80 to 81 include corresponding color commands in the text to be displayed with (fg:black)
and (fg:green)
.
Tricky Date Arithmetic
Selecting a random day of the year is more difficult than you might think. Sure, most years have 365 days, but in a leap year with 366 days, even February 29 should occur every now and then. Thanks to the Duration
type from the time package, Go offers a method to calculate the time span between January 1 of the year investigated and the same date of the following year. Unfortunately, it refuses to express this in days, but uses hours instead.
The reason for this is the mess that occurs when a leap second [5] or the summer/winter time changeover occurs between two dates. Does that count as a fraction of a day or not? Go forces the programmer to multiply the hour difference by 24 to get the day number – as an indication that this may not be entirely true.
It is easier to use the Unix epoch time on Linux; this gives you the number of seconds that elapsed since January 1, 1970. It does not include leap seconds that have occurred, but gives the same timestamp to the times before and during a leap second. The randDate()
function from line 93 in Listing 1 determines the Unix time for January 1st of the investigated year as well as the time stamp for January 1 of the following year and determines the time difference in seconds.
The rand.Intn()
function then selects a random number between
(inclusive) and the timestamp of January 1 of the following year (exclusive) from the math/rand package and adds the value to the start date. The result is a second timestamp sometime in the current year, which the time.Unix()
function converts into a time.Time
object from the Go standard library, whose month and day are output by Month()
and Day()
. Since Unix seconds are available as int64
and the random functions from math/rand expect and return normal ints, line 102 needs to mediate between the two and convert the types accordingly.
The random number generator provided by Go still has the unpleasant feature of supplying the same random values whenever you call the program; this is unlikely to offer users any lasting training benefits in the long run. For this reason, line 98 taps into a new entropy source, initializes it with the current time in nanoseconds as the seed, and thus creates the new random number generator in the r1
variable. Its Intn()
method therefore comes up with new random sequences each time the dateday
binary is called.
« Previous 1 2 3 Next »
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
New Slimbook EVO with Raw AMD Ryzen Power
If you're looking for serious power in a 14" ultrabook that is powered by Linux, Slimbook has just the thing for you.
-
The Gnome Foundation Struggling to Stay Afloat
The foundation behind the Gnome desktop environment is having to go through some serious belt-tightening due to continued financial problems.
-
Thousands of Linux Servers Infected with Stealth Malware Since 2021
Perfctl is capable of remaining undetected, which makes it dangerous and hard to mitigate.
-
Halcyon Creates Anti-Ransomware Protection for Linux
As more Linux systems are targeted by ransomware, Halcyon is stepping up its protection.
-
Valve and Arch Linux Announce Collaboration
Valve and Arch have come together for two projects that will have a serious impact on the Linux distribution.
-
Hacker Successfully Runs Linux on a CPU from the Early ‘70s
From the office of "Look what I can do," Dmitry Grinberg was able to get Linux running on a processor that was created in 1971.
-
OSI and LPI Form Strategic Alliance
With a goal of strengthening Linux and open source communities, this new alliance aims to nurture the growth of more highly skilled professionals.
-
Fedora 41 Beta Available with Some Interesting Additions
If you're a Fedora fan, you'll be excited to hear the beta version of the latest release is now available for testing and includes plenty of updates.
-
AlmaLinux Unveils New Hardware Certification Process
The AlmaLinux Hardware Certification Program run by the Certification Special Interest Group (SIG) aims to ensure seamless compatibility between AlmaLinux and a wide range of hardware configurations.
-
Wind River Introduces eLxr Pro Linux Solution
eLxr Pro offers an end-to-end Linux solution backed by expert commercial support.