My not-first FORTRAN code

Back in 2001, for a challenge, I taught myself part of the Python programming language and wrote a program based on the idea of a FORTRAN program I wrote decades ago. Now, for another challenge, I’ve written the same program – in FORTRAN! I had to dig out a free compiler from the Internet (FORTRAN90). Things have developed and changed since I was a programmer and I have had to learn new things in the language. Back then I think I used FORTRAN 66 and FORTRAN 77.

It’s been fun coding in FORTRAN, again! For the record, I downloaded and used two free products, Code::Blocks and Strawberry Perl, which I’ve found to be successful. (I’m not clear on where Strawberry Perl fits into this!). I also found this YouTube video to explain configuring of Code::Blocks.

! ===================================================================
! Program REMINDER
!
! Decades ago I wrote a FORTRAN program to take a file of reminders 
! and to display the records in a sorted and pretty format.
! In March 2021, for fun, I wrote a Python version of the program.
! Now, in January 2023, for fun, I have again written a FORTRAN version.
!
! Version 0.1 20-Jan-2023 Start of conversion of the Python code
! Version 1.0 29-Jan-2023 Final version.....?
!
! ===================================================================
program Reminder

use ReminderModule ! All the functions/subroutines are in this module.
implicit none
type (rec_data) ReminderTable(100)
character myfile*100
integer Nreminders

myFile = "C:\Users\Mike\Documents\Documents\MyFortranCode\MyReminderProject\Reminder.dat"

call GetReminderData(myFile,ReminderTable,Nreminders)
call SortList (ReminderTable,Nreminders)
call PrintList(ReminderTable,Nreminders)
end program Reminder
!
!==========================================================
! Module REMINDERMODULE containing all the functions and subroutines.
!==========================================================
module ReminderModule
!
implicit none
type rec_data !Structure to hold the reminder records
    character*11  rec_date      !reminder date
    character*50  rec_event     !reminder event
    integer  rec_numdays        !Calculate days between date and today's date
end type rec_data
contains

!============================================================
!Subroutine GETREMINDERDATA to get the reminder records
!Records are of the form dd-mmm-yyyy,"Event description" and are unordered
!============================================================
subroutine GetReminderData(filename,ReminderTable,N)
implicit none
integer mystatus,N,ans,ans_today
character filename*(*), mystatusmessage*200,mydate*11,mytext*50,today*8
character monthchar*3,months*36
integer d,m,y
type (rec_data) ReminderTable(*)
data months/"JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"/

open (unit=1,file=filename,action='read', &
      form='formatted',iostat=mystatus,iomsg=mystatusmessage)
if (myStatus /= 0) then
    write (*,'(///2a)') "OOPS! ", mystatusmessage
    stop
endif
!
! Calculate the number of days between today and a base date
!
call date_and_time(date=today) ! Inbuilt procedure
read(unit=today,fmt='(i4,i2,i2)')y,m,d ! This used to be done using an ENCODE statement!
call getDays(d,m,y,ans_today) !Get the number of days between today and a base date
!
! Get the reminder records
!
N = 0
do
    read (unit=1,fmt=*,iostat=mystatus,iomsg=mystatusmessage)mydate,mytext
    if (mystatus /= 0) then
        exit
    else
        N=N+1
        ReminderTable(N)%rec_date = mydate
        ReminderTable(N)%rec_event = mytext
        read (unit=mydate,fmt='(i2,1x,a3,1x,i4)')d,monthchar,y ! Get the date components
        m = index(months,uppercase(monthchar))/3+1 ! Lookup the month number using the month text
        call getDays(d,m,y,ans) !Get the number of days between the date and a base date
        ReminderTable(N)%rec_numdays = ans - ans_today !Number of days between date and today's date
    end if
end do
close (unit=1)
end subroutine

!============================================================
! Subroutine GETDAYS to calculate the number of days between
! the supplied date and an arbitrary base date (01/01/2000)
!============================================================
subroutine getDays( day,month,year ,ans)
implicit none
integer ans,i,daysPerMonth(1:12),daysPerMonthLeapYear(1:12)
integer day,month,year
data daysPerMonth         / 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 /
data daysPerMonthLeapYear / 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 /

ans=0
do  i = 2000, year-1 ! Add up the days in the preceding years of the supplied date
    ans=ans +365
    if (isLeap(i)) ans=ans + 1
end do
!
do i =1,month-1,1 ! Add up the days in the preceding months in the year of the supplied date
    if (isLeap(year)) then
        ans = ans + daysPerMonthLeapYear(i)
    else
        ans=ans + daysPerMonth(i)
    end if
end do
!
ans = ans + day - 1 ! Finally add in the number of days (less 1) of the month of the supplied date
!
end subroutine getdays



!=============================================================
! Function ISLEAP to determine if a year is a leap year
!=============================================================
logical function isLeap(Y)
!
integer Y
!
! A leap year is divisible by 400 or, is divisible by 4 but not by 100
!
isLeap = (mod(Y,400) .EQ. 0) .OR. (mod(Y,4) .EQ. 0 .AND. mod(Y,100) .NE. 0)

end function isleap
!
!=============================================================
! Subroutine SORTLIST to sort the data in date order.
!=============================================================
subroutine SortList (ReminderTable,N)
type (rec_data) :: ReminderTable(*),temp
integer :: N,i,j
logical :: Swapped

DO j = N-1, 1, -1
    swapped = .FALSE.
    DO i = 1, j
      IF (ReminderTable(i)%rec_numdays > ReminderTable(i+1)%rec_numdays) THEN
        temp = ReminderTable(i)
        ReminderTable(i) = ReminderTable(i+1)
        ReminderTable(i+1) = temp
        swapped = .TRUE.
      END IF
    END DO
    IF (.NOT. swapped) EXIT
END DO

end subroutine
!
!=============================================================
! Function UPPERCASE to convert text to upper case.
!=============================================================
function uppercase(string)
character(len=*), intent(in) :: string
character(len=len(string)) :: uppercase
integer :: j
do j = 1,len(string)
  if(string(j:j) >= "a" .and. string(j:j) <= "z") then
       uppercase(j:j) = achar(iachar(string(j:j)) - 32)
  else
       uppercase(j:j) = string(j:j)
  end if
end do
end function uppercase
!
!====================================================
! Function PRINTLIST to nicely print the data
!====================================================
subroutine PrintList (ReminderTable,N)
type (rec_data) :: ReminderTable(*)
integer :: N, nDays, i
logical :: tChange
character*16 t1
character*75,parameter :: mySectionSeparator="---------------------------------------------------"

tChange = .TRUE.

write (*,'(/////)')
write (*,'(2x,a)')mySectionSeparator
write (*,'(2x,a)')"         Welcome to my FORTRAN Reminder program!"
write (*,'(2x,a)')mySectionSeparator
do i = 1, N
    nDays = ReminderTable(i)%rec_numdays
    if (tChange .eqv. .TRUE. .and. nDays > 0) then
        tChange = .False.
        write (*,'(2x,a)') mySectionSeparator
    end if
    if (nDays == 0) then
        t1 = "     Today    "
    else if (nDays == -1) then
        t1 = "   Yesterday  "
    else if (nDays == 1) then
        t1 = "    Tomorrow  "
    else if (nDays < 0) then
            write(unit=t1,fmt='(i4,a)')-ndays," days since" !In my days it was the ENCODE statement
    else
            write(unit=t1,fmt='(i4,a)')ndays," days until"
    end if

    write (*,'(2x,a,1x,a,1x,a,a)')ReminderTable(i)%rec_date,t1,ReminderTable(i)%rec_event

end do
write (*,'(2x,a///)')mySectionSeparator
end subroutine

end module

And the output is….

When Covid stops you doing much

I’m on my 5th day with Covid and there’s no sign of improvement. In isolation, other than from my wife, there’s little enthusiasm or energy for doing much. But I have felt able to tackle my laptop’s downloads-folder which has filled up considerably over the past year or so. The folder mainly contains images downloaded from the camera or phone, some of which I had dealt with but not deleted or filed away, and some which have just got ignored. After much effort the downloads folder is now in good shape with just two, near-empty sub-folders.

I found these 4 images which have some interest, particularly the main one of 8-year-old Chloe in a rather stunning outfit.

It’s my birthday

Happy birthday
to me!

I had a lovely birthday in Bushy Park with our daughter and the two little ones, followed by chocolate cake back at their home.

And then to open some lovely presents (see below) including some Nordic walking poles.

Iris and Chloe hiding coins in Bushy Park fallen trees,
hopefully bringing joy to other kids when they find them!

50 years ago!

50 years ago!

We made it!

This is me on our wedding day, in a pink suit. Probably the last outfit I wore with any colour in!

By Chloe
By Iris & Chloe
By Iris

A new chess board

Our dad gave us a chess set when we were kids. Somehow my brother got the board and I got the pieces. Several decades later I’ve belatedly treated myself to a new board to replace the crappy, cardboardy thing I got from who-knows-where. The new board even has the letters and numbers to assist me when I’m following the games of the grandmasters – cool!

Son, next time you’re over from Berlin, we must have a rematch!

[Note to self: Next time I take a picture of a chess board, ensure the pieces are lined up properly in their squares…]

Painting kite flying

After my last painting I wrote that it was my final artwork until I’d worked through some of “Acrylics for the Absolute Beginners, by Charles Evans”. Well that hasn’t happened – I’ve never been very good at RTFM.

So here’s me at work, the laptop casting Steely Dan to the speakers, the iPad showing the photo I’m attempting to approximate, and the work in progress. Below is the finished painting. I confess that I’ve digitally brightened the image as my painting was, shall I say, subdued. I’m reasonably happy with it.

You can see my artistic development / non-development at https://thingschange.blog/not-an-artist/

These are my final artworks

These are my final artworks until I’ve worked through at least some of “Acrylics for the Absolute Beginners, by Charles Evans”. Why? Because I’m struggling to figure out what to paint. When you don’t have the basic skills, you’re limited in what you can achieve. This morning’s efforts are the two cards for the little ones and this bizarre effort. I’ve no idea what the thing is in the top right. I think it started off as a bird! I should have painted over it and put in the sun or an aeroplane! Oh well, watch this space.

You can see my artistic development / non-development at https://thingschange.blog/not-an-artist/

A life of games

Childhood

I was mad on playing football as a young kid. I considered myself a star dribbler in the junior school playground. At senior school I once played matches for the junior, middle and senior teams, all in the same week.

I even had a trial to get into the Southampton schoolboys team (was it Southampton West or East? – I can’t remember). I was rubbish on that day and my football playing days came to an end when Saturday matches clashed with doing a Saturday job.

That’s me, with the ball

College days

At college I played an awful lot of bridge. I fondly recall playing well into the early morning with only a break around 11pm, to re-energise with chicken and chips from the chippy around the corner. Once we tried playing in the evening in a pub but some grumpy sod complained and that was cut short. Oh happy, wasted days!

In my last year at college I discovered badminton. I remember beating the class instructor in my very first game. My interest in badminton was to continue for many decades.

Twenties

During my first career job I took up chess, having learnt to play at a young age. I still have my first chess pieces, which were a present from my dad. I played at work during the lunch break on a rather nice portable set that I treated myself to. Games stretched over several days and me and my colleague would sometimes play over the phone (each with our own board). I somehow accumulated two more sets, presents I think, so a total of 4 of sets which I still have, though I haven’t played for many, many years. I’m hoping that I may be able to interest one of the little ones in the near future.

I also played a bit of badminton, in church halls with low ceilings.

Thirties & beyond

After a bit of a gap I eventually resumed playing badminton. For a couple of years I was hooked on playing singles against a much younger work colleague. For a long time he was unable to beat me, but given the closeness of the games it was inevitable that eventually he would. From then on the games were pretty evenly matched and the spoils shared.

I began playing mixed doubles with work colleagues, and this was to continue for some considerable time. My time as a badminton player came to end when for the second time in two years I tore something at the back of my leg (first the right then the left). The experience was so painful and distressing that I decided I didn’t want a repeat of this injury.

Regrets

I wish I had put more of an effort into playing tennis and also table tennis. I’ve played a little, and I love these games. I’m clearly a missile-over-the-net person!

The NotAnArtist resurfaces

It’s been over a month since I last had out my acrylics and it was probably about the same time that I last sent cards of my paintings to the two little ones. So here are two more efforts by yours truly, NotAnArtist.

I’m very aware that I’m not really progressing, despite have bought or been given some cheap art books such as How to Draw Anything, Acrylics in 10 Steps, Painting With Watercolours, Oils & Acrylics, Read This If You Want To Be Great At Painting, and finally, How to Draw Anything. The trouble is I have no discipline and I’m, and have always been, a lousy learner. I’m not sure what the answer is….

You can see my artistic development / non-development at https://thingschange.blog/not-an-artist/

2 paintings in one day!

The kids sent me a WhatsApp image taken from their trip to the seaside and I tried to paint something similar. Here is my effort. That was done in the morning and in the afternoon I decided to carry on and came up with a second work. The subject wasn’t quite what I intended- let’s just say it evolved into what it is!

You can see my artistic development / non-development at https://thingschange.blog/not-an-artist/