Better software through software architecture and devops

@jamessnape

Posts

  • Bournemouth Beach

    Converting code between Javascript technologies isn't simple but GPT/Copilots can do a lot of the heavy lifting.

    Its been nearly 10 years since I last posted an article on this site. Having children and other priorities pushed blogging lower down the priority stack. Plus the site used hosted on https://jamessnape.wordpress.com/ and getting embedded code to look good was an effort.

    My kids are older now and I’m interested in using this site to learn about new technologies; specifically Astro, Svelte, and Tailwind CSS.

    Once of the challenges I’ve had creating this new implementation is there are now a lot of privacy laws in place such as GDPR. Since I use Google Analytics I have to include a Privacy Policy and cookie consent pop-up 1.

    As a guide I followed Creating a Cookie Consent Banner for Google Tag Manager to add mine here. This example uses Solid JS for the implementation of the consent functionality and its not familiar to me so I turned to Bing Copilot for help.

    First step is to ask a general question “how to convert solidjs to svelte?

    To convert SolidJS to Svelte, you can follow the steps below:

    1. First, install the latest version of Svelte by running the following command in your terminal: npm install svelte@latest

    2. Next, create a new Svelte component file with the same name as your SolidJS component file. For example, if your SolidJS component file is named MyComponent.js, create a new file named MyComponent.svelte.

    3. Copy the contents of your SolidJS component file into your new Svelte component file.

    4. Replace any SolidJS-specific syntax with equivalent Svelte syntax. You can refer to the official Svelte documentation for more information on Svelte syntax.

    5. Finally, compile your Svelte component file into a JavaScript file that creates the DOM and CSS files that style it. You can use SvelteKit, the official application framework from the Svelte team, to handle this process. Run the following command in your terminal: npm run dev

    I hope this helps! Let me know if you have any other questions.

    This is a nice high level plan but the 4th point is a little light on detail so next question “expand on point 4 please”.

    Sure, I can explain more about point 4. Point 4 is about replacing any SolidJS-specific syntax with equivalent Svelte syntax. This means that you need to change the way you write your component logic, state, props, events, and other features that are different between SolidJS and Svelte.

    Here are some examples of how to convert some common SolidJS syntax to Svelte syntax:

    • Component logic: In SolidJS, you write your component logic inside a function that returns JSX. In Svelte, you write your component logic inside a <script> tag that can export variables and functions to the template. For example:
    // SolidJS
    import { createSignal } from "solid-js";
    
    function Counter() {
      const [count, setCount] = createSignal(0);
    
      function increment() {
          setCount(count() + 1);
      }
    
      return (
        <div>
          <p>Count: {count()}</p>
          <button onClick={increment}>+1</button>
        </div>
      );
    }
    

    HTML

    <!-- Svelte -->
    <script>
      let count = 0;
    
      function increment() {
        count++;
      }
    </script>
    
    <div>
      <p>Count: {count}</p>
      <button on:click={increment}>+1</button>
    </div>
    
    • State: In SolidJS, you use createSignal to create reactive state variables that are updated by calling setter functions. In Svelte, you use let to declare reactive state variables that are updated by assigning new values. For example:
    // SolidJS
    import { createSignal } from "solid-js";
    
    function App() {
      const [name, setName] = createSignal("World");
    
      function handleChange(e) {
        setName(e.target.value);
      }
    
      return (
        <div>
          <h1>Hello {name()}!</h1>
          <input type="text" value={name()} onInput={handleChange} />
        </div>
      );
    }
    

    HTML

    <!-- Svelte -->
    <script>
      let name = "World";
    
      function handleChange(e) {
        name = e.target.value;
      }
    </script>
    
    <div>
      <h1>Hello {name}!</h1>
      <input type="text" bind:value={name} on:input={handleChange} />
    </div>
    
    • Props: In SolidJS, you use props to access the properties passed to your component from the parent component. In Svelte, you use export to declare the properties that your component expects from the parent component. For example:
    // SolidJS
    function Greeting(props) {
      return <p>Hello, {props.name}!</p>;
    }
    

    HTML

    <!-- Svelte -->
    <script>
      export let name;
    </script>
    
    <p>Hello, {name}!</p>
    
    • Events: In SolidJS, you use onClick, onInput, onChange, and other event handlers to listen to user interactions on your elements. In Svelte, you use on:click, on:input, on:change, and other event listeners to listen to user interactions on your elements. For example:
    // SolidJS
    function Button(props) {
      return <button onClick={props.onClick}>{props.label}</button>;
    }
    

    HTML

    <!-- Svelte -->
    <script>
      export let onClick;
      export let label;
    </script>
    
    <button on:click={onClick}>{label}</button>
    

    These are just some of the syntax differences between SolidJS and Svelte. You can find more information on Svelte syntax in the [official Svelte documentation]. I hope this helps! Let me know if you have any other questions.

    There is quite a lot of specific information in this response to I started to convert the code but didn’t understand the following:

    createEffect(() => {
        setIsMounted(true);
        // get cookie approval after component is mounted
        setCookies(getCookieConsent());
      });
    

    …so another question: “Convert the following solidjs code to svelte: plus the code above”. The response is both accurate and uncannily expands the example to include the complete code.

    To convert the following SolidJS code to Svelte, you can use the onMount lifecycle function from Svelte, which runs after the component is first rendered to the DOM. For example:

    // SolidJS
    import { createEffect } from "solid-js";
    
    function App() {
      const [isMounted, setIsMounted] = createSignal(false);
      const [cookies, setCookies] = createSignal(null);
    
      createEffect(() => {
        setIsMounted(true);
        // get cookie approval after component is mounted
        setCookies(getCookieConsent());
      });
    
      return (
        <div>
          <p>Is mounted: {isMounted() ? "Yes" : "No"}</p>
          <p>Cookies: {cookies()}</p>
        </div>
      );
    }
    

    HTML

    <!-- Svelte -->
    <script>
      import { onMount } from "svelte";
      let isMounted = false;
      let cookies = null;
    
      onMount(() => {
        isMounted = true;
        // get cookie approval after component is mounted
        cookies = getCookieConsent();
      });
    </script>
    
    <div>
      <p>Is mounted: {isMounted ? "Yes" : "No"}</p>
      <p>Cookies: {cookies}</p>
    </div>
    

    I hope this helps! Let me know if you have any other questions.

    This got me to the stage where I could convert the typescript part of of the code. Only the markup to go but some of it isn’t plain HTML, specifically the <Show> element. So I asked “What is the equivalent svelte construct to a solidjs <Show> element?“.

    The final response was all I needed.

    The equivalent Svelte construct to a SolidJS <Show> element is the {#if ...} block. The <Show> element in SolidJS is used to conditionally render a component based on a boolean expression. The {#if ...} block in Svelte does the same thing, but with a different syntax. For example:

    // SolidJS
    import { Show } from "solid-js/web";
    
    function App() {
      const [show, setShow] = createSignal(true);
    
      function toggle() {
        setShow(!show());
      }
    
      return (
        <div>
          <button onClick={toggle}>Toggle</button>
          <Show when={show()}>
            <p>This is shown when show is true</p>
          </Show>
        </div>
      );
    }
    

    HTML

    <!-- Svelte -->
    <script>
      let show = true;
    
      function toggle() {
        show = !show;
      }
    </script>
    
    <div>
      <button on:click={toggle}>Toggle</button>
      {#if show}
        <p>This is shown when show is true</p>
      {/if}
    </div>
    

    You can ask to convert the code in one go but I like being able to learn along the way. Asking GPT to break a problem down usually results in a better response.

    Final code

    The final code for the converted CookieConsent.svelte component looks like:

    <script lang="ts">
        declare function consentGranted(): void;
        declare function getCookieConsent(): string;
    
        import { onMount } from "svelte";
    
        let cookies = "unk";
        let isMounted = false;
        export let CookieConsent;
    
        const handleAccept = () => {
            cookies = "granted";
    
            // accepted cookie lasts for a year
            let d = new Date();
            let oneYear = new Date(d.getFullYear() + 1, d.getMonth(), d.getDate());
    
            document.cookie = "cookie-consent=granted; expires=" + oneYear + "; path=/";
            
            consentGranted();
        };
    
        const handleDecline = () => {
            cookies = "denied";
        
            // declined cookie only lasts for the session
            document.cookie = "cookie-consent=denied; path=/";
        };
    
      // this waits to load the cookie banner until the component is mounted
      // so that there is not a component flash
      onMount(() => {
            isMounted = true;
            // get cookie approval after component is mounted
            cookies = getCookieConsent();
        });
    
    </script>
    
    <!-- if there is no cookie for "cookie-consent", display the banner -->
    {#if isMounted}
        <div
        id="cookie-banner"
        class={`${
            cookies === "granted" || cookies === "denied" ? "hidden" : ""
        } fixed bottom-0 right-0 z-50 m-2 max-w-screen-sm rounded-lg border-2 border-slate-300 bg-purple-50 text-slate-800 shadow-xl`}
        >
        <div class="p-4 text-center">
            <p class="mb-4 text-sm sm:text-base">
            We use cookies to analyze our website and make your experience even
            better. To learn more, see our{" "}
            <a
                class="text-blue-600 underline hover:text-blue-700"
                href="/privacy/"
                target="_blank"
            >
                Privacy Policy.
            </a>
            </p>
    
            <div class="mx-auto">
            <button
                class="rounded-md bg-blue-600 p-2 text-white transition hover:bg-blue-700"
                on:click={handleAccept}
            >
                Accept
            </button>
            <button
                class="ml-2 rounded-md bg-transparent p-2 text-slate-600 transition hover:bg-gray-200"
                on:click={handleDecline}
            >
                Decline
            </button>
            </div>
        </div>
        </div>
    {/if}
    

    Footnotes

    1. If you didn’t see the popup then you may have an automatic blocker like Ghostery enabled.

    This entry was posted in code  and tagged #solidjs #svelte #typescript #gen-ai  on .
    Discuss this on Twitter or LinkedIn
  • Woman placing sticky notes on wall.

    Right now I’m reading “Agile Data Warehousing Project Management: Business Intelligence Systems Using Scrum” which I can heartily recommend. This article is about one quote in particular:

    Unfortunately, tracking actual hours spent on the individual tasks is ineffective, aims at the wrong objectives, and drowns the developers in detail while undermining agile’s pillar of self-organization that is so crucial to a team’s velocity. Tracking actuals should be strongly discouraged.

    I would go one step further and say tracking actuals can end up having a negative effect on your scrum project. Before I get into why its worth pointing out that for short periods of time it can be useful particularly if you need to gather data on where you are spending your time (see the second point below). Once you have the data though - stop recording.

    So why is tracking actuals so counterproductive? Primarily because it subverts the iterative estimation method.

    One of the key activities in a scrum process is to update the remaining time estimate every day. From this estimate a burn down is calculated and the burn down is then used to monitor and adjust the sprint in order to deliver.

    Consider what happens when scrum team members are logging the amount of time they worked on a task. Simple maths tells the remaining time is the current estimate minus the hours worked so there is a temptation to skip the re-estimating step. As a result a sprint burns down at a constant rate (ignoring task completion as a backup progress indicator) and inevitably it is not until the end of the sprint that underestimation is discovered; too late to do anything about it.

    This second point can be good or bad depending on management and team culture - if you log time correctly and in detail you will know where you are spending time including interruptions, meetings, etc. There are two types of response from the team:

    1. Look at all this waste activity we are doing - how can we remove it and spend more time on value add work?
    2. How can I possibly deliver on my sprint commitments - look at the other work I had to do during the sprint.

    Obviously you want the first response.

    Finally, overshooting sprints is something to be avoided but often there are additional constraints on time logging that cause you to miss estimate future sprints as well. I know of many organisations where team members are required to log a fixed number of hours a day; no more, no less. You can imagine the havoc this causes - if you work 5 or 15 hours during one day on a task but have to log 8 then you create an inaccurate data set from which to base future sprint planning on.

    Photo by Jason Goodman on Unsplash

    This entry was posted in agile  and tagged #estimation #scrum  on .
    Discuss this on Twitter or LinkedIn
  • Photo of Bournemouth Library taken on an angle in an architectural style.

    These seem to get longer and longer. A whole pile of links for you.

    Management and Organisational Behaviour

    How Serving Is Your Leadership? - Who is working for who here?

    Be a Manager - “The only reason there’s so many awful managers is that good people like you refuse to do the job.”

    I’m the Boss! Why Should I Care If You Like Me? - Because your team will be more productive… Here are some pointers.

    Software Development

    Technical debt 101 - Do you think you know what technical debt is and how to tackle it? Even so I’m sure this article has more you can discover and learn. A must read.

    Heisenberg Developers - So true. In fact this hits a little close to home since we use JIRA, the bug tracking tool mentioned in the article.

    What is Defensive Coding? - Many think that defensive coding is just making sure you handle errors correctly but that is a small part of the process.

    Need to Learn More about the Work You’re Doing? Spike It! - So you are an agile shop, your boss is demanding some story estimates and you have no idea how complex the piece of work is because it’s completely new. What do you do?

    Software Development with Feature Toggles - Don’t branch, toggle instead.

    Agile practices roundup - here are a number of articles I’ve found useful recently:

    How to review a merge commit- Phil dives into the misunderstood world of merge commits and reviews. Also see this list of things to look out for during code reviews.

    Functional Programming

    Don’t Be Scared Of Functional Programming - A good introduction to functional programming concepts using JavaScript as the demonstration language.

    Seamlessly integrating T-SQL and F# in the same code - The latest version of FSharp.Data allows you to write syntax checked SQL directly in your F# source and it executes as fast as Dapper.

    Railway Oriented Programming - This is a functional technique but I’ve recently been using it in C# when I needed to process many items in a sequence, any of which could fail and I want to collect all the errors up for reporting back to ops. It is harder to do in C# since there are no discriminated unions but a custom wrapper class is enough.

    Erlang and code style - A different language this time, Erlang. How easy is programming when you don’t have to code defensively and crashing is the preferred way of handling errors.

    Twenty six low-risk ways to use F# at work - Some great ways to get into F# programming without risking your current project.

    A proposal for a new C# syntax - A lovely way to look at writing C# using a familiar but lighter weight syntax. C#6 have some of these features planned but this goes further. Do check out the link at the end of the final proposal.

    Excel-DNA: Three Stories - Integrating F# into Excel - a data analysts dream…

    Data Warehousing

    Signs your Data Warehouse is Heading for the Boneyard - Some interesting things to look out for if you hold the purse strings to a data warehouse project. How many have you seen before?

    The 3 Big Lies of Data - I’ve heard these three lies over and over from business users and technology vendors alike. Who is kidding who?

    Six things I wish we had known about scaling - Not specifically about data warehouses but these are all issues we see on a regular basis.

    Why Hadoop Only Solves a Third of the Growing Pains for Big Data - You can’t just go and install a Hadoop cluster. There is more to it than that.

    Microsoft Azure Machine Learning - Finally it looks like we can have a simple way of doing cloud scale data mining.

    Data Visualization

    5 Tips to Good Vizzin’ - So many visualizations break these rules.

    Five indicators you aren’t using Tableau to its full potential - I’ve seen a few of these recently - tables anyone?

    Create a default Tableau Template - Should save some time when you have a pile of dashboards to create.

    Building a Tableau Center of Excellence - It is so easy to misunderstand Tableau which is not helped by a very effective sales team. This article has some great advice for introducing Tableau into your organisation.

    Beginner’s guide to R: Painless data visualization - Some simple R data visualization tips.

    Visualizing Data with D3 - If you need complete control over your visualization then D3 is just what you need. It can be pretty low-level but its easy to produce some amazing stuff with a bit of JavaScript programming.

    Testing

    I Don’t Have Time for Unit Testing - I’ve recently been guilt of this myself so I like to keep a reminder around - you will go faster if you write tests.

    Property Based Testing with FsCheck - FsCheck is a fantastic tool primarily used in testing F# code but there is no reason it can’t be used with C# too. It generates automated test cases to explore test boundaries. I love the concise nature of F# test code too especially with proper sentences for test names.

    Analysis Services

    I’ve collected a lot of useful links for Analysis Services, both tabular and multidimensional:

    DAX Patterns website - This website is my go-to resource for writing DAX calculations. These two are particularly useful:

    Using Tabular Models in a Large-scale Commercial Solution - Experiences of SSAS tabular in a large solution. Some tips, tricks and things to avoid.

    Also:

    This entry was posted in reference  and tagged #business-intelligence #data-visualization #data-warehouse #excel #functional-programming #tableau #testing  on .
    Discuss this on Twitter or LinkedIn
  • Photo of the old IMAX cinema on Bournemouth seafront.

    Latest links for easy consumption over the May long weekends – I missed out on March so have dropped some of the less interesting ones to keep the list short.

    Organisational Behaviour

    Programmers, Teach Non-Geeks The True Cost of Interruptions – a simple way to show to your boss how drive-by-management kills programmer productivity. Also work reading Maker’s Schedule, Manager’s Schedule which highlights the differences. If this is still a problem then this notice might be your only solution

    The Death Of Expertise – The Dunning-Kruger effect is often strong in semi-technical managers especially in industries where confidence plays a large part in success such as finance. This article discusses some of the problems related to treating all opinions as equal and ignoring experts.

    Save Your Software from the Start: Overcoming Skewed Thinking in the Project Planning Stage – Very simply, why we always underestimate the true complexity and cost of a project plus some tools to help overcome these psychological effects.

    Why Good Managers Are So Rare - Gallup finds that companies fail to choose the candidate with the right talent for the job 82% of the time. Managers account for at least 70% of variance in employee engagement scores across business units.

    I Give Up: Extroverted Barbarians at the Gates – Anyone remember the “perpendicular transparent red lines” video doing the rounds? This is an on-the-nail deconstruction of what is happening and why it happens. If you are an introvert then this other post might feel very familiar to you.

    Agile

    Coconut Headphones: Why Agile Has Failed – A rant about how modern agile methodologies seem to only consist of management practises. Take note of the end points to being successful.

    The death of agile? – Additional comment on the above. 

    Writing User Stories for Back-end Systems – The real functionality a user sees in a business intelligence project is quite small and can easily be described in a few words. This makes breaking up user stories into sprint sized chunks hard. This article gives some great advice that can be translated to BI projects. 

    Design Your Agile Project, Part 1 – So how do you pick the right kind of agile project? When should you use Kanban and when should you use Scrum? How is the business side of equation handled? Also Part 2, Part 3, and Part 4.

    Large Agile Framework Appropriate for Big, Lumbering Enterprises – A perfect solution to doing agile in finance organisations (wink). Love the concept of ‘Pair Managing’.

    Metrics that matter with evidence-based management – Its long but Martin does a great job looking at lots of the metrics in use today, why their use is limited and a far better approach to designing metrics that really help.

    Databases

    Is ETL Development doomed? – “Long term, the demand for ETL skills will decline”. The demand will mutate into one for more abstract ETL capabilities.

    Testing

    Intro to Unit Testing 9: Tips and Tricks – A handy list of tips that can make maintaining unit test code a little easier.

    FsCheck + XUnit = The Bomb – Even if you write code in C# it may be wise to think about writing unit tests in F# since the code is more concise, easier to read and with FxCheck can find things you might not.

    Data Visualization

    5 Tips to Good Vizzin’ – Should be required reading for anyone who is thinking about creating dashboards in Tableau.

    A Natural Approach to Analytics – This explains why using tools such as Tableau for largely static dashboards is a waste of time. Users need to interact with the data in a way they cannot do when relegated to dashboard consumers.

    Big Data/Hadoop

    Modern Financial Services Architectures Built with Hadoop – Hortonworks looks at big data in financial services.

    Beyond hadoop: fast queries from big data – I think Hadoop might be catching up here but it is still a bit of an elephant compared to SQL Server/Oracle etc when it comes to raw query performance.

    Don’t understand Big Data? Blame your genes! – 5 common errors for dealing with big data.

    The Parable of Google Flu: Traps in Big Data Analysis – Big data answers are not always correct. This paper looks at some of the pitfalls.

    No, Hadoop Isn’t Going To Replace Your Data Warehouse – More thoughts on modern data architectures and hybrid transactional/analytical processing.

    This entry was posted in reference  and tagged #apache-hadoop #business-intelligence #etl #sql-server-integration-services #ssis #tableau  on .
    Discuss this on Twitter or LinkedIn