<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ant Smith</title>
    <description>The latest articles on DEV Community by Ant Smith (@ant_smith_e85a60e94fded6b).</description>
    <link>https://dev.to/ant_smith_e85a60e94fded6b</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3467903%2Fbbd0e9b7-a1cd-4758-9d13-6cf5342e7ffe.jpg</url>
      <title>DEV Community: Ant Smith</title>
      <link>https://dev.to/ant_smith_e85a60e94fded6b</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ant_smith_e85a60e94fded6b"/>
    <language>en</language>
    <item>
      <title>SkyQuest: A story-coded python app for scheduling astrophotography sessions</title>
      <dc:creator>Ant Smith</dc:creator>
      <pubDate>Sat, 06 Sep 2025 16:10:15 +0000</pubDate>
      <link>https://dev.to/ant_smith_e85a60e94fded6b/skyquest-a-story-coded-python-app-for-scheduling-astrophotography-sessions-kfk</link>
      <guid>https://dev.to/ant_smith_e85a60e94fded6b/skyquest-a-story-coded-python-app-for-scheduling-astrophotography-sessions-kfk</guid>
      <description>&lt;p&gt;&lt;b&gt;TL;DR: A little app to help plan astronomy sessions, written in Python using the Story-Code method&lt;/b&gt;&lt;br&gt;
The app might be useful to others so I shared it on GitHub - but really I wanted an example of Story-Code that meets a real-world use-case.&lt;/p&gt;

&lt;p&gt;Below is the full code-documentation, as extracted from the source-code itself using the primitive story-code tooling. If you want to know more about story-code, read my previous article: &lt;a href="https://dev.to/ant_smith_e85a60e94fded6b/story-coding-metaphor-as-cognition-5ed9"&gt;Story-Coding: Metaphor as Cognition&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=FOzBg48Tiig" rel="noopener noreferrer"&gt;Here's an example of the video output&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SkyQuest
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(3, 0)world&lt;/em&gt;:astrophotography.transits.world: This is the entry script fot the SkyQuest app.&lt;/p&gt;

&lt;p&gt;SkyQuest shows the astronomical info regarding the observability of celestial bodies from a given earth-bound observation point;  you'll need to look elsewhere (perhaps out of the window) for metereological impact.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1hgbclcpz0i1i0lsuvhv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1hgbclcpz0i1i0lsuvhv.png" alt="SkyQuest, screenshot" width="800" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It provdes a 24-hour daily view of how selected bodies transit across the skyline from the chosen vantage point. Multiple daily views can be stacked. The x-axis shows the local time of day, sensitive to daylight saving time. When showing multiple days, the x-axis reflects the last day drawn. The y-axis sets the plotted altitude range.&lt;/p&gt;

&lt;p&gt;Daylight bands can also be shown which segment the day (through coloured background blocks) between day and night, along with the various periods of twilight and dawn (civil, nautical and astronmical) - which is again true to the last day plotted.&lt;/p&gt;

&lt;p&gt;Celestial bodies can be selected for the plot, with the lunar arc, also, always available. The lunar arc is plotted in grey, at a brightness dictated by the moon-illumination on each plotted hour. The transit arcs of chosen objects are plotted with a degree of transparency dictated by the moon-illumination - i.e indicating how visible such onjects &lt;em&gt;may&lt;/em&gt; be (of course that's also a question of altitude and weather)&lt;/p&gt;

&lt;p&gt;It is therefore possible to see the optimum time to observe specific objects in the night sky with regards daylight level, moon-illumination and altitude - for one or more days; from anywhere in the world. The current dataset (from skyfield) is good to just before John Lennon's 113th birthday; so that'll need an update at some point...&lt;/p&gt;

&lt;p&gt;Once a plot has been created, it can be animated. Basically this clears the chart and re-draws it on an hour-by-hour and day-by-day basis; optionally generating a video file. SkyQuest maintains 2 views on the data: that which renders the overall plot in its entirety, and; that which renders the plot as a sequenced animation. This supports fast visibility toggling of aspects of the plot (e.g. turning the lunar arc on or off), and also allows those aspects to be excluded from the (reccorded) animation. The animation can proceed either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To the full accccumulation of the plot, or&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;as a sliding time window across the full day-range of the plot; e.g. to show a full monthly cycle changing across a year&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SkyQuest is well aware of just what it IS. There are a number of founding principals woven inherently into the source-code. You might want to argue that I should have been more absract in my modelling, to make the code more (re)useful; I'd counter, you know, life is finite.  Anyways, so we are clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;SkyQuest shows a (possibly stacked) day-by-day view, with a 'day' being the 24h hour period that follows noon on a given date.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Altitudes (and illumation) of objects are plotted to an hourly resolution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Events (sunrise, onset of astronomical twilight, etc...) are plotted to a minute resolution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are 9 such events in a day&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Video is output in HD resolution at 50fps - i.e. at a rate of 2 full animated days per second.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In-code, SkyQuest is presented as a cast of ancient greek mythological figures and concepts. Time is presented as both its fundamental material (Chronos) and its working mechanics (Kairos) with some influence of the fates (Moirai) also. Tiphys (helmsman of the Argonauts) provides the navigational support by caring for our home base vantage and our destination (selected celestial bodies). Idmon (the Argonaut's seer) connects us with our almanacs (from skyfield). Astreus (a Greek god of astrology) visualises Idmon's prophecies, through a rich collection of artboard, inscription tools, and parchment.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(296, 0)affordance&lt;/em&gt;:astrophotography.transits.Observatory&lt;/p&gt;

&lt;p&gt;On this quest everybody works within The Observatory.&lt;/p&gt;

&lt;p&gt;It allows queries to be resolved on a day-by-day basis. Each of the attendants concentrate on a given day, as sequenced by the query presented.&lt;/p&gt;

&lt;p&gt;Each of the key players provide their own control panels: vantage and targets from Tiphys; date and range from Chronos; Various plot settings from Astreus.  The observatory itself presents the master control (the hosios - attending the prophet Idmon - button).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(385, 0)behaviour&lt;/em&gt;:astrophotography.transits.main: Powers-up the observatory and allows it to run until explicitly stopped by the user exiting the main app by mouse or keyboard.&lt;/p&gt;







&lt;h2&gt;
  
  
  Main Players
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Time and Destiny
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(2, 0)throughline&lt;/em&gt;:astrophotography.aeonforge&lt;/p&gt;

&lt;p&gt;Herein we steward time so that no-one else needs to worry about the vagueries of time management.&lt;/p&gt;

&lt;p&gt;Just like the ancient greeks did, we split our concept of time into the material itself (how much of it we have to work with) and the mechanics of it (the expressions of time).&lt;/p&gt;

&lt;p&gt;There are 2 key underlying concepts that are woven throughout:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;All days start at noon and last for exactly 24 hours. This places midnight at the center of our inquiries, since astronomers are implicitly night-owls. Also note, 24hrs from noon may or may not be noon on the following day, since we display local times along with the vagueries of daylight saving.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Days are divided into, at most, 9 bands of daytime, night-time, dawns and dusks (civil, nautical, astronomical). Never more than 9 (the sun only rises once per day).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that we have imported QWidget from the continuum in its own (alien) metaphor. We allow that metaphor (of layouts, labels and fonts) to pervade here out of kindness to the sanity of others reading this module... but the underlying data concepts and exposures are within our chrono-mytho metaphor; as you will see.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(15, 0)figuration&lt;/em&gt;:astrophotography.aeonforge.Chronos&lt;/p&gt;

&lt;p&gt;As the personification of time itself, Chronos sets the temporal limits of an inquiry.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(140, 0)affordance&lt;/em&gt;:astrophotography.aeonforge.Kairos&lt;/p&gt;

&lt;p&gt;Regarding the nature of time, whilst Chronos concerns sequence, Kairos concerns moment.&lt;/p&gt;

&lt;p&gt;Through the mechanics of Kairos we attain fundamental knowledge of moments such as 'what time is it, here'; 'what daylight band is it?'&lt;/p&gt;

&lt;p&gt;One day Kairos will also understand the Vantage that Tiphys has set to better help us understand what time it is, although right now it always thinks we are in London!&lt;/p&gt;




&lt;h3&gt;
  
  
  Place and Knowledge
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(39, 0)figuration&lt;/em&gt;:astrophotography.transits.Tiphys&lt;/p&gt;

&lt;p&gt;Tiphys was the Argonaut's navigator, and here takes care of location based concepts - i.e where we are and where we are going.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(181, 0)figuration&lt;/em&gt;:astrophotography.transits.Idmon&lt;/p&gt;

&lt;p&gt;Idmon was a seer for the Argonauts, in fact he foresaw his own death on the voyage but went along anyway...&lt;/p&gt;

&lt;p&gt;This quest is a little easier for him, he consults the almanacs to tell us where things are on a given hour. &lt;/p&gt;

&lt;p&gt;He always tracks the sun and the moon and informs us about the daylight, twilight and night-time bands for any given date; along with the moon-illumination at each hour of a given date.&lt;/p&gt;

&lt;p&gt;Obvs, we also get the altitude data for observed objects on a (24) hourly basis for any given date.&lt;/p&gt;

&lt;p&gt;He's kind of micro-managed, so if we want data for multiple days, or multiple target objects on a given date, he has to be re-consulted.&lt;/p&gt;




&lt;h3&gt;
  
  
  Master Scribe
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(6, 0)throughline&lt;/em&gt;:astrophotography.astraeus&lt;/p&gt;

&lt;p&gt;There's quite a lot to do in terms of dislaying, animating and recording the plots that arise from the queries, so there are a number of layered concepts at play:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;ASTREUS is the master-scribe that orchestrates everything to do with the plot visualisation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;He is equipped with an ARTBOARD (GUI) that allows visual elements to be turned on or of and provides:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;INSCRIPTION tools for adding elements to the plot; where each tool provides for the animation of the added inscriptions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;and whereby the inscriptions are laid down on a PARCHMENT for the final visualisation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F211d8vma2dkj4awm4k5q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F211d8vma2dkj4awm4k5q.png" alt="Observatory, mapped layout" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;







&lt;h2&gt;
  
  
  CHAPTER - Time and Destiny
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What we know
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(35, 8)knowledge&lt;/em&gt;:astrophotography.aeonforge.Chronos.&lt;strong&gt;init&lt;/strong&gt;.self.chronogenesis: the denoted start of time, allowing for the entry of a (niave) date&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(114, 4)knowledge&lt;/em&gt;:astrophotography.aeonforge.Chronos.arche_date: the exact dawn of time (the first date)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(99, 4)behaviour&lt;/em&gt;:astrophotography.aeonforge.Chronos.arche_flux: A change in the chronogenesis implicitly invokes a new aion, a new quest&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(47, 8)knowledge&lt;/em&gt;:astrophotography.aeonforge.Chronos.&lt;strong&gt;init&lt;/strong&gt;.self.moira: the denoted destiny, the time alloted to us by the Fates (or Moirai) - as a simple integer&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(119, 4)knowledge&lt;/em&gt;:astrophotography.aeonforge.Chronos.aion: our precise allotment of time&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(129, 4)behaviour&lt;/em&gt;:astrophotography.aeonforge.Chronos.aion_flux: A change in our destiny, our alloted time.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(124, 4)knowledge&lt;/em&gt;:astrophotography.aeonforge.Chronos.eschatos: the end of days&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(77, 8)mechanism&lt;/em&gt;:astrophotography.aeonforge.Chronos.&lt;strong&gt;init&lt;/strong&gt;.self.telos: For the fulfillment of our destiny. The quest itself is governed by The Observatory, which provides it (via callaback) to Chronos so that time-flux based impulses can be satisifed.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(151, 4)knowledge&lt;/em&gt;:astrophotography.aeonforge.Kairos.day_bands: meaning of oblique twilight band codes (as revealed by Idmon) - note that twilight covers both ends of the day (dawn and dusk)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(148, 4)knowledge&lt;/em&gt;:astrophotography.aeonforge.Kairos.local_tz: reference for local time&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(106, 4)impulse&lt;/em&gt;:astrophotography.aeonforge.Chronos._quest: Although we never directly see our destiny (it is elsewhere written in the stars) we can still reach it through quest; which is triggered by any change in time, or by The Observatory when a new query is presented.&lt;/p&gt;




&lt;h3&gt;
  
  
  Mechanics
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(168, 4)mechanism&lt;/em&gt;:astrophotography.aeonforge.Kairos.divine_universal_time: provides the universal time for a given offset from noon of a given date.&lt;/p&gt;

&lt;p&gt;We work from noon because midnight is always at the center of our focus.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(212, 4)mechanism&lt;/em&gt;:astrophotography.aeonforge.Kairos.to_utc: Convert any (not niave) time to UTC, allowing for daylight saving&lt;/p&gt;

&lt;p&gt;(can also check that a time &lt;strong&gt;is&lt;/strong&gt; UTC)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(180, 4)mechanism&lt;/em&gt;:astrophotography.aeonforge.Kairos.true_hour: provides the universal time for a given hour after noon on a given date&lt;/p&gt;

&lt;p&gt;Allows us to be agnostic to timezones and daylight saving concerns&lt;/p&gt;

&lt;p&gt;Slightly blunt since we only allow for hour-resolution, but that is all we ever use.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(202, 4)mechanism&lt;/em&gt;:astrophotography.aeonforge.Kairos.utc_hours_difference: Finds the (fractional) hours separation between two UTC times&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(190, 4)mechanism&lt;/em&gt;:astrophotography.aeonforge.Kairos.what_time_is_it: Tells us what time it is at a given time!&lt;/p&gt;

&lt;p&gt;We can never really know what time it really is... because of daylight saving!&lt;/p&gt;

&lt;p&gt;So this answers the question, what time is it 'x' hours after noon on 'date', where we are asking from.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(91, 8)impulse&lt;/em&gt;:astrophotography.aeonforge.Chronos.&lt;strong&gt;init&lt;/strong&gt;.self.chronogenesis.dateChanged.connect: If a new aion begins then we  we attempt to fulfill our destiny through quest&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(86, 8)impulse&lt;/em&gt;:astrophotography.aeonforge.Chronos.&lt;strong&gt;init&lt;/strong&gt;.self.moira.valueChanged.connect: If something changes our destiny (our alloted time) we attempt to fulfill it through quest&lt;/p&gt;







&lt;h2&gt;
  
  
  CHAPTER - Divinations
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(203, 4)behaviour&lt;/em&gt;:astrophotography.transits.Idmon.set_transit: Does the heavy-lifting needed to consult the almanac for a number of things on a given date. This takes account of the fact that the vantage point shifts (with respect to the heavens) over the course of a day due to the earth's rotation. &lt;/p&gt;

&lt;p&gt;Note that because the lunar arc is always available to the plot, &lt;strong&gt;and&lt;/strong&gt; because we use the moon-illumination when plotting other arcs, Idmon provides those as soon as the heavy-lifting has been achieved.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(64, 8)knowledge&lt;/em&gt;:astrophotography.transits.Tiphys.&lt;strong&gt;init&lt;/strong&gt;.self.targets: Right now we have small, hand curated, list of celestial references. Really, this ought  to get loaded from a JSON file, with some kind of tool to support maintaing that by navigating the options within our almanac.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(118, 4)mechanism&lt;/em&gt;:astrophotography.transits.Tiphys.destination: gives us a list of dicts of the things we want to observe. These things may either be planets (with their skyfield-internal id) or objects designated by ra/dec values.&lt;/p&gt;

&lt;p&gt;Tiphys is a little surly in these regards, currently lettting us choose either all the planets, or &lt;strong&gt;a&lt;/strong&gt; planet or single object. However, he supplies the info as a list, so with a little further care, we could provide for much richer queries.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(107, 4)knowledge&lt;/em&gt;:astrophotography.transits.Tiphys.vantage: From where we are looking&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(150, 4)mechanism&lt;/em&gt;:astrophotography.transits.Tiphys.HomeBase: Although ancient, Tiphys is fully up-to-date with GDPR type concerns. The vantage (home location) is hidden behind a buttton so it isn't captured by any screen grabs.&lt;/p&gt;

&lt;p&gt;This could be quite lovely if it were to open a map-picker interface&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(191, 8)knowledge&lt;/em&gt;:astrophotography.transits.Idmon.&lt;strong&gt;init&lt;/strong&gt;.self.loader: this retrieves the almanac, which must have been downloaded&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(235, 4)mechanism&lt;/em&gt;:astrophotography.transits.Idmon.get_transit_arc: Provides the altitude of a given target at each hour of the transit date; handles both planetary and star type targets.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(254, 4)mechanism&lt;/em&gt;:astrophotography.transits.Idmon.get_twilight_bands: Works out the daily event times, e.g. sunrise et al. on the transit date&lt;/p&gt;

&lt;p&gt;provides a list of (9) start/end times-of-day periods consulting Kairos to prescribe the type of the time-period (day, night, etc...)&lt;/p&gt;

&lt;p&gt;Whilst it doesn't attemt to differentiate between dusks and dawns that is to our advantage because neither do we! All that matters to us is the daylight level: true night, astronomical twilight, nautical twilght, etc.. whichever end of the day we find those levels.&lt;/p&gt;

&lt;p&gt;Logically speaking we get 9 of these per day. We can cope with fewer (like we might see near the poles) but we have a deeply grounded faith that no day (24 hour period) will see the sun rise twice. I think that's reasonable.&lt;/p&gt;







&lt;h2&gt;
  
  
  CHAPTER - Charting
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(15, 0)figuration&lt;/em&gt;:astrophotography.astraeus.Astraeus&lt;/p&gt;

&lt;p&gt;Astraeus derives from the Greek word for 'star' and is said to be the father of the winds - so very much a key player in any astronomical quest.&lt;/p&gt;

&lt;p&gt;In this quest he creates the charts that answer the queries presented in The Observatory, which calls for the presentation to be started/completed - and for the days of interest to be drawn-in.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(4, 0)throughline&lt;/em&gt;:astrophotography.artboard&lt;/p&gt;

&lt;p&gt;The ArtBoard is essentially a collection of inscription tools along with a scroll (of PARCHMENT).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(2, 0)throughline&lt;/em&gt;:astrophotography.inscriptions&lt;/p&gt;

&lt;p&gt;Inscriptions are chart elements that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;contain a 'veil', a collection of marks on the parchment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;provide (UI) tooling to draw or hide the veil (or otherwise effect its apppearance)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;maintains the animation sequence for the veil's marks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;provides the means to execute the animation sequence&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;(2, 0)throughline&lt;/em&gt;:astrophotography.parchment&lt;/p&gt;

&lt;p&gt;The Parchment is where we actually (finally!) get to see stuff. It is powered by (and totally encapsulates our use of) matplotlib.&lt;/p&gt;

&lt;p&gt;It contains those visible elements that are not a part of the SkyQuest query per se - i.e. the chart title and axis.&lt;/p&gt;

&lt;p&gt;It allows for fresh parchments to be laid down, and old parchments to be recalled as we create new queries, or switch between displaying charts and animating charts.&lt;/p&gt;

&lt;p&gt;The parchment is supported by further affordances that handle our ability to restore old parhcments, and also for the actual mark-making.&lt;/p&gt;




&lt;h3&gt;
  
  
  The ArtBoard
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(26, 0)affordance&lt;/em&gt;:astrophotography.artboard.ArtBoard&lt;/p&gt;

&lt;p&gt;The ArtBoard controls presentation layers - whether or not we want to see groups of things, and what we want them to look like.&lt;/p&gt;

&lt;p&gt;So, for example, we can turn the display of the lunar arc on or off; or we can set the range of altitudes we want to see.&lt;/p&gt;

&lt;p&gt;One day we will extend this to allow selection of ink colours for the plotted arcs.&lt;/p&gt;

&lt;p&gt;The ArtBoard also lets us kick-off the animated reveal of the chart, providing us with the tools to control that.&lt;/p&gt;

&lt;p&gt;The ArtBoard comprises sets of layers that can be toggled on or off, with each layer being provisioned the inscription tools needed to draw the layer.&lt;/p&gt;

&lt;h4&gt;
  
  
  Inscription Tool Types
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;(112, 4)mechanism&lt;/em&gt;:astrophotography.artboard.ArtBoard.InscribeArc: Extends the basic inscription tool so that (complex) arcs can be inscribed.&lt;/p&gt;

&lt;p&gt;This tool adds one inscription for each arc to be displayed; we may have several arcs each day (e.g. all the planets) or we may end up with an arc for each of several days.&lt;/p&gt;

&lt;p&gt;We create one such tool for each set of arcs we provide - i.e. 2 such tools: the lunar arcs and, the transit arcs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(127, 4)mechanism&lt;/em&gt;:astrophotography.artboard.ArtBoard.InscribeBackground: Extends the basic inscription tool so that backgrounds can be inscribed.&lt;/p&gt;

&lt;p&gt;This is slightly different to inscribing arcs because we have one background - we don't accumulate the background day by day; rather we shift what is already there. Thus, you will note that the actual inscriptions are generated statically and then &lt;strong&gt;modified&lt;/strong&gt; - rather than adding new inscriptions as we progress&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(195, 4)mechanism&lt;/em&gt;:astrophotography.artboard.ArtBoard.InscribeGrid: Extends the basic inscription tool so that we can control the parchment's grid display. Again, we never add further inscriptions to this tool (there is only 1 grid), and the grid itself is not animated.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(159, 4)mechanism&lt;/em&gt;:astrophotography.artboard.ArtBoard.InscribeThreshold: Extends the basic inscription tool so that a value can be accepted that inscribes a horizontal guide on the parchment. &lt;/p&gt;

&lt;p&gt;We only allow for one guide, so the inscription is created statically when we forge the tool and is updated (via the UI) when desired. It is not an animated inscription.&lt;/p&gt;

&lt;h4&gt;
  
  
  ArtBoard Layers
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;(9, 0)affordance&lt;/em&gt;:astrophotography.artboard.Layer&lt;/p&gt;

&lt;p&gt;The Inscription tools have an associated 'layer' which provides the UI elements of the tool. &lt;/p&gt;

&lt;p&gt;A basic layer provides a simple toggle that connects to the inscriptions's visibility control&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(172, 8)affordance&lt;/em&gt;:astrophotography.artboard.ArtBoard.InscribeThreshold.ThresholdLayer&lt;/p&gt;

&lt;p&gt;Extends a basic layer by also providing UI for a threshold value&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(69, 4)affordance&lt;/em&gt;:astrophotography.artboard.ArtBoard.AltitudeRange&lt;/p&gt;

&lt;p&gt;Extends a basic layer by also providing for a pair of values which are directly connected to the parchment's Y-axis&lt;/p&gt;

&lt;h4&gt;
  
  
  Supporting mechanisms
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;(288, 4)mechanism&lt;/em&gt;:astrophotography.artboard.ArtBoard.render_title: Renders a title for the plot taking account of what is actually plotted (visible). &lt;/p&gt;

&lt;p&gt;Note that a reference to this method is provided to the inscriptions that effect the title - so the title is re-rendered when such inscriptions are turned on or off.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(275, 4)mechanism&lt;/em&gt;:astrophotography.artboard.ArtBoard.wipe: Cleans-up the ArtBoard when we are ready to start plotting a new presentation&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(215, 4)mechanism&lt;/em&gt;:astrophotography.artboard.ArtBoard.&lt;strong&gt;init&lt;/strong&gt;: Creates an ArtBoard with all of its complex tooling.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;a provided scroll is pinned to the artboard&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It's part of the ArtBoard's duty to keep track of which day we're dealing with when we are plotting over multiple days. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;UI components are added for the plot itself (the scroll PARCHMENT)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;and for the animation utility&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Specialised inscription tooling is added for the threshold indicator, the background, and the grid&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;then the inscription tooling and UI controls for each of the transit arcs are added. To keep the UI light the inscriptions are grouped into sets, with a UI control for each set: Background, Lunar arc, all (other) transit arcs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Inscriptions
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(11, 0)affordance&lt;/em&gt;:astrophotography.inscriptions.Inscriptions&lt;/p&gt;

&lt;p&gt;Inscriptions add 'stuff' to the presentation which can then be shown on the parchment. either as a complete charted element, or as an animated sequencce.&lt;/p&gt;

&lt;p&gt;They work with the PARCHMENT to make this stuff visible, but the main concern of an inscription is to granularise the inscribed 'thing' so that it can be revealed step-by-step when an animation is requested.&lt;/p&gt;

&lt;p&gt;The main affordance describes what an inscription IS and provides the main animation logic&lt;/p&gt;

&lt;h4&gt;
  
  
  Inscribing
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;(20, 4)affordance&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.Inscribe&lt;/p&gt;

&lt;p&gt;Inscriptions are sets of marks that can be made on a parchment.&lt;/p&gt;

&lt;p&gt;The full set lives in the 'veil' which may or may not be drawn at any given point (determined by the inscription's visible state)&lt;/p&gt;

&lt;p&gt;That's all there is to it for simple inscriptions like the grid or the guides.&lt;/p&gt;

&lt;p&gt;More complex (or compound) inscriptions like transit arcs and the background are also created as animateable groups - i.e. per-hour per-day segments. Unlike the veil (which is completely on or off) these can be revealed step-by-step (when we animate). &lt;/p&gt;

&lt;p&gt;Effectively the inscriptions provides 2 views on the same displayable 'thing': the entire thing (line or background) turned on or off as a whole, and; a segmented version turned on or off on an hour-by-hour basis.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(39, 8)mechanism&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.Inscribe.add_inscription: Adds a set of marks to the inscription's veil (the overall view of the chart)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(47, 8)mechanism&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.Inscribe.update_inscription: Updates previous inscriptions, but only in a simple well-defined way; i.e. when we know exactly what we are dealing with. So we may change the value of an existing guideline, or the extent of a known background band.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(149, 8)skill&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.Inscribe.draw_veil: Directs the parchment to make or erase the marks of this veil (i.e avoids direct low-level calls into matplotlib at this point)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(54, 8)mechanism&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.Inscribe.make_arc_inscription: Adds segemented lines to the animation view, returning an inscription set that can then also be added to the veil - i.e. presumes the data is already suitably segmented (by the hour), which it will be when it comes to transit arcs that are derived on an hourly basis.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(84, 8)mechanism&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.Inscribe.make_bg_inscription: Creates the animation steps for the background. These either grow the day bands from nothing to full width (day zero) or else shuffles the boundary between the day bands (on subsequent days).&lt;/p&gt;

&lt;p&gt;Note that the inscriptions themselves are already added, here we create the animation steps that adjust them.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(130, 8)mechanism&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.Inscribe.set_visibility: Shows or hides the inscription's veil, updating the overall plot title if needed&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(142, 8)mechanism&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.Inscribe.toggle_visibility: For the UI which operates in terms of toggle rather than absolute state&lt;/p&gt;




&lt;h3&gt;
  
  
  Parchment
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(254, 0)affordance&lt;/em&gt;:astrophotography.parchment.Parchment&lt;/p&gt;

&lt;p&gt;The parchment sets the overall look and feel of a chart, it orchestrates the ChartedElements and provides for video records. It is the visualisation of the chart.&lt;/p&gt;

&lt;h4&gt;
  
  
  Save and Restore
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;(376, 4)mechanism&lt;/em&gt;:astrophotography.parchment.Parchment.fresh_parchment: Saves the format and content of the current parchment, before clearing it for fresh duty.&lt;/p&gt;

&lt;p&gt;Changes the parchment format if we are writing a video file (to HD geometry)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(417, 4)mechanism&lt;/em&gt;:astrophotography.parchment.Parchment.restore_parchment: Signs-off the current parchment (closing the video file if we had it open) before clearing and restoring whatever went before.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(400, 4)mechanism&lt;/em&gt;:astrophotography.parchment.Parchment.clear_plots: Clears any existing chart content that a new query will influence.&lt;/p&gt;

&lt;p&gt;I.e. remove line collectioons and super-slim background blocks (to a width of 0)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(11, 0)affordance&lt;/em&gt;:astrophotography.parchment.ChartedElements&lt;/p&gt;

&lt;p&gt;Simply stores or recalls all elements of a chart - lets us restore the parchment if we wipe it in order to present the animated version; manages both content and format.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(23, 4)mechanism&lt;/em&gt;:astrophotography.parchment.ChartedElements.save_geometry: Saves the format (geometry) of the parchment, in case we need to change it for video output&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(31, 4)mechanism&lt;/em&gt;:astrophotography.parchment.ChartedElements.restore_geometry: Restores the format (geometry) of the parchment&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(40, 4)mechanism&lt;/em&gt;:astrophotography.parchment.ChartedElements.save_original_ax: Saves the chart content in case we need to clear the parchment for the animation&lt;/p&gt;

&lt;p&gt;This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;the line collections of the transit arcs, which get removed so they can be added piece-by-piece in the animation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the visible extent of the background daybands, which don't get removed but do get resized by the animation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;x-axis ticks, which might be blanked at the end of an animation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the chart title. To be honest this ought to be right when an animation ends, but it will have been twiddled with so might as well save the original along with the foregoing&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;(65, 4)mechanism&lt;/em&gt;:astrophotography.parchment.ChartedElements.restore_original_ax: Simply reverses the original save&lt;/p&gt;




&lt;h4&gt;
  
  
  Making Marks
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;(81, 0)affordance&lt;/em&gt;:astrophotography.parchment.InnerChartElements&lt;/p&gt;

&lt;p&gt;By 'inner' we mean the actual plot area of the chart, so that's the data we plot, the background elements, any guide lines and the grid. &lt;/p&gt;

&lt;p&gt;Lets us add/change/remove and show/hide such elements.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(107, 4)skill&lt;/em&gt;:astrophotography.parchment.InnerChartElements.inscription_visibility: Turns all marks of an inscription on or off&lt;/p&gt;

&lt;h5&gt;
  
  
  For Transit Arcs
&lt;/h5&gt;

&lt;p&gt;&lt;em&gt;(128, 4)mechanism&lt;/em&gt;:astrophotography.parchment.InnerChartElements.add_lines: Adds the lines of a transit arc as a line collection.&lt;/p&gt;

&lt;p&gt;For the main plot this will be many segments of a full-day arc.&lt;/p&gt;

&lt;p&gt;During animation, this will be the first hour's segments only&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(166, 4)mechanism&lt;/em&gt;:astrophotography.parchment.InnerChartElements.decay_line: Shrinks a line collection from its earliest point, until it is sooo short it is no longer a collection of lines (whereupon it is removed completely)!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(142, 4)mechanism&lt;/em&gt;:astrophotography.parchment.InnerChartElements.extend_line: Specifically for the animation, extends an arc's previous line collection with a new hour's segment&lt;/p&gt;

&lt;h5&gt;
  
  
  For the background
&lt;/h5&gt;

&lt;p&gt;&lt;em&gt;(185, 4)mechanism&lt;/em&gt;:astrophotography.parchment.InnerChartElements.add_block: Adds a block (rectangle) to the parchment&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(203, 4)skill&lt;/em&gt;:astrophotography.parchment.InnerChartElements.set_block: Updates the position and extent of a block on the parchment&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(212, 4)mechanism&lt;/em&gt;:astrophotography.parchment.InnerChartElements.shuffle_blocks: Shuffles blocks: i.e. shifts the end point of one block and the start point of its (right-hand) neighbour; juggling the widths as needed. This lets us see the bands grown and shrink as the days pass by.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(230, 4)mechanism&lt;/em&gt;:astrophotography.parchment.InnerChartElements.decay_blocks: Shrinks background blocks from the left, specifically during the wind-down of an animation&lt;/p&gt;

&lt;h5&gt;
  
  
  Ancilliaries
&lt;/h5&gt;

&lt;p&gt;&lt;em&gt;(90, 4)mechanism&lt;/em&gt;:astrophotography.parchment.InnerChartElements.hguide: Inscribe a horizontal guide on the parchment, or modify its position if it has already been inscribed.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(116, 4)mechanism&lt;/em&gt;:astrophotography.parchment.InnerChartElements.set_grid: Establish the look of the grid (when it is visible) or else sets the grid invisaible&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(293, 4)affordance&lt;/em&gt;:astrophotography.parchment.Parchment.XAxis&lt;/p&gt;

&lt;p&gt;Presents the x-axis and handles changes to its tick labels&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(265, 4)affordance&lt;/em&gt;:astrophotography.parchment.Parchment.YAxis&lt;/p&gt;

&lt;p&gt;Presents the y-axis and handles changes to its range&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(369, 4)skill&lt;/em&gt;:astrophotography.parchment.Parchment.retitle: Renders a new title for the chart&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(432, 4)skill&lt;/em&gt;:astrophotography.parchment.Parchment.redraw: Ensures everything actually gets rendered.&lt;/p&gt;




&lt;h3&gt;
  
  
  Plots
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(339, 4)behaviour&lt;/em&gt;:astrophotography.transits.Observatory.present_query: THIS is the telos, the fulfillment of our destiny. &lt;/p&gt;

&lt;p&gt;Sets up the specific observation requested then steps through the day range to marshal the skills of Idmon and Astraeus to build-up the results.&lt;/p&gt;

&lt;p&gt;Finally calling on Astraeus to complete the works and present the plot&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(45, 4)mechanism&lt;/em&gt;:astrophotography.astraeus.Astraeus.commence_presentation: Sets-up the ArtBoard with a fresh parchment for the new plot (clearing any animation)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(58, 4)behaviour&lt;/em&gt;:astrophotography.astraeus.Astraeus.draw_day: Draws the entire plot for a single day: the background day bands, each transit arc, the title and the axes.&lt;/p&gt;

&lt;p&gt;The title includes the (overall) day range and so needs updating for each plotted day, as does the x-axis as the time-of-day hour labels change when we have daylight saving.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(118, 4)mechanism&lt;/em&gt;:astrophotography.astraeus.Astraeus.draw_day_bands: Adds the day/twilight colour-bands to the inscriptions&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(133, 4)mechanism&lt;/em&gt;:astrophotography.astraeus.Astraeus.plot_arc_day: Adds (all) the transit arcs to the inscriptions for a given day&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(160, 4)mechanism&lt;/em&gt;:astrophotography.astraeus.Astraeus.complete_presentation: Finalises a presentation by adding the threshold inscription and calling on the ArtBoard's draw_veil methods to set what is (or isn't) visible. Thereafter calling on the parchment to do the draw.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(27, 8)knowledge&lt;/em&gt;:astrophotography.astraeus.Astraeus.&lt;strong&gt;init&lt;/strong&gt;.arc_sets: we always allow for the lunar arc, plus 1 or more celsatial bodies&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(22, 8)knowledge&lt;/em&gt;:astrophotography.astraeus.Astraeus.&lt;strong&gt;init&lt;/strong&gt;.self.greyscale: a look-up table that lets us plot the moon's arc relative to its illumination&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(34, 8)knowledge&lt;/em&gt;:astrophotography.astraeus.Astraeus.&lt;strong&gt;init&lt;/strong&gt;.self.target_colours: the colours we use to plot celestial arcs. Fixed here but one will be managed by the ArtBoard&lt;/p&gt;







&lt;h3&gt;
  
  
  Animations
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(333, 4)behaviour&lt;/em&gt;:astrophotography.artboard.ArtBoard.do_animation: Initiates an animation, allowing a video render to be produced also.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(38, 4)mechanism&lt;/em&gt;:astrophotography.artboard.ArtBoard.AnimationModeDialog: Allows us to direct how the animation of a plot procedes - i.e. should each day accumulate in the plot, or should older days be erased as the animation procedes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(368, 0)affordance&lt;/em&gt;:astrophotography.artboard.AnimationFilter&lt;/p&gt;

&lt;p&gt;Records the state of the chart display before we start messing with it in order to present the animation; resetting the initial state when the animation completes.&lt;/p&gt;

&lt;p&gt;Having remembered the original state of the chart display it can also answer the question 'is this part of the animation'? whilst the animation is running; So only those thongs visible when we asked for the animation are included in the animation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(252, 4)behaviour&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.animate: Executes the animation of the current (complete) plot.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Remember what was visible before the animation so we can restore that state later. Then turn all the veils of so we have a blank slate for the animation to begin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;animate by day...&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;... by hour...&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;...by step...&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;only animate that which was visible&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;remove any expired line segments / collections&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;if we are currently unwinding the animation, just get on with it, no need to look for any steps that might want adding&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;otherwise perform the animated steps, which includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;update title (specifically so the date range is accurate)&lt;/li&gt;
&lt;li&gt;update x-axis ticks, which change on daylight saving days&lt;/li&gt;
&lt;li&gt;add the transit arcs for the hour&lt;/li&gt;
&lt;li&gt;grow the day bands as the animation procedes. So on day 1 we see the daybands expand from nothing&lt;/li&gt;
&lt;li&gt;shuffle the day bands on subsequent days&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;At the end of each hour now...&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;on the final day of the unwind, erase the background and the x-tick labels (since time is evapourating..!) on an hour-by-hour basis&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;display/record the animation of this hour&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;at the end of day, step to the next day, if there is one&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;(164, 4)affordance&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.DayTracker&lt;/p&gt;

&lt;p&gt;Keeps track of the days during an animation, providing the key mechanisms for a controlled unwind at the end of the animated day range (if needed)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(188, 8)disposition&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.DayTracker.more_days: A simple yes or no to the question 'are there more days to present': whether those days are the main animation, or days in the unwind period.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(177, 8)mechanism&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.DayTracker.step_day: Keeps track of days both through the day-range of the animation, and through the unwind period atthe end off an animation&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(196, 8)disposition&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.DayTracker.too_many_days: Indicates if we ought to be erasing earlier arcs from teh plot as the animation procedes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(204, 8)disposition&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.DayTracker.final_day: Indicates if this is the final day of the end of days&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(212, 4)affordance&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.ArcLimiter&lt;/p&gt;

&lt;p&gt;An intermediary between the animator and the PARCHMENT.&lt;/p&gt;

&lt;p&gt;Collects references to the marks that are made so they can be progressively removed later if required.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(226, 8)mechanism&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.ArcLimiter.expire: Removes all of the marks made in the (current) oldest hour of the animated chart&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(238, 8)mechanism&lt;/em&gt;:astrophotography.inscriptions.Inscriptions.ArcLimiter.extend: Adds the animated marks to the PARCHMENT, remembering all the marks made in the given hour so they can later be expired.&lt;/p&gt;







&lt;h2&gt;
  
  
  APPENDIX: CONTINUUM
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(2, 0)throughline&lt;/em&gt;:astrophotography.continuum&lt;/p&gt;

&lt;p&gt;Defines foundational imports and truths upon which the drama unfolds.&lt;/p&gt;

&lt;p&gt;All our modules perform 'import *' from the continuum.&lt;/p&gt;

&lt;p&gt;In a larger app we would split this into separate modules, and then use &lt;strong&gt;init&lt;/strong&gt;.py to 'import *' from the core section only, with individual user modules then importing all from the extensions.&lt;/p&gt;

&lt;p&gt;but it is kept simple for now, albeit less scalable.&lt;/p&gt;

&lt;p&gt;NOTE:: This is THE CONTINUUM, it only hosts the external world and NEVER includes imports of app-local modules!&lt;/p&gt;

&lt;p&gt;I know, its unusual to promote the use of 'import *' (and you may well hate the idea) but exactly what gets imported is somewhat restricted to exactly what we use and this appproach gives us a single point of truth with regards our reliance on the wider world..!&lt;/p&gt;

&lt;h3&gt;
  
  
  Standards
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(17, 0)continuum&lt;/em&gt;:astrophotography.continuum.sys: we use the standard sys module to get CLI arguments and issue exit codes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(27, 0)continuum&lt;/em&gt;:astrophotography.continuum.collections: we use the convenience of the defaultdict to ensure we can always index every hour of every day in a given day range, since conceptually those indices are always valid (days always have 24 hours!) - even if we don't happen to have any data for a given time.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(23, 0)continuum&lt;/em&gt;:astrophotography.continuum.math: The standard math module provides 'ceil', which helps to chunk time into 1 hour bands&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(25, 0)continuum&lt;/em&gt;:astrophotography.continuum.numpy: The NUMPY module is used a convenience to create small sequences, when needed - there no serious vectorised operations in this app&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(19, 0)continuum&lt;/em&gt;:astrophotography.continuum.gc: at the end of an animation we have a lot of matplotlib objects to clean-up, at which point we perform an explicit garbage collection. Not really something we should HAVE to do, but, well - matplotlib...&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(21, 0)continuum&lt;/em&gt;:astrophotography.continuum.time: The standard time module provides 'sleep', for when we want to pace an interactive animation&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(31, 0)continuum&lt;/em&gt;:astrophotography.continuum.datetime: Dates and times pervade in this application, but you can pretty much always expect them to be standard datetime objects - EXCEPT where Idmon needs to work in Julian dates, but that's a complexity he keeps to himselff...&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(36, 0)continuum&lt;/em&gt;:astrophotography.continuum.zoneinfo: when we add contextual time to a (naive) input date we do so as UTC, then convert to local time as needed (e.g. when display time axes); in general we can expect our datetime objects to be UTC&lt;/p&gt;




&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(42, 0)continuum&lt;/em&gt;:astrophotography.continuum.skyfield.api: All of our astronomical knowledge is drawn from skyfield, based on data downloads in './skyfield-data'&lt;/p&gt;




&lt;h3&gt;
  
  
  UI
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(56, 0)continuum&lt;/em&gt;:astrophotography.continuum.PyQt5.QtWidgets: All GUI  is provided by PyQt5&lt;/p&gt;




&lt;h3&gt;
  
  
  Plotting
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(102, 0)continuum&lt;/em&gt;:astrophotography.continuum.matplotlib.animation: provides the (FFMPEG) video writer&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(96, 0)continuum&lt;/em&gt;:astrophotography.continuum.matplotlib.backends.backend_agg: provides the chart visualisation when recording video frames&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(92, 0)continuum&lt;/em&gt;:astrophotography.continuum.matplotlib.backends.backend_qt5agg: provides the interactive (on-screen) chart visualisation, in concert with GUI (PyQt5)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(111, 0)continuum&lt;/em&gt;:astrophotography.continuum.matplotlib.collections: All of our actual plotted arcs are created as line collections, which helps when we want to animate the chart&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(123, 0)continuum&lt;/em&gt;:astrophotography.continuum.matplotlib.colors: we use colours with transparency when plotting the transit arcs, inversely relative to the moon illumination (which makes celestial objects less visible!).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(107, 0)continuum&lt;/em&gt;:astrophotography.continuum.matplotlib.figure: lets us add figures to a canvas - we only ever work with 1 figure, but nevertheless matplot lib treats a canvas as containing a set of figures.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(119, 0)continuum&lt;/em&gt;:astrophotography.continuum.matplotlib.font_manager: we use a single font family, but at a variety of sizes&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(115, 0)continuum&lt;/em&gt;:astrophotography.continuum.matplotlib.patches: the background visualisation of daylight/twilight bands is achieved by adding rectangles (behind the transit arcs) as so-called patches.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(104, 0)continuum&lt;/em&gt;:astrophotography.continuum.matplotlib.pyplot: only required when we come to release canvas memory&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;The full source code can be found in this GitHub repository: &lt;a href="https://github.com/AntSmith60/skyquest" rel="noopener noreferrer"&gt;https://github.com/AntSmith60/skyquest&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>astrophotography</category>
      <category>documentation</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Ant Smith</dc:creator>
      <pubDate>Fri, 29 Aug 2025 16:42:23 +0000</pubDate>
      <link>https://dev.to/ant_smith_e85a60e94fded6b/-393e</link>
      <guid>https://dev.to/ant_smith_e85a60e94fded6b/-393e</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/ant_smith_e85a60e94fded6b" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3467903%2Fbbd0e9b7-a1cd-4758-9d13-6cf5342e7ffe.jpg" alt="ant_smith_e85a60e94fded6b"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/ant_smith_e85a60e94fded6b/story-coding-metaphor-as-cognition-5ed9" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Story-Coding: Metaphor as Cognition&lt;/h2&gt;
      &lt;h3&gt;Ant Smith ・ Aug 29&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#cognition&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#paradigms&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#documentation&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>cognition</category>
      <category>paradigms</category>
      <category>programming</category>
      <category>documentation</category>
    </item>
    <item>
      <title>Story-Coding: Metaphor as Cognition</title>
      <dc:creator>Ant Smith</dc:creator>
      <pubDate>Fri, 29 Aug 2025 16:40:17 +0000</pubDate>
      <link>https://dev.to/ant_smith_e85a60e94fded6b/story-coding-metaphor-as-cognition-5ed9</link>
      <guid>https://dev.to/ant_smith_e85a60e94fded6b/story-coding-metaphor-as-cognition-5ed9</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Story-Coding reframes programming as a cognitive act—one that transcends pure rationality.&lt;/strong&gt; It introduces a dramaturgical grammar that weaves metaphor and meaning around code, transforming technical artifacts into lived experience. This isn’t code plus documentation—it’s cognitive ignition.&lt;/p&gt;




&lt;p&gt;When I was a junior developer back in the 80's, one guy told me “If it was hard to write, it should be hard to read". I don't think he was entirely joking, and he perhaps contributed to the idea that C was a write-only language.&lt;/p&gt;

&lt;p&gt;I never saw programming like that. For me it was a kind of modern magic, the way simple numbers (perhaps the simplest numbers, 0 and 1) could be impelled to flow from the imagination into the real-world; to draw dots on a page, colours on a screen, or drive motors on a mighty mechanical behemoth (I was working in the field of process control - so yes, there were lots of primitive robots around). Programming was fun, captivating even. And I believed it ought to be an understandable, shareable experience; like, I just couldn't keep this awesome 'thing' all to myself.&lt;/p&gt;

&lt;p&gt;The key concept here is that code should be 'an understandable experience'.&lt;/p&gt;

&lt;p&gt;This is what 'written for humans' really means. It has little to do with readability or documentation; and everything to do with experience.&lt;/p&gt;

&lt;p&gt;For millennia, humans have used 'narrative cognition' (story-telling) to experience the abstract. So it seems a no-brainer to me that there is a place for narrative in writing (and consequently documenting) code.&lt;/p&gt;

&lt;h2&gt;
  
  
  On Understanding
&lt;/h2&gt;

&lt;p&gt;To date, we have largely approached programming as a purely rational pursuit; Afterall computers themselves are purely rational constructs, right? Well, that's as maybe, but we write code for humans not machines - else why employ high-order languages at all? Bending our own thought processes to the limits of the metal, simply limits our own thoughts. The compilers and interpreters should provide the duty of abstracting rational constructs from our intent. We should express that intent in ways that are natural to human thought processes.&lt;/p&gt;

&lt;p&gt;We can know a thing by observation, but we can only understand it by experience. A senior developer can certainly understand code just by looking at it, but that's by dint of years (or decades) of experience. Understanding is always a product of knowing and experiencing.&lt;/p&gt;

&lt;p&gt;So, what if we can make the code not just a rational construct that can be known, but rather an experience in and of itself? I.e. make code that ignites cognition, through the power of narrative.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Narrative isn't just decorative - it isn't an embellishment of cognition; &lt;strong&gt;it is one of its native forms&lt;/strong&gt;. From predictive modelling to memory construction, narrative enables us to think, feel, and act with coherence.&lt;br&gt;
Narrative "is deeply integrated into how we make sense of what happens and how we figure ourselves into it” (Brooke Miller, Narrativity in Cognition, 2023). Gerrig &amp;amp; Egidi (Cognitive Psychological Foundations of Narrative Experiences, 2003) explore how narrative comprehension draws on memory, inference, and simulation — core cognitive functions that are activated through narrative structure. Bouizegarene et al. (Narrative as Active Inference, 2024) argue that narrative helps individuals and groups generate useful models of the world, coordinate behaviour, and adapt over time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  On Excitation
&lt;/h2&gt;

&lt;p&gt;At this point, you are perhaps reminded of Knuth (et al.)'s Literate Programming concept, which never really flew in the mainstream. There are various criticisms of that approach, but for me the key problem lay in the fact that the results were, well, just boring. You cannot read an LP artifact and &lt;b&gt;feel&lt;/b&gt; cognitively excited by it!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Emotion is not a luxury, it is essential to rational thinking.”&lt;br&gt;
Antonio Damasio, Descartes’ Error (1994)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we want code to be understood, then it needs to impel an emotional response.&lt;/p&gt;

&lt;p&gt;I'm not interested in critiquing or dismissing Knuth (for his time, it was truly great work) - but rather to evolve. &lt;/p&gt;

&lt;p&gt;And I think the key evolutions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To not just annotate the code in-place, but to apply a grammar of story&lt;/li&gt;
&lt;li&gt;To not enforce a rigid structure, but to provide for the creation of a narrative arc that can be orthogonal to the code structure&lt;/li&gt;
&lt;li&gt;To not require a singular authorial voice, but to allow for a chorus of characterisations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Story-coding is about weaving rich metaphor &lt;b&gt;around and within&lt;/b&gt; the code; applying narrative constructs that have been developed and refined since the very dawn of civilisation.&lt;/p&gt;

&lt;p&gt;An example may make sense... which I have in &lt;a href="https://github.com/AntSmith60/code-as-story" rel="noopener noreferrer"&gt;this GitHub repository&lt;/a&gt; - check-out the expo.md to see the manual that has been extracted from the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basics of story-code
&lt;/h2&gt;

&lt;p&gt;Fundamentally, Story-Code is about adding an extra dimension to the code we write. It doesn't aim to replace technical documentation, nor enforce a structure upon the rational code-architecture. The code (continues to) contain the rational thought, with the story components adding the cognitive ignition - the creation of an emotional response that enables cognition, experience, feeling.&lt;/p&gt;

&lt;p&gt;And it isn't just about documentation. That cognitive excitation is for the benefit of the coder, as much as it is for others. Writing stories is fun. Weaving stories helps to promote coherent thought.&lt;/p&gt;

&lt;p&gt;Although much of story-coding comes down to (guided) addition of exposition to the code it's altogether a more refined approach than that. We use (well known) parts-of-story concepts (the story grammar) to devise rich metaphor for the code. We express that metaphor in the exposition, but also in the code itself - especially through the naming of objects (and consequently, the aliasing of objects that cross metaphorical boundaries).&lt;/p&gt;

&lt;p&gt;There's no attempt to enforce a singular metaphor across an entire code base, as that would cause much dissonance between collaborators. Nor is it necessary. Good stories weave a variety of characterisations together, that create internal resonance or friction.&lt;/p&gt;

&lt;p&gt;Finally, &lt;strong&gt;if&lt;/strong&gt; we provide sufficient exposition (as distinct parts of story) then we can be confident that they will assemble into a complete narrative arc, at the appropriate time. I.e. it is common in narrative constructs to recognise a distinction between parts-of-story and plot. In Story-Coding there is a deliberate separation of these concerns. The (rational) code structure is allowed its own architecture, with the (expressive) narrative extracting and grouping components into its own plot structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Story Grammar
&lt;/h2&gt;

&lt;p&gt;Story-coding doesn't just call for added prose that in itself creates the cognitive spark, it offers a series of 'writing prompts' which, when coupled with the metaphor at hand, leads us towards a coherent experience.&lt;/p&gt;

&lt;p&gt;There are various (documented) formulas for storytelling, and we are at liberty to devise our own. In fact, the grammar of story can be a foundational moment in the high-order analysis of a problem domain. There need not be a single, strict and definitive, statement of what constitutes the grammar of story (although for a given code-base, it ought to be tied down).&lt;/p&gt;

&lt;p&gt;My own approach is grounded by my MA in Playwrighting, so is perhaps a fair starting point - albeit as yet somewhat nascent. The components (currently are):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WORLD VIEW: An initial scene setting discourse at the application level. Also introduces the various metaphors that will be employed&lt;/li&gt;
&lt;li&gt;CONTINUUM: Description of an 'alien entity' - something that intrudes into the story world, possibly in its own metaphor (typically imported or included concepts)&lt;/li&gt;
&lt;li&gt;THROUGHLINE: A discourse that connects the current metaphor (of the module in hand) with the world view. Helps us to relate metaphorical concepts to code mechanics, typically therefore, one per module.&lt;/li&gt;
&lt;li&gt;CHARACTERISATION: A &lt;b&gt;figuration&lt;/b&gt; or &lt;b&gt;affordance&lt;/b&gt;, a complex package of smaller story parts with broad purpose. Key players in the story.&lt;/li&gt;
&lt;li&gt;KNOWLEDGE: Things that are known, or come to be known.&lt;/li&gt;
&lt;li&gt;DISPOSITION: states or attitudes&lt;/li&gt;
&lt;li&gt;BEHAVIOUR: A sequence or iteration of actions based on knowledge and dispositions&lt;/li&gt;
&lt;li&gt;MECHANISM: Transformative actions with material effects&lt;/li&gt;
&lt;li&gt;SKILLS: Informative actions&lt;/li&gt;
&lt;li&gt;FLAWS: All the stuff that goes wrong&lt;/li&gt;
&lt;li&gt;PROSE: More detailed discussions...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We use the grammar to introduce comments or comment blocks within the code base that become attached to the following meaningful lexical item - e.g. a class or method or variable. Such expositions precede the thing they describe, discussing more 'why' it exists than 'how' it works. This is fundamentally orthogonal to technical notes (of how) that typically sit within (not before) the thing they discuss (e.g. Python docstrings sit inside their encapsulator). &lt;/p&gt;

&lt;p&gt;There's a couple of exceptions to that placement expectation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Module-level expositions (WORLD VIEW and THROUGHLINE) sit within the module they relate to&lt;/li&gt;
&lt;li&gt;PROSE expositions weave around the code they relate to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PROSE expositions help to keep the specific mechanics of code statements bound to the story, and seem most useful within BEHAVIOURS&lt;/p&gt;

&lt;p&gt;My initial view of the story grammar was more complex, including concerns such as STORY LIMITS, PERSPECTIVES, IMPULSES and IMPROVISATIONS. Dramaturgy often thinks of CHARACTERISATIONS as having UNIQUE ABILITIES and CRITICAL FLAWS; it may also consider IMPEDIMENTS and GOALS. There's a rich seam of dramaturgical concepts that can be applied when describing code as story - whatever best ignites cognition. But the foregoing proved enough, at least initially.&lt;/p&gt;

&lt;h2&gt;
  
  
  Narrative Arc
&lt;/h2&gt;

&lt;p&gt;The example code (Python scripts that extract expositions from Python scripts) was written using the story grammar. &lt;/p&gt;

&lt;p&gt;The lexicographer metaphor spans 2 modules, the base class of LEXICOGRAPHICS skills and the derived class of LEXICOGRAPHER behaviours - not an unusual architectural decomposition.&lt;/p&gt;

&lt;p&gt;The extracted story is somewhat different. The throughline that contextualises the (shared) metaphor is extracted from LEXICOGRAPHER, there is one throughline for one metaphor even though the metaphor extends across two modules. The rest of the chapter on lexicographics then intermixes expositions from the two modules to provide a coherent story that is less fractured than simply following the code structure.&lt;/p&gt;

&lt;p&gt;The resulting story file is generated by editorialising the list of lexical entities that have expositions attached. The list is grouped and re-ordered to form the narrative arc, with subject headings inserted. The story-telling is in the code, but the story itself is plotted as a separate activity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Epilogue
&lt;/h2&gt;

&lt;p&gt;The most important thing in Story-Coding is to understand that it is not about documenting code. It's about adopting a cognitive, rather than rational, mindset; cognition being a superset of rationality. A story grammar helps to create a coherency when writing story-fragments, and a metaphorical throughline helps to ignite cognition in the coder and for those that come after. &lt;/p&gt;

&lt;p&gt;Plus, metaphor is fun - and fun tasks are simply, done better.&lt;/p&gt;

&lt;p&gt;These are pretty novel thoughts - I would love to enter into discussion with others here!!!&lt;/p&gt;

&lt;h2&gt;
  
  
  RESOURCES
&lt;/h2&gt;

&lt;p&gt;To 'get' what all this means, you really need to look at the code and outputs in this GitHub repository: &lt;a href="https://github.com/AntSmith60/code-as-story" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://github.com/AntSmith60/code-as-story" rel="noopener noreferrer"&gt;https://github.com/AntSmith60/code-as-story&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cognition</category>
      <category>paradigms</category>
      <category>programming</category>
      <category>documentation</category>
    </item>
  </channel>
</rss>
