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
Direct Download
Read full article as PDF:
Price $2.95
News
-
Kali Linux 2022.3 Released
From the creators of the most popular penetration testing distributions on the planet, comes a new release with some new tools and a community, real-time chat option.
-
The 14" Pinebook Pro Linux Laptop is Shipping
After a considerable delay, the 14" version of the Pinebook Pro laptop is, once again, available for purchase.
-
OpenMandriva Lx ROME Technical Preview Released
OpenMandriva’s rolling release distribution technical preview has been released for testing purposes and adds some of the latest/greatest software into the mix.
-
Linux Mint 21 is Now Available
The latest iteration of Linux Mint, codenamed Vanessa, has been released with a new upgrade tool and other fantastic features.
-
Firefox Adds Long-Anticipated Feature
Firefox 103 has arrived and it now includes a feature users have long awaited…sort of.
-
System76 Refreshes Their Popular Oryx Pro Laptop with a New CPU
The System76 Oryx Pro laptop has been relaunched with a 12th Gen CPU and more powerful graphics options.
-
Elive Has Released a New Beta
The Elive team is proud to announce the latest beta version (3.8.30) of its Enlightenment-centric Linux distribution.
-
Rocky Linux 9 Has Arrived
The latest iteration of Rocky Linux is now available and includes a host of new features and support for new architecture.
-
Slimbook Executive Linux Ultrabook Upgrading Their CPUs
The Spanish-based company, Slimbook, has made available their next generation Slimbook Executive Linux ultrabooks with a 12th Gen Intel Alder Lake CPU.
-
Fedora Linux is Coming to the Raspberry Pi 4
Thanks to significant work in the upstream, the upcoming release of Fedora 37 will introduce support for the Raspberry Pi 4.