Last active
March 15, 2022 00:22
-
-
Save davidhaynz/d014fc26f139ec819657c805bdb980d4 to your computer and use it in GitHub Desktop.
Create a Google Calendar of NZ tides for a defined location. This python3 script parses tide data obtained as a .csv file from Land Information NZ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import csv | |
from datetime import datetime, timedelta | |
# Create a Google Calendar of NZ tides for a defined location | |
# This python3 script parses tide data obtained as a .csv file from Land Information NZ | |
# The data files are downloadable from: https://www.linz.govt.nz/sea/tides/tide-predictions | |
# The output .csv file(s) can be imported into a Google Calendar | |
# Script was used to create tides for 2022, 2023 & 2024 at Weiti River Entrance | |
# The public Google Calendar is named: NZ_Tides_Weiti | |
# If you use this script for another location, please make the calendar public and use the same naming convention, | |
# such as: NZ_Tides_Wellington | |
# N.B. script may fail if the input .csv file is not coded UTF-8. | |
# Open in Excel or Libreoffice Calc, choose UTF-8 coding, then save the file before running this script | |
# Request location, input & output file names in terminal: | |
tide_at = input("Name of tide location - e.g. 'Weiti River Entrance': ") | |
tide_file = input("Name of .csv file to process (include .csv suffix): ") | |
calendar_file = input("Provide a name for calendar data file (include .csv suffix): ") | |
# tide data parsing function | |
def make_tide(tdate, ttime, tval, tstr): | |
# create a list, this function will replace the values | |
the_tide = ['0_Subj', '1_stDate', '2_stTime', '3_enDate', '4_enTime', '5_Desc', '6_Weiti', 'PUBLIC'] | |
# Add 30 mins to tide time, to create end time for calendar entry (will span midnight, if a tide is after 23:30) | |
time_begin = tdate + " " + ttime | |
time_plus = datetime.strptime(time_begin, '%d/%m/%Y %H:%M') + timedelta(minutes=30) | |
date_end = datetime.strftime(time_plus, '%d/%m/%Y') | |
time_end = datetime.strftime(time_plus, '%H:%M') | |
#convert all tide height values to 1 decimal point | |
thgt = float(tval) | |
tval = str(thgt) | |
# Acknowledge data source in calendar entry description field | |
data_source = 'Tide data provided by Land Information NZ: https://www.linz.govt.nz/sea/tides/tide-predictions' | |
# replace the_tide list values | |
the_tide[0] = tstr + tval + "m" # e.g. High: 3.2m | |
the_tide[1] = tdate | |
the_tide[2] = ttime | |
the_tide[3] = date_end | |
the_tide[4] = time_end | |
the_tide[5] = data_source | |
the_tide[6] = tide_at | |
return the_tide | |
# open input .csv file | |
with open(tide_file, 'r') as read_obj: | |
# pass the file object to reader() to get the reader object | |
csv_reader = csv.reader(read_obj) | |
# Pass reader object to list() to get a list of tide data (by day) | |
dayList = list(csv_reader) | |
# the output is a separate list for each tide: three or four per day/row | |
# create empty output list | |
tide_data = [] | |
# iterate through rows in csv file that contain tide data (the first 3 rows don't) | |
i = 3 | |
while i < len(dayList): | |
day = dayList[i] | |
# Set up the variables to pass to the make_tide function | |
# 1: create the date value string from csv columns 0,2,3 | |
tDate = day[0] + "/" + day[2] + "/" + day[3] | |
# 2: get tide heights (High or Low) to for calendar display | |
tH1 = day[5] | |
tH2 = day[7] | |
if tH2 < tH1: | |
hiLo = ['High: ', 'Low: ', 'High: ', 'Low: '] | |
else: | |
hiLo = ['Low: ', 'High: ', 'Low: ', 'High: '] | |
# 3: determine if there are 3 or 4 tides in the day (if 3, doesn't process the empty 4th column) | |
if not day[11]: | |
nCol = 9 | |
else: | |
nCol = 11 | |
# Iterate through tide columns in "day" and pass tide values to make_tide function | |
x = 4 # start at 5th column in aRow, increment by 2 | |
y = 0 # Choose "High" or "Low" from hiLo list, to pass to Subject (tStr) | |
while x < nCol: | |
tStr = hiLo[y] | |
tVal = day[x + 1] | |
tTime = day[x] | |
a_tide = make_tide(tDate, tTime, tVal, tStr) | |
# debug check - disabled: | |
# print(atide) | |
# Add returned atide to tide_data output list: | |
tide_data.append(a_tide) | |
# iterate tides in a row | |
y += 1 | |
x += 2 | |
# iterate rows | |
i += 1 | |
# create an output file (with the input file name) | |
with open(calendar_file, 'w', encoding='UTF8', newline='') as f: | |
# Header Row as required for Google Calendar upload | |
header = ['Subject', 'Start Date', 'Start Time', 'End Date', 'End Time', 'Description', 'Location', 'Private'] | |
# populate output file with header and data rows | |
writer = csv.writer(f) | |
# write the header | |
writer.writerow(header) | |
# write tide data rows | |
writer.writerows(tide_data) | |
# all done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment