<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Oli Howson]]></title><description><![CDATA[Lecturer in Computing, Researcher in Virtual Reality, Geek, Dad. And a little bit ginger.]]></description><link>https://badllama.net/</link><image><url>https://badllama.net/favicon.png</url><title>Oli Howson</title><link>https://badllama.net/</link></image><generator>Ghost 3.0</generator><lastBuildDate>Mon, 20 Apr 2026 01:35:13 GMT</lastBuildDate><atom:link href="https://badllama.net/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[The 1938 Raleigh Restoration]]></title><description><![CDATA[<p>I've been working on bikes for quite a while. I have a compatriot, James, and while we have very different approaches the partnership works.<br>Me: ummmm bike - get it - fix it - flog it or leave in the garden. Make pennies take way too much time.</p><p>James: ummmm</p>]]></description><link>https://badllama.net/the-1938-raleigh-restoration/</link><guid isPermaLink="false">689af8e1918aa0043db241bd</guid><dc:creator><![CDATA[Oli Howson]]></dc:creator><pubDate>Tue, 12 Aug 2025 08:40:05 GMT</pubDate><content:encoded><![CDATA[<p>I've been working on bikes for quite a while. I have a compatriot, James, and while we have very different approaches the partnership works.<br>Me: ummmm bike - get it - fix it - flog it or leave in the garden. Make pennies take way too much time.</p><p>James: ummmm bike - wash and flip. </p><p>He is profit oriented, I am waste my own time oriented.</p><p></p><p>Somehow I've got it into my head that we can amalgamate this by flipping modern bikes while I do a bit of a restoration on a vintage bike. I came across an ebay advert:</p><h1 id="rare-vintage-black-delivery-style-raleigh-bike-for-restoration"><strong><strong><strong>RARE! Vintage Black Delivery Style Raleigh Bike for restoration</strong></strong></strong></h1><figure class="kg-card kg-gallery-card kg-width-wide"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2025/08/s-l1600-Large.jpeg" width="1280" height="960"></div><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2025/08/s-l1600--8--Large.jpeg" width="960" height="1280"></div><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2025/08/s-l1600--7--Large.jpeg" width="960" height="1280"></div></div><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2025/08/s-l1600--6--Large.jpeg" width="960" height="1280"></div><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2025/08/s-l1600--5--Large.jpeg" width="960" height="1280"></div><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2025/08/s-l1600--4--Large.jpeg" width="960" height="1280"></div></div><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2025/08/s-l1600--3--Large.jpeg" width="960" height="1280"></div><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2025/08/s-l1600--1--Large.jpeg" width="960" height="1280"></div><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2025/08/s-l1600--2--Large.jpeg" width="960" height="1280"></div></div></div></figure><p>"It’s very old, possibly pre war. I’ve taken a picture of the hub head made by Sturmey Archer which gives some indication. The gear shift is not connected and I do not know if the gears operate or not. Everything else on the bicycle operates but needs a good clean up. It is a while since I tested it so the brakes might be less than roadworthy."</p><p>Well. I did a little bit of research, primarily based on the Sturmey-Archer hub, which has "AB-8" on it. From what I understand, the "AB" means it is a 3-speed hub with integrated brake. The -8 took a little more reading but it seems that a single-digit suffix was only used for a 9-year period. According to <a href="https://colwoodwheelworks.co.uk/sturmey-archer/sturmey-archer-hub-date-markings/">colwoodwheelworks</a> this means what we have here is a 1938 hub. And it's fair to assume the bike therefore is a 1938 model. </p><p>I then managed to find a <a href="https://icenicam.org.uk/library/Raleigh/Cycles_catalogue_1938.pdf">1938 Raleigh catalogue</a> online and only two models had the top bar mounted shifter, the <strong>Dawn Safety Tourist Model 20 </strong>and the <strong>Sports 'C' Tourist Model 38</strong>. The primary difference seems to be frame size, the Dawn being 22" and the Sports 'C' being 21". A quick measure and it seems ours is 21".</p><figure class="kg-card kg-image-card"><img src="https://badllama.net/content/images/2025/08/Screenshot-2025-08-07-at-23.28.37.png" class="kg-image"></figure><p>The only confusion being ours seems to have the Sturmey-Archer brake on the back like the 38X but the rim brakes on the front like the model 38. Perhaps the front wheel was changed, maybe it's a special build, it could even be a completely different model and I've got it all wrong!</p><p>After entering some discussion with Peter the lovely previous owner with a true gift for showing an interest in people, I mounted the bike into the rear seat of my wife's A5 cabrio (her having taken my estate car for the week) and brought it home in bits. </p><p>And that's how it is now. In bits, with some obvious first work to do:<br>- Remove the tinware for straightening<br>- Remove the chain for cleaning<br>- A general de-grease<br>- Replace the Sturmey-Archer gear cable.</p><p>Then I'll reassemble (probably sans the tinware for now) and see if it rides!</p><figure class="kg-card kg-gallery-card kg-width-wide"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2025/08/IMG_3497-Large.jpeg" width="960" height="1280"></div><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2025/08/IMG_3500-Large.jpeg" width="960" height="1280"></div><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2025/08/IMG_3496-Large.jpeg" width="960" height="1280"></div></div><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2025/08/IMG_3499-Large.jpeg" width="1280" height="960"></div><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2025/08/IMG_3495-Large.jpeg" width="1280" height="960"></div><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2025/08/IMG_3498-Large.jpeg" width="960" height="1280"></div></div></div></figure>]]></content:encoded></item><item><title><![CDATA[Prompts and Results]]></title><description><![CDATA[<p>This post is a companion to a book chapter I am working on. In the book chapter I am sharing a number of prompts used by students to use GenAI in supporting their learning. Unfortunately there is not room in the book chapter to include all of the outputs, so</p>]]></description><link>https://badllama.net/prompts-and-results/</link><guid isPermaLink="false">67bc9ff2b6378c041b2cf923</guid><dc:creator><![CDATA[Oli Howson]]></dc:creator><pubDate>Mon, 24 Feb 2025 16:48:32 GMT</pubDate><content:encoded><![CDATA[<p>This post is a companion to a book chapter I am working on. In the book chapter I am sharing a number of prompts used by students to use GenAI in supporting their learning. Unfortunately there is not room in the book chapter to include all of the outputs, so here they are.</p><hr><!--kg-card-begin: markdown--><h1 id="defeatingtheblankpage">Defeating the Blank Page</h1>
<h2 id="prompt">Prompt:</h2>
<p>I am doing an A-level in Computer Science. I am studying the AQA specification. My project, known as NEA or non-examined assessment, is a Python program to illustrate physics concepts for other students. I am taking a rapid application design approach to writing the program.</p>
<p>I have attached the NEA guidance document from the exam board.</p>
<p>I need a template for my NEA report. Please give me headings with as many levels of sub-headings as you feel appropriate.</p>
<h2 id="output">Output:</h2>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><style>
    .small-headers h1 { font-size: 1.5em; }
    .small-headers h2 { font-size: 1.2em; }
    .small-headers h3 { font-size: 1em; }
</style>
<div class="small-headers" style="border: 2px solid #ccc; margin: 20px; padding: 20px; background: #eee; font-size: 80%;">
    
    <h1>A-Level Computer Science NEA Report</h1>
    
    <h2>Project Title: [Insert Your Project Title Here]</h2>
    <h3>Candidate Name: [Your Name]</h3>
    <h3>Candidate Number: [Your Candidate Number]</h3>
    <h3>Centre Number: [Your Centre Number]</h3>
    <h3>Date of Submission: [Your Submission Date]</h3>

    <hr>

    <h2>1. Introduction</h2>
    <ul>
        <li>Overview of the NEA project</li>
        <li>Justification for project choice</li>
        <li>Target audience</li>
        <li>Objectives of the project</li>
        <li>Overview of the report structure</li>
    </ul>

    <hr>

    <h2>2. Analysis (9 marks)</h2>

    <h3>2.1 Understanding the Problem</h3>
    <ul>
        <li>Description of the problem domain</li>
        <li>Purpose of the project</li>
        <li>Real-world relevance</li>
        <li>Scope and limitations of the project</li>
    </ul>

    <h3>2.2 Research & Investigation</h3>
    <ul>
        <li>Methods used to research the problem</li>
        <li>Background research on similar solutions</li>
        <li>Data sources and information gathering</li>
    </ul>

    <h3>2.3 End User and Stakeholder Analysis</h3>
    <ul>
        <li>Identification of a third party (teacher, expert, potential user)</li>
        <li>Requirements gathered from discussions/questionnaires</li>
    </ul>

    <h3>2.4 Objectives of the Project</h3>
    <ul>
        <li>Measurable and testable objectives</li>
        <li>Primary objectives (core functionality)</li>
        <li>Extension objectives (additional features)</li>
        <li>Success criteria (how objectives will be validated)</li>
    </ul>

    <h3>2.5 Feasibility and Critical Path Analysis</h3>
    <ul>
        <li>Key challenges and constraints</li>
        <li>Technical feasibility assessment</li>
        <li>Timeline and milestone planning</li>
    </ul>

    <hr>

    <h2>3. Documented Design (12 marks)</h2>

    <h3>3.1 High-Level System Overview</h3>
    <ul>
        <li>System architecture diagram</li>
        <li>Description of different system components</li>
        <li>Data flow within the system</li>
    </ul>

    <h3>3.2 Algorithm Design</h3>
    <ul>
        <li>Description of key algorithms</li>
        <li>Flowcharts or pseudocode for main algorithms</li>
        <li>Explanation of how algorithms solve the problem</li>
    </ul>

    <h3>3.3 Data Structures and Storage</h3>
    <ul>
        <li>Variables and data structures used</li>
        <li>Justification for choice of data structures</li>
        <li>File handling and database design (if applicable)</li>
        <li>ER diagrams or file structures</li>
    </ul>

    <h3>3.4 User Interface Design</h3>
    <ul>
        <li>Wireframes or mockups of user interface</li>
        <li>Explanation of user interactions</li>
        <li>Accessibility considerations</li>
    </ul>

    <h3>3.5 Security and Integrity Considerations</h3>
    <ul>
        <li>Data validation and error handling</li>
        <li>Security measures (e.g., input validation, authentication)</li>
        <li>Encryption methods (if applicable)</li>
    </ul>

    <h3>3.6 Hardware and Software Considerations</h3>
    <ul>
        <li>Development environment</li>
        <li>Hardware requirements</li>
        <li>Software dependencies and libraries</li>
    </ul>

    <hr>

    <h2>4. Technical Solution (42 marks)</h2>

    <h3>4.1 Implementation Overview</h3>
    <ul>
        <li>Programming language and libraries used</li>
        <li>Development approach (e.g., rapid application development, agile)</li>
        <li>Version control (if used)</li>
    </ul>

    <h3>4.2 Code Structure and Organization</h3>
    <ul>
        <li>Modular structure of the code</li>
        <li>Key classes, functions, and methods</li>
        <li>Code snippets with explanations</li>
    </ul>

    <h3>4.3 Achieving Project Objectives</h3>
    <ul>
        <li>Mapping code implementation to project objectives</li>
        <li>Explanation of how each feature was implemented</li>
    </ul>

    <h3>4.4 Advanced Techniques Used</h3>
    <ul>
        <li>Explanation of complex programming techniques used</li>
        <li>Use of external APIs or advanced algorithms</li>
        <li>Performance optimizations</li>
    </ul>

    <h3>4.5 Challenges and Problem-Solving</h3>
    <ul>
        <li>Technical challenges faced</li>
        <li>How problems were identified and resolved</li>
    </ul>

    <hr>

    <h2>5. Testing (8 marks)</h2>

    <h3>5.1 Testing Strategy</h3>
    <ul>
        <li>Explanation of testing methodology</li>
        <li>Types of testing used (unit testing, integration testing, system testing)</li>
    </ul>

    <h3>5.2 Test Plan</h3>
    <ul>
        <li>Table of test cases</li>
        <li>Expected vs. actual results</li>
        <li>Screenshots or logs of test execution</li>
    </ul>

    <h3>5.3 Debugging and Fixing Issues</h3>
    <ul>
        <li>Description of major bugs encountered</li>
        <li>Steps taken to resolve them</li>
    </ul>

    <h3>5.4 User Testing and Feedback</h3>
    <ul>
        <li>Summary of feedback from the third party</li>
        <li>Usability testing results</li>
        <li>Improvements made based on feedback</li>
    </ul>

    <hr>

    <h2>6. Evaluation (4 marks)</h2>

    <h3>6.1 Comparison Against Objectives</h3>
    <ul>
        <li>Analysis of how well the project met the original objectives</li>
        <li>Explanation of any objectives not met and reasons why</li>
    </ul>

    <h3>6.2 Reflection on Project Development</h3>
    <ul>
        <li>Strengths of the solution</li>
        <li>Weaknesses and areas for improvement</li>
        <li>Lessons learned</li>
    </ul>

    <h3>6.3 Future Enhancements</h3>
    <ul>
        <li>Possible extensions or additional features</li>
        <li>Suggestions for further development</li>
    </ul>

    <h3>6.4 Third-Party Feedback and Analysis</h3>
    <ul>
        <li>Review of stakeholder feedback</li>
        <li>Discussion of suggestions for improvement</li>
    </ul>

    <hr>

    <h2>7. Appendices</h2>
    <ul>
        <li>Full source code (or link to GitHub repository if applicable)</li>
        <li>Additional test evidence</li>
        <li>User feedback forms</li>
        <li>Additional diagrams or research notes</li>
    </ul>
</div><!--kg-card-end: html--><!--kg-card-begin: markdown--><h2 id="prompt">Prompt:</h2>
<p>How should I frame my &quot;Overview of the NEA project&quot;?</p>
<h2 id="output">Output:</h2>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><style>
    .small-headers h1 { font-size: 1.5em; }
    .small-headers h2 { font-size: 1.2em; }
    .small-headers h3 { font-size: 1em; }
</style>
<div class="small-headers" style="border: 2px solid #ccc; margin: 20px; padding: 20px; background: #eee; font-size: 80%;">
<p>
Your "Overview of the NEA project" should be a concise introduction that sets the context for your project. It should clearly explain <strong>what</strong> the project is about, <strong>why</strong> you chose it, and <strong>who it is for</strong>. Since your project is a <strong>Python program to illustrate physics concepts for other students</strong>, and you're using <strong>rapid application design</strong>, here’s a structured way to frame it:
    </p>

    
<h2>Overview of the NEA Project</h2>

<p>
    This project is a <strong>Python-based educational tool</strong> designed to help 
    <strong>A-level students understand key physics concepts through interactive simulations and visualizations</strong>. 
    The goal is to provide an intuitive and engaging way for students to explore physics topics that may be difficult 
    to grasp through traditional methods.
</p>

<p>
    The project follows a <strong>rapid application design (RAD) approach</strong>, which emphasizes 
    <strong>iterative development, prototyping, and user feedback</strong> to refine the software efficiently. 
    This approach ensures that the tool remains user-friendly and effectively meets the needs of its target audience.
</p>

<p>
    By developing this software, I aim to <strong>enhance learning through interactive demonstrations</strong>, 
    making abstract physics principles more accessible and engaging for students. The final product will include 
    <strong>real-time simulations, graphical representations, and interactive elements</strong> that allow students 
    to manipulate variables and observe their effects.
</p>

<p>
    The project will be evaluated based on its <strong>accuracy in illustrating physics concepts, usability, 
    and the effectiveness of its design in supporting student learning</strong>.
</p>
    
<p>This overview effectively:
<ul>
    <li>Defines the <strong>purpose</strong> of the project.</li>
    <li>Identifies the <strong>target audience.</strong></li>
    <li>Explains the <strong>development approach.</strong></li>
    <li>Highlights <strong>key features.</strong></li>
    <li>Sets the <strong>evaluation criteria.</strong></li>
</ul>
</p>
</div><!--kg-card-end: html--><!--kg-card-begin: markdown--><h1 id="summarisingknuth">Summarising Knuth</h1>
<h2 id="prompt">Prompt:</h2>
<p>I'm an undergraduate Computer Science student. I am struggling to understand the attached document. Summarise the concepts in terms I can understand.</p>
<p><strong>Note</strong>: The GPT was provided with a copy of a <a href="https://www-cs-faculty.stanford.edu/~knuth/fasc12a+.pdf">Knuth preprint</a></p>
<h2 id="output">Output:</h2>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><style>
    .small-headers h1 { font-size: 1.5em; }
    .small-headers h2 { font-size: 1.2em; }
    .small-headers h3 { font-size: 1em; }
</style>
<div class="small-headers" style="border: 2px solid #ccc; margin: 20px; padding: 20px; background: #eee; font-size: 80%;">
    <h1>Understanding Depth-First Search (DFS) and Tarjan’s Algorithm</h1>
        
        <h2>1. Depth-First Search (DFS)</h2>
        <p>Depth-First Search (DFS) is a graph traversal algorithm that explores as far as possible along each branch before backtracking. It uses a <strong>stack</strong> (either explicitly or through recursion) to track its path.</p>
        
        <h2>2. Algorithm Q (Quick Digraph Search)</h2>
        <p>Algorithm Q is a simple method for traversing a directed graph. It:</p>
        <ul>
            <li>Visits every vertex and edge.</li>
            <li>Uses a <strong>stack</strong> to ensure each vertex is visited only once.</li>
            <li>Is efficient but does not structure traversal data in a useful way for further graph analysis.</li>
        </ul>
        
        <h2>3. Algorithm D (Depth-First Search)</h2>
        <p>Algorithm D improves on Algorithm Q by constructing a <strong>spanning tree</strong> as it traverses the graph. Each node receives:</p>
        <ul>
            <li><strong>Preorder number (PRE):</strong> The order in which the node is first visited.</li>
            <li><strong>Postorder number (POST):</strong> The order in which the node is finished being explored.</li>
        </ul>
        
        <h2>4. Types of Graph Edges in DFS</h2>
        <p>DFS classifies edges into different types:</p>
        <ul>
            <li><strong>Tree edges:</strong> Part of the DFS tree.</li>
            <li><strong>Back edges:</strong> Connect a node to one of its ancestors (indicating a cycle).</li>
            <li><strong>Forward edges:</strong> Connect a node to one of its descendants but are not tree edges.</li>
            <li><strong>Cross edges:</strong> Connect unrelated nodes (neither ancestors nor descendants).</li>
        </ul>
        
        <h2>5. Strongly Connected Components (SCCs)</h2>
        <p>An SCC is a group of nodes where each node can reach every other node in the group. DFS helps find SCCs efficiently.</p>
        
        <h2>6. Tarjan’s Algorithm</h2>
        <p>Tarjan’s Algorithm finds SCCs using DFS with <strong>lowpoint values (LOW)</strong>, which track the smallest reachable node in a DFS subtree. It operates in <code>O(V + E)</code> time and efficiently detects SCCs while traversing the graph.</p>
        
        <h2>7. Weakly Connected Components</h2>
        <p>Weakly connected components are groups of nodes that remain connected when edge directions are ignored. These form a <strong>topological order</strong>, meaning edges only point forward in a directed acyclic graph (DAG).</p>
        
        <h2>Conclusion</h2>
        <p>Depth-First Search (DFS) is a powerful graph traversal technique that forms the foundation of many graph algorithms. Tarjan’s Algorithm extends DFS to find SCCs efficiently, helping analyze graph structures in applications like network connectivity, dependency resolution, and web crawling.</p>

</div><!--kg-card-end: html--><!--kg-card-begin: markdown--><h1 id="alittlemoreknuth">A Little More Knuth</h1>
<h2 id="prompt">Prompt:</h2>
<p>Please go into more detail summarising algorithm Q according to Knuth's paper.</p>
<h2 id="output">Output:</h2>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><style>
    .small-headers h1 { font-size: 1.5em; }
    .small-headers h2 { font-size: 1.2em; }
    .small-headers h3 { font-size: 1em; }
</style>
<div class="small-headers" style="border: 2px solid #ccc; margin: 20px; padding: 20px; background: #eee; font-size: 80%;"><h1>Understanding Depth-First Search (DFS) and Tarjan’s Algorithm</h1>
        
        <h2>1. Depth-First Search (DFS)</h2>
        <p>Depth-First Search (DFS) is a graph traversal algorithm that explores as far as possible along each branch before backtracking. It uses a <strong>stack</strong> (either explicitly or through recursion) to track its path.</p>
        
        <h2>2. Algorithm Q (Quick Digraph Search)</h2>
        <p>Algorithm Q, as described by Donald Knuth, is a simple yet efficient method for traversing directed graphs. It ensures that every vertex and arc is visited while minimizing memory operations. The algorithm operates using a stack to keep track of nodes that need to be explored further, reducing the need to maintain extensive auxiliary structures.</p>
        <p>The core steps of Algorithm Q are:</p>
        <ul>
            <li><strong>Initialization:</strong> Every vertex is marked as unvisited, and a special sentinel value is used to track stack elements.</li>
            <li><strong>Traversal:</strong> The algorithm begins at the last vertex and moves backward, skipping any already visited nodes.</li>
            <li><strong>Exploration:</strong> When a new vertex is encountered, it is pushed onto the stack, and its outgoing edges are processed.</li>
            <li><strong>Stack Management:</strong> The algorithm ensures that vertices are not added to the stack more than once, using the stack links to track previously visited nodes.</li>
            <li><strong>Completion:</strong> If no more vertices remain to be explored, the algorithm terminates.</li>
        </ul>
        <p>One key feature of Algorithm Q is that it efficiently visits every vertex and arc of a graph while ensuring minimal redundant memory accesses. Knuth notes that the algorithm performs fewer than <code>3m + 5n</code> memory operations, where <code>m</code> is the number of arcs and <code>n</code> is the number of vertices. However, despite its speed, it lacks the structured traversal properties of depth-first search, making it less useful for applications requiring spanning trees or topological ordering.</p>
        
        <h2>3. Algorithm D (Depth-First Search)</h2>
        <p>Algorithm D improves on Algorithm Q by constructing a <strong>spanning tree</strong> as it traverses the graph. Each node receives:</p>
        <ul>
            <li><strong>Preorder number (PRE):</strong> The order in which the node is first visited.</li>
            <li><strong>Postorder number (POST):</strong> The order in which the node is finished being explored.</li>
        </ul>
        
        <h2>4. Types of Graph Edges in DFS</h2>
        <p>DFS classifies edges into different types:</p>
        <ul>
            <li><strong>Tree edges:</strong> Part of the DFS tree.</li>
            <li><strong>Back edges:</strong> Connect a node to one of its ancestors (indicating a cycle).</li>
            <li><strong>Forward edges:</strong> Connect a node to one of its descendants but are not tree edges.</li>
            <li><strong>Cross edges:</strong> Connect unrelated nodes (neither ancestors nor descendants).</li>
        </ul>
</div><!--kg-card-end: html--><!--kg-card-begin: markdown--><h1 id="knuthforsevenyearolds">Knuth for Seven Year Olds</h1>
<h2 id="prompt">Prompt:</h2>
<p>I'm still struggling. Explain algorithm Q as if I am a seven year old that knows nothing about Computer Science.</p>
<h2 id="output">Output:</h2>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><style>
    .small-headers h1 { font-size: 1.5em; }
    .small-headers h2 { font-size: 1.2em; }
    .small-headers h3 { font-size: 1em; }
</style>
<div class="small-headers" style="border: 2px solid #ccc; margin: 20px; padding: 20px; background: #eee; font-size: 80%;">
    <h1>Understanding Algorithm Q: A Simple Explanation</h1>
    
    <h2>Explaining Algorithm Q Like You’re 7 Years Old</h2>
    <p>Imagine you are in a big castle with lots of rooms and secret passages. Your job is to explore every room and every passage without getting lost or visiting the same room twice.</p>
    
    <h3>How Algorithm Q Works (Like a Castle Adventure Game!)</h3>
    <ol>
        <li><strong>Start at the Last Room:</strong> You begin at the very last room in the castle (because that’s how Algorithm Q works). You want to check every passage that leads from that room to other rooms.</li>
        <li><strong>Use a Backpack (The Stack!):</strong> You carry a magical backpack where you can put the names of rooms you need to check later. But you <strong>only put a room in once</strong>—if it’s already in your backpack, you skip it.</li>
        <li><strong>Follow a Passage and Mark the Room:</strong> When you enter a new room, you put a mark on the wall so you don’t enter it again by accident.</li>
        <li><strong>Check Every Passage:</strong>
            <ul>
                <li>If a passage leads to a new room, you add it to your backpack and go there next.</li>
                <li>If all the passages from a room have been checked, you take the last room out of your backpack and go back there.</li>
            </ul>
        </li>
        <li><strong>Keep Going Until the Whole Castle is Explored!</strong> Once every room has been checked and all passages have been walked through, your adventure is done!</li>
    </ol>
    
    <h3>Why This is Clever</h3>
    <ul>
        <li>You <strong>never visit the same room twice unnecessarily</strong>, so you don’t waste time.</li>
        <li>You <strong>don’t need a giant map</strong>, just your backpack to remember rooms you haven’t fully checked yet.</li>
        <li>It works <strong>quickly</strong>, checking every passage only a few times.</li>
    </ul>
    <p>But this method <strong>doesn’t</strong> organize the rooms in a structured way, which is why <strong>Algorithm D (Depth-First Search)</strong> is better when you need to build a map of how everything connects.</p>
</div><!--kg-card-end: html--><!--kg-card-begin: markdown--><h1 id="amirightinthinking">Am I right in thinking...</h1>
<h2 id="prompt">Prompt:</h2>
<p>I am studying Computer Science. I am covering complexity. In terms of time complexity, am I right in thinking that big-oh complexity tells me the worst case complexity and big-theta tells me the exact complexity?</p>
<h2 id="output">Output:</h2>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><style>
    .small-headers h1 { font-size: 1.5em; }
    .small-headers h2 { font-size: 1.2em; }
    .small-headers h3 { font-size: 1em; }
</style>
<div class="small-headers" style="border: 2px solid #ccc; margin: 20px; padding: 20px; background: #eee; font-size: 80%;">
    <h2>Understanding Big-O and Big-Theta Complexity</h2>

<p>Yes, you're mostly correct in your understanding of Big-O and Big-Theta notation, but let's clarify the distinctions:</p>

<ul>
  <li><strong>Big-O (O)</strong> notation describes an <em>upper bound</em> on the time complexity of an algorithm. It represents the worst-case scenario but does not necessarily indicate the tightest bound. It essentially tells you that the algorithm will not perform worse than the given complexity in the worst case.</li>
  <li><strong>Big-Theta (Θ)</strong> notation describes a <em>tight bound</em>, meaning it gives both an upper and lower bound on the complexity. If an algorithm is Θ(f(n)), it means that for large enough inputs, its running time grows asymptotically at the same rate as f(n), both in the worst and best cases.</li>
</ul>

<p>So while <strong>Big-O represents worst-case complexity</strong>, <strong>Big-Theta gives the exact asymptotic complexity</strong> (when upper and lower bounds match).</p>

</div><!--kg-card-end: html--><!--kg-card-begin: markdown--><h1 id="amireallyrightinthinking">Am I <em>really</em> right in thinking...</h1>
<h2 id="prompt">Prompt:</h2>
<p>Is there anything else about this I might have misunderstood?</p>
<h2 id="output">Output:</h2>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><style>
    .small-headers h1 { font-size: 1.5em; }
    .small-headers h2 { font-size: 1.2em; }
    .small-headers h3 { font-size: 1em; }
</style>
<div class="small-headers" style="border: 2px solid #ccc; margin: 20px; padding: 20px; background: #eee; font-size: 80%;">
    <p>You're on the right track, but there are a few common misconceptions about asymptotic complexity that might be useful to clarify:</p>

<h3>1. Big-O Does Not Always Mean Worst-Case Complexity</h3>
<p>While Big-O is often <em>used</em> to describe worst-case complexity, it is actually just an upper bound. It can apply to worst-case, best-case, or average-case complexity.</p>
<p><strong>Example:</strong> The <em>insertion sort</em> algorithm has a worst-case time complexity of <code>O(n²)</code> (when the input is reversed) but a best-case complexity of <code>O(n)</code> (when the input is already sorted).</p>

<h3>2. Big-Theta (Θ) Does Not Mean "Exact Complexity" in a Strict Sense</h3>
<p>Big-Theta gives a tight bound, meaning the function grows <em>asymptotically</em> at the same rate as <code>f(n)</code>, but it doesn’t mean the <em>exact running time</em> (e.g., including constant factors or lower-order terms).</p>
<p>If an algorithm’s runtime is <code>3n² + 5n + 7</code>, it is <code>Θ(n²)</code>, but its <em>exact</em> running time depends on those coefficients.</p>

<h3>3. Big-O vs. Big-Ω (Omega)</h3>
<ul>
  <li><strong>Big-O (O)</strong> gives an <em>upper</em> bound (worst-case performance or limit).</li>
  <li><strong>Big-Ω (Ω)</strong> gives a <em>lower</em> bound (best-case performance or guaranteed minimum).</li>
  <li><strong>Big-Theta (Θ)</strong> applies when an algorithm’s complexity has both an upper and lower bound that match.</li>
</ul>

<p><strong>Example:</strong></p>
<ul>
  <li><strong>Merge Sort:</strong> <code>O(n log n)</code> (worst-case) and <code>Ω(n log n)</code> (best-case), so it is <code>Θ(n log n)</code>.</li>
  <li><strong>Bubble Sort:</strong> <code>O(n²)</code> (worst-case), but <code>Ω(n)</code> (best-case if the list is already sorted).</li>
</ul>

<h3>4. "Big-O vs. Small-o" Notation</h3>
<ul>
  <li><strong>Big-O (O(f(n)))</strong> means the function <em>grows at most</em> as fast as <code>f(n)</code> (upper bound, possibly tight).</li>
  <li><strong>Small-o (o(f(n)))</strong> means the function grows <em>strictly slower</em> than <code>f(n)</code> (not tight).</li>
</ul>

<p><strong>Example:</strong> <code>n² + n = O(n²)</code>, but it is <em>not</em> <code>o(n²)</code>, since <code>n² + n</code> still grows at <code>Θ(n²)</code>.</p>

</div>
<!--kg-card-end: html--><!--kg-card-begin: markdown--><h1 id="debuggingcode">Debugging Code</h1>
<h2 id="prompt">Prompt:</h2>
<p>My program is supposed to count down from 10 to a number I input, but it is stopping one above the question I input. For example, if I input 4 it counts down from 10 to 5. What do I need to do to fix this?</p>
<h3 id="codefileprovided">Code File Provided:</h3>
<pre><code># problem 1

countDownTo = int(input('What would you like to count down to? '))
for i in range(10,countDownTo,-1):
    print('I count...',i)
</code></pre>
<h2 id="output">Output:</h2>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><style>
    .small-headers h1 { font-size: 1.5em; }
    .small-headers h2 { font-size: 1.2em; }
    .small-headers h3 { font-size: 1em; }
</style>
<div class="small-headers" style="border: 2px solid #ccc; margin: 20px; padding: 20px; background: #eee; font-size: 80%;">
<h1>Fixing a Countdown Loop in Python</h1>

<p>Your issue is with the <code>range()</code> function in your for loop:</p>

<pre>
<code>
<span style="color:blue;">countDownTo</span> = <span style="color:red;">int</span>(<span style="color:green;">input</span>('What would you like to count down to? '))
<span style="color:red;">for</span> i <span style="color:red;">in</span> <span style="color:green;">range</span>(10, countDownTo, -1):
    <span style="color:green;">print</span>('I count...', i)
</code>
</pre>

<h2>Explanation:</h2>
<ul>
    <li>The <code>range(start, stop, step)</code> function generates numbers starting from <code>start</code>, decreasing by <code>step</code> each time, and stopping <strong>before reaching</strong> <code>stop</code>.</li>
    <li>In your case, <code>start = 10</code>, <code>step = -1</code>, and <code>stop = countDownTo</code>, meaning it will count down <strong>until it reaches a value just above</strong> <code>countDownTo</code>, but not including it.</li>
</ul>

<h2>Solution:</h2>
<p>You need to modify the <code>range()</code> function to include <code>countDownTo</code> in the sequence. You can do this by setting <code>stop = countDownTo - 1</code>, like this:</p>

<pre>
<code>
<span style="color:red;">for</span> i <span style="color:red;">in</span> <span style="color:green;">range</span>(10, countDownTo - 1, -1):
</code>
</pre>

<h2>Fixed Code:</h2>
<pre>
<code>
<span style="color:blue;">countDownTo</span> = <span style="color:red;">int</span>(<span style="color:green;">input</span>('What would you like to count down to? '))
<span style="color:red;">for</span> i <span style="color:red;">in</span> <span style="color:green;">range</span>(10, countDownTo - 1, -1):  <span style="color:gray;"># Adjust stop value</span>
    <span style="color:green;">print</span>('I count...', i)
</code>
</pre>

<h2>Expected Output:</h2>
<p>Now, if you input <code>4</code>, the output will correctly be:</p>

<pre>
<code>
I count... 10
I count... 9
I count... 8
I count... 7
I count... 6
I count... 5
I count... 4
</code>
</pre>

<p>Let me know if you need further clarification! 🚀</p>

</div><!--kg-card-end: html--><!--kg-card-begin: markdown--><h1 id="debuggingcodewithoutthefix">Debugging Code Without the Fix</h1>
<h2 id="prompt">Prompt:</h2>
<p>My program is supposed to count down from 10 to a number I input, but it is stopping one above the question I input. For example, if I input 4 it counts down from 10 to 5. What do I need to do to fix this? Please explain what I have done wrong but do not fix my code, I want to figure that bit out myself.</p>
<h3 id="codefileprovided">Code File Provided:</h3>
<pre><code># problem 1

countDownTo = int(input('What would you like to count down to? '))
for i in range(10,countDownTo,-1):
    print('I count...',i)
</code></pre>
<h2 id="output">Output:</h2>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><style>
    .small-headers h1 { font-size: 1.5em; }
    .small-headers h2 { font-size: 1.2em; }
    .small-headers h3 { font-size: 1em; }
</style>
<div class="small-headers" style="border: 2px solid #ccc; margin: 20px; padding: 20px; background: #eee; font-size: 80%;">
<p>Your issue is caused by the way the <span style="color:blue;">range()</span> function works in Python. The <span style="color:blue;">range(start, stop, step)</span> function generates numbers starting from <span style="color:green;">start</span> and decreasing by <span style="color:green;">step</span> until it <strong>reaches but does not include</strong> <span style="color:green;">stop</span>.</p>

<p>In your code:</p>
<pre>
<span style="color:blue;">for</span> <span style="color:purple;">i</span> <span style="color:blue;">in</span> <span style="color:blue;">range</span>(<span style="color:red;">10</span>, <span style="color:purple;">countDownTo</span>, <span style="color:red;">-1</span>):
    <span style="color:blue;">print</span>(<span style="color:orange;">'I count...'</span>, <span style="color:purple;">i</span>)
</pre>

<ul>
  <li><strong>start</strong> = <span style="color:red;">10</span></li>
  <li><strong>stop</strong> = <span style="color:purple;">countDownTo</span></li>
  <li><strong>step</strong> = <span style="color:red;">-1</span></li>
</ul>

<p>The key problem is that <span style="color:blue;">range()</span> stops <strong>before</strong> reaching <span style="color:purple;">countDownTo</span>. That means if <span style="color:purple;">countDownTo</span> = <span style="color:red;">4</span>, <span style="color:blue;">range</span>(<span style="color:red;">10</span>, <span style="color:red;">4</span>, <span style="color:red;">-1</span>) generates <span style="color:green;">[10, 9, 8, 7, 6, 5]</span>, stopping <strong>before</strong> 4.</p>

<p>To fix this, you need to adjust your <span style="color:green;">stop</span> value in <span style="color:blue;">range()</span>. Now, it's your turn to figure out how to modify it so that the loop includes <span style="color:purple;">countDownTo</span>.</p>
</div><!--kg-card-end: html--><!--kg-card-begin: markdown--><h1 id="debuggingcodesimplepromptandmultipleproblems">Debugging Code - Simple prompt and multiple problems</h1>
<h2 id="prompt">Prompt:</h2>
<p>My program doesn't work properly. What's wrong with it?</p>
<h3 id="codefileprovided">Code File Provided:</h3>
<pre><code># problem 2

countDownTo = input('What would you like to count down to? '
for i in range(10,countDownTo,-1):
    print('I count...',i)
</code></pre>
<h2 id="output">Output:</h2>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><style>
    .small-headers h1 { font-size: 1.5em; }
    .small-headers h2 { font-size: 1.2em; }
    .small-headers h3 { font-size: 1em; }
</style>
<div class="small-headers" style="border: 2px solid #ccc; margin: 20px; padding: 20px; background: #eee; font-size: 80%;">
    
 <span>There are a couple of issues with your code:</span>

<span><strong>1. Syntax Error:</strong></span>  
<ul>
<li>Your <span>input</span> statement is missing a closing parenthesis. It should be:</li>
</ul>
<pre>
<span>countDownTo</span> <span>=</span> <span>input</span><span>(</span><span>'What would you like to count down to? '</span><span>)</span>
</pre>

<span><strong>2. Type Error:</strong></span>  
<ul>
<li>The <span>input</span> function returns a string, but you are using it as an integer in the <span>range</span> function.</li>
<li>You need to convert it to an integer using <span>int()</span>:</li>
</ul>
<pre>
<span>countDownTo</span> <span>=</span> <span>int</span><span>(</span><span>input</span><span>(</span><span>'What would you like to count down to? '</span><span>)</span><span>)</span>
</pre>

<span><strong>3. Incorrect Range Logic:</strong></span>  
<ul>
<li>The <span>range</span> function is structured as <span>range(start, stop, step)</span>, but your step is <span>-1</span>, meaning it will count down.</li>
<li>The loop should be:</li>
</ul>
<pre>
<span>for</span> <span>i</span> <span>in</span> <span>range</span><span>(</span><span>10</span><span>,</span> <span>countDownTo</span> <span>-</span> <span>1</span><span>,</span> <span>-1</span><span>)</span><span>:</span>
</pre>
<ul>
<li>This ensures it includes <span>countDownTo</span>.</li>
</ul>

<span><strong>Corrected Code:</strong></span>
<pre>
<span>countDownTo</span> <span>=</span> <span>int</span><span>(</span><span>input</span><span>(</span><span>'What would you like to count down to? '</span><span>)</span><span>)</span>

<span>for</span> <span>i</span> <span>in</span> <span>range</span><span>(</span><span>10</span><span>,</span> <span>countDownTo</span> <span>-</span> <span>1</span><span>,</span> <span>-1</span><span>)</span><span>:</span>
    <span>print</span><span>(</span><span>'I count...'</span><span>,</span> <span>i</span><span>)</span>
</pre>

<span>This should work correctly. Let me know if you need further adjustments! 🚀</span>

    
</div><!--kg-card-end: html--><!--kg-card-begin: markdown--><h1 id="quizquestions">Quiz Questions</h1>
<h2 id="prompt">Prompt:</h2>
<p>I am an A-level student studying AQA Computer Science. Please quiz me on networks.</p>
<h2 id="output">Output:</h2>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><style>
    .small-headers h1 { font-size: 1.5em; }
    .small-headers h2 { font-size: 1.2em; }
    .small-headers h3 { font-size: 1em; }
</style>
<div class="small-headers" style="border: 2px solid #ccc; margin: 20px; padding: 20px; background: #eee; font-size: 80%;">
    <h2>Quiz on Networks (AQA A-Level Computer Science)</h2>

<h3>Multiple Choice Questions</h3>
<ol>
    <li><strong>What is the main function of a router in a network?</strong>
        <ul>
            <li>a) Assign IP addresses to devices</li>
            <li>b) Connect multiple networks and direct data packets</li>
            <li>c) Convert digital signals to analog</li>
            <li>d) Control data access in a network</li>
        </ul>
    </li>

    <li><strong>Which protocol is responsible for breaking messages into packets for transmission over a network?</strong>
        <ul>
            <li>a) TCP</li>
            <li>b) IP</li>
            <li>c) FTP</li>
            <li>d) HTTP</li>
        </ul>
    </li>

    <li><strong>Which of the following is an example of a protocol used for email transmission?</strong>
        <ul>
            <li>a) SMTP</li>
            <li>b) HTTP</li>
            <li>c) SSH</li>
            <li>d) UDP</li>
        </ul>
    </li>

    <li><strong>What does DNS stand for?</strong>
        <ul>
            <li>a) Data Network Service</li>
            <li>b) Domain Name System</li>
            <li>c) Digital Naming Structure</li>
            <li>d) Distributed Network Security</li>
        </ul>
    </li>

    <li><strong>What type of network topology is characterized by a central hub that connects all devices?</strong>
        <ul>
            <li>a) Ring</li>
            <li>b) Mesh</li>
            <li>c) Star</li>
            <li>d) Bus</li>
        </ul>
    </li>
</ol>

<h3>True or False</h3>
<ol>
    <li>A <strong>MAC address</strong> is assigned dynamically to a device by the router. <strong>(True/False)</strong></li>
    <li>A <strong>VPN</strong> (Virtual Private Network) encrypts data for secure communication over an insecure network. <strong>(True/False)</strong></li>
    <li><strong>IPv4</strong> uses 128-bit addresses, making it more secure than IPv6. <strong>(True/False)</strong></li>
</ol>

<h3>Short Answer</h3>
<ol>
    <li>What is the difference between <strong>circuit switching</strong> and <strong>packet switching</strong> in networking?</li>
    <li>Explain how <strong>CSMA/CD</strong> (Carrier Sense Multiple Access with Collision Detection) helps in Ethernet networks.</li>
</ol>

<p>Let me know if you’d like hints or explanations for any of these! 🚀</p>
</div><!--kg-card-end: html--><!--kg-card-begin: markdown--><h1 id="interactivequizquestions">Interactive Quiz Questions</h1>
<h2 id="prompt">Prompt:</h2>
<p>I am an A-level student studying AQA Computer Science. Please quiz me interactively on networks.</p>
<h2 id="output">Output:</h2>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><style>
    .small-headers h1 { font-size: 1.5em; }
    .small-headers h2 { font-size: 1.2em; }
    .small-headers h3 { font-size: 1em; }
</style>
<div class="small-headers" style="border: 2px solid #ccc; margin: 20px; padding: 20px; background: #eee; font-size: 80%;">
    <h2>Interactive Quiz on Networks (AQA A-Level Computer Science)</h2>

<h3>Question 1:</h3>
<p><strong>What is the main function of a router in a network?</strong></p>
<ul>
    <li>a) Assign IP addresses to devices</li>
    <li><strong>b) Connect multiple networks and direct data packets ✅</strong></li>
    <li>c) Convert digital signals to analog</li>
    <li>d) Control data access in a network</li>
</ul>
<p>A <strong>router</strong> connects multiple networks and directs data packets between them, ensuring they reach their destination efficiently.</p>

<h3>Question 2:</h3>
<p><strong>Which protocol is responsible for breaking messages into packets for transmission over a network?</strong></p>
<ul>
    <li><strong>a) TCP ✅</strong></li>
    <li>b) IP</li>
    <li>c) FTP</li>
    <li>d) HTTP</li>
</ul>
<p><strong>TCP (Transmission Control Protocol)</strong> is responsible for breaking messages into packets, ensuring they are transmitted reliably, and reassembling them at the destination.</p>

<h3>Question 3:</h3>
<p><strong>Which of the following is an example of a protocol used for email transmission?</strong></p>
<ul>
    <li><strong>a) SMTP ✅</strong></li>
    <li>b) HTTP</li>
    <li>c) SSH</li>
    <li><strong>d) UDP ❌</strong></li>
</ul>
<p><strong>SMTP (Simple Mail Transfer Protocol)</strong> is used to send emails between mail servers and from email clients to mail servers.</p>
<p><strong>UDP (User Datagram Protocol)</strong> is a connectionless protocol used for fast but less reliable data transmission—often used in streaming and gaming.</p>

<h3>Question 4:</h3>
<p><strong>What does DNS stand for?</strong></p>
<ul>
    <li>a) Data Network Service</li>
    <li><strong>b) Domain Name System ✅</strong></li>
    <li>c) Digital Naming Structure</li>
    <li>d) Distributed Network Security</li>
</ul>
<p><strong>DNS (Domain Name System)</strong> is responsible for translating human-friendly domain names (like <code>google.com</code>) into IP addresses that computers use to locate each other on the internet.</p>

<h3>Question 5:</h3>
<p><strong>What type of network topology is characterized by a central hub that connects all devices?</strong></p>
<ul>
    <li>a) Ring</li>
    <li><strong>b) Mesh ❌</strong></li>
    <li><strong>c) Star ✅</strong></li>
    <li>d) Bus</li>
</ul>
<p>In a <strong>star topology</strong>, all devices are connected to a <strong>central hub or switch</strong>, which manages communication between them. This setup improves fault tolerance—if one device fails, it doesn't affect the rest of the network.</p>
<p><strong>Mesh topology</strong>, on the other hand, connects devices directly to multiple other devices, providing redundancy and high reliability.</p>

<h3>Question 6:</h3>
<p><strong>A MAC address is assigned dynamically to a device by the router.</strong></p>
<ul>
    <li><strong>False ✅</strong></li>
</ul>
<p>A <strong>MAC address (Media Access Control address)</strong> is a unique identifier <strong>hardcoded into a device’s network interface card (NIC)</strong> by the manufacturer. It does not change and is not assigned dynamically by the router. Instead, routers assign <strong>IP addresses</strong>, which can change dynamically.</p>

<h3>Question 7:</h3>
<p><strong>A VPN (Virtual Private Network) encrypts data for secure communication over an insecure network.</strong></p>
<ul>
    <li><strong>False ❌</strong></li>
</ul>
<p>The correct answer is <strong>True ✅</strong>.</p>
<p>A <strong>VPN (Virtual Private Network)</strong> encrypts data, allowing users to securely transmit information over an insecure or public network (like the internet). This helps protect privacy and prevents data interception by attackers.</p>

<h3>Question 8:</h3>
<p><strong>IPv4 uses 128-bit addresses, making it more secure than IPv6.</strong></p>
<ul>
    <li><strong>True ❌</strong></li>
</ul>
<p>The correct answer is <strong>False ✅</strong>.</p>
<p>- <strong>IPv4</strong> uses <strong>32-bit addresses</strong>, not 128-bit. It has a limited address space (about 4.3 billion addresses).</p>
<p>- <strong>IPv6</strong> uses <strong>128-bit addresses</strong>, providing a much larger address space and improved security features, such as built-in encryption and authentication.</p>

<h3>Question 9:</h3>
<p><strong>What is the difference between circuit switching and packet switching in networking?</strong></p>
<p><strong>Your Answer:</strong> Circuit switching switches circuits while packet switching switches packets.</p>
<p><strong>Feedback:</strong> ✅ <strong>Technically correct, but let's expand a bit!</strong></p>
<ul>
    <li><strong>Circuit Switching</strong> establishes a <strong>dedicated</strong> communication path between two devices before data is transmitted (e.g., traditional telephone networks). The entire session uses the same path.</li>
    <li><strong>Packet Switching</strong> divides data into <strong>small packets</strong>, which travel independently through the network and may take different routes (e.g., the internet, where TCP/IP is used).</li>
</ul>
<p>Packet switching is <strong>more efficient</strong> for modern networks since it optimizes bandwidth and avoids tying up a fixed route.</p>

<h3>Question 10:</h3>
<p><strong>Explain how CSMA/CD (Carrier Sense Multiple Access with Collision Detection) helps in Ethernet networks.</strong></p>
<p><strong>Your Answer:</strong> The sender senses the carrier (the cable or wireless network) to see if any data is being transmitted. If it is, it waits. If not, it tries to send. If a collision is detected, it will wait a random amount of time and try again. Each time a collision is detected, it waits a longer random amount of time.</p>
<p><strong>Feedback:</strong> ✅ <strong>Excellent answer!</strong></p>
<p><strong>CSMA/CD (Carrier Sense Multiple Access with Collision Detection)</strong> is used in <strong>wired Ethernet networks</strong> to manage multiple devices sharing the same transmission medium.</p>
<ul>
    <li><strong>Carrier Sense</strong> → The device listens to the network before sending data.</li>
    <li><strong>Multiple Access</strong> → Multiple devices can attempt to send data.</li>
    <li><strong>Collision Detection</strong> → If two devices transmit at the same time, a <strong>collision</strong> occurs.</li>
    <li><strong>Backoff Algorithm</strong> → After a collision, devices wait a <strong>random</strong> amount of time before retrying. If collisions keep happening, the wait time increases exponentially.</li>
</ul>
<p>This ensures fair access to the network and prevents continuous collisions.</p>

<h2>🎉 Great job! That wraps up the quiz! 🚀</h2>
<p>Would you like another round or a different topic?</p>

</div><!--kg-card-end: html--><!--kg-card-begin: markdown--><h1 id="findingcitations">Finding Citations</h1>
<h2 id="promptstandardchatgpt">Prompt (Standard ChatGPT):</h2>
<p>Find me citations supporting the use of rock music to enhance learning.</p>
<h2 id="output">Output:</h2>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><style>
    .small-headers h1 { font-size: 1.5em; }
    .small-headers h2 { font-size: 1.2em; }
    .small-headers h3 { font-size: 1em; }
</style>
<div class="small-headers" style="border: 2px solid #ccc; margin: 20px; padding: 20px; background: #eee; font-size: 80%;">
    <p><strong>Several studies and educational approaches support the use of rock music to enhance learning:</strong></p>

<ul>
  <li><strong>Popular Music Pedagogy:</strong> This educational approach involves the systematic teaching and learning of popular music, including rock, both inside and outside formal classroom settings. It emphasizes group improvisation and is often associated with community music activities. The integration of popular music into education has been linked to increased student engagement and motivation. <a href="https://en.wikipedia.org/wiki/Popular_music_pedagogy?utm_source=chatgpt.com">[Source]</a></li>
  
  <li><strong>Melodic Learning:</strong> This multimodal learning method uses elements of singing—such as pitch, rhythm, and rhyme—to facilitate the capture, storage, and retrieval of information. Techniques like setting educational content to melodies can improve memory and recall, suggesting that incorporating rock music into learning could leverage these benefits. <a href="https://en.wikipedia.org/wiki/Melodic_learning?utm_source=chatgpt.com">[Source]</a></li>
  
  <li><strong>Music-Related Memory Enhancement:</strong> Research indicates that music can improve memory in various contexts. For instance, pairing visual cues with background music has been shown to aid in the retrieval of information. Additionally, training in music has been associated with improved verbal memory in both children and adults. <a href="https://en.wikipedia.org/wiki/Music-related_memory?utm_source=chatgpt.com">[Source]</a></li>
  
  <li><strong>Music Education Integration:</strong> Integrating music education, including rock music, with other subjects has been associated with enhanced academic achievement. Studies have shown that students involved in music education programs often perform better in areas such as mathematics, science, and language arts. <a href="https://en.wikipedia.org/wiki/Music_education?utm_source=chatgpt.com">[Source]</a></li>
</ul>

<p>These findings suggest that incorporating rock music into educational settings can be an effective strategy to enhance learning outcomes.</p>

<p><strong>Additional Resources:</strong></p>
<ul>
  <li><a href="https://www.thetimes.co.uk/article/groovy-music-boosts-brainpower-as-well-as-mood-t9vvlpx8x?utm_source=chatgpt.com">Groovy music 'boosts brainpower as well as mood'</a></li>
  <li><a href="https://www.theguardian.com/commentisfree/2025/jan/04/i-started-singing-in-a-rock-band-in-my-50s-and-learned-it-could-boost-my-brain-health?utm_source=chatgpt.com">I started singing in a rock band in my 50s - and learned it could boost my brain health</a></li>
</ul>
</div><!--kg-card-end: html--><!--kg-card-begin: markdown--><h1 id="findingcitations">Finding Citations</h1>
<h2 id="promptscholargpt">Prompt (Scholar GPT):</h2>
<p>Find me citations supporting the use of rock music to enhance learning.</p>
<h2 id="output">Output:</h2>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><style>
    .small-headers h1 { font-size: 1.5em; }
    .small-headers h2 { font-size: 1.2em; }
    .small-headers h3 { font-size: 1em; }
</style>
<div class="small-headers" style="border: 2px solid #ccc; margin: 20px; padding: 20px; background: #eee; font-size: 80%;">
    
    <h2>Academic Sources Supporting the Use of Rock Music to Enhance Learning</h2>

<p>Here are some academic sources that support the idea that <strong>rock music</strong> can enhance <strong>learning</strong>:</p>

<h3>1. Southgate, D. E., & Roscigno, V. J. (2009)</h3>
<p><em>The impact of music on childhood and adolescent achievement.</em> <span>Social Science Quarterly, 90(1), 4-21.</span></p>
<ul>
  <li>Examines the impact of various music genres, including rock, on student performance and cognitive abilities.</li>
  <li>Finds positive effects on engagement and retention.</li>
  <li><a href="https://onlinelibrary.wiley.com/doi/abs/10.1111/j.1540-6237.2009.00598.x">Read here</a></li>
</ul>

<h3>2. Hallam, S., & Price, J. (1998)</h3>
<p><em>Can the use of background music improve the behavior and academic performance of children with emotional and behavioral difficulties?</em> <span>British Journal of Special Education, 25(2), 88-91.</span></p>
<ul>
  <li>Suggests that background music, including rock, can improve concentration and cognitive performance.</li>
  <li>Particularly beneficial for students with attention difficulties.</li>
  <li><a href="https://onlinelibrary.wiley.com/doi/abs/10.1111/1467-8527.t01-1-00063">Full article</a></li>
</ul>

<h3>3. Schellenberg, E. G. (2005)</h3>
<p><em>Music and cognitive abilities.</em> <span>Current Directions in Psychological Science, 14(6), 317-320.</span></p>
<ul>
  <li>Exposure to various musical styles, including rock, enhances spatial-temporal reasoning, problem-solving, and memory retention.</li>
  <li><a href="https://journals.sagepub.com/doi/10.1111/j.0963-7214.2005.00389.x">Access here</a></li>
</ul>

<h3>4. Levitin, D. J., & Tirovolas, A. K. (2009)</h3>
<p><em>Current advances in the cognitive neuroscience of music.</em> <span>Annals of the New York Academy of Sciences, 1156(1), 211-231.</span></p>
<ul>
  <li>Discusses how rhythm and melodies in rock music can improve learning by stimulating neural pathways related to memory.</li>
  <li><a href="https://nyaspubs.onlinelibrary.wiley.com/doi/10.1111/j.1749-6632.2009.04417.x">Read more</a></li>
</ul>

<h3>5. Brodsky, W. (2002)</h3>
<p><em>The effects of music tempo on simulated driving performance and vehicular control.</em> <span>Transportation Research Part F: Traffic Psychology and Behaviour, 4(4), 219-241.</span></p>
<ul>
  <li>Finds that rock music enhances focus and mental alertness, which can be extended to learning environments.</li>
  <li><a href="https://www.sciencedirect.com/science/article/abs/pii/S1369847802000190">Available here</a></li>
</ul>

<h3>6. Moreno, S., & Besson, M. (2006)</h3>
<p><em>Musical training and language-related brain electrical activity in children.</em> <span>Psychophysiology, 43(3), 287-291.</span></p>
<ul>
  <li>Findings indicate that musical training, particularly exposure to rhythmic rock patterns, improves linguistic and reading skills in children.</li>
  <li><a href="https://pubmed.ncbi.nlm.nih.gov/16805826/">Full paper</a></li>
</ul>

<h3>7. Dolegui, A. S. (2013)</h3>
<p><em>The impact of listening to music on cognitive performance.</em> <span>Inquiries Journal, 5(9), 1-3.</span></p>
<ul>
  <li>Explores how music genres, including rock, influence concentration and memory tasks.</li>
  <li>Finds that moderate-tempo rock can enhance learning.</li>
  <li><a href="http://www.inquiriesjournal.com/articles/762/the-impact-of-listening-to-music-on-cognitive-performance">Read here</a></li>
</ul>

<h3>8. Kallinen, K. (2002)</h3>
<p><em>Reading news from a pocket computer in a distracting environment: Effects of the tempo of background music.</em> <span>Computers in Human Behavior, 18(5), 537-551.</span></p>
<ul>
  <li>Examines how background music, including rock, influences reading comprehension and information retention.</li>
  <li><a href="https://www.sciencedirect.com/science/article/abs/pii/S0747563202000063">More info</a></li>
</ul>

<h3>9. Schellenberg, E. G., Nakata, T., Hunter, P. G., & Tamoto, S. (2007)</h3>
<p><em>Exposure to music and cognitive performance: Tests of children and adults.</em> <span>Psychology of Music, 35(1), 5-19.</span></p>
<ul>
  <li>Finds that listening to rock and other music genres before cognitive tasks improved performance on spatial and linguistic tests.</li>
  <li><a href="https://journals.sagepub.com/doi/abs/10.1177/0305735607068886">Check it out</a></li>
</ul>

<h3>10. Jäncke, L. (2008)</h3>
<p><em>Music, memory and emotion.</em> <span>Journal of Biology, 7(6), 21.</span></p>
<ul>
  <li>Discusses how music, including rock, triggers emotional responses that can facilitate learning by strengthening neural connections.</li>
  <li><a href="https://jbiol.biomedcentral.com/articles/10.1186/jbiol82">Read here</a></li>
</ul>

<h2>Final Thoughts</h2>
<p>These sources provide substantial evidence that <strong>rock music can enhance learning</strong> by improving concentration, memory, cognitive performance, and emotional engagement. Whether used as <em>background music</em> or an active component in education, rock music offers powerful cognitive benefits.</p>

<p>Would you like help selecting specific studies for a research project? 🎸📖</p>
</div><!--kg-card-end: html--><!--kg-card-begin: markdown--><h1 id="findingcitations">Finding Citations</h1>
<h2 id="promptscholarai">Prompt (Scholar AI):</h2>
<p>Find me citations supporting the use of rock music to enhance learning.</p>
<h2 id="output">Output:</h2>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><style>
    .small-headers h1 { font-size: 1.5em; }
    .small-headers h2 { font-size: 1.2em; }
    .small-headers h3 { font-size: 1em; }
</style>
<div class="small-headers" style="border: 2px solid #ccc; margin: 20px; padding: 20px; background: #eee; font-size: 80%;">
<h2>The Impact of Rock Music on Learning</h2>

<p>Research suggests that rock music can have both positive and negative effects on learning, depending on various factors such as volume, complexity, and individual learning styles.</p>

<p>One study tested college students' cognitive performance under the influence of rock music and found that it could either enhance or impair learning depending on the context and the task at hand (<a href="https://westcollections.wcsu.edu/bitstream/20.500.12945/2973/1/harmon.pdf">Harmon et al., 2009</a>). Similarly, research on the use of rock music in classrooms has found that it can be an effective tool for managing mood and energy, thereby influencing student engagement and learning outcomes (<a href="https://books.google.com/books?hl=en&lr=&id=sTw4DQAAQBAJ&oi=fnd&pg=PP1&dq=rock+music+and+its+effects+on+learning+and+cognition&ots=mOL70GIPvN&sig=AHsbfK1qfBABbR-7vtDSRaM_AEg">Allen & Wood, 2012</a>).</p>

<p>In terms of auditory distraction, some findings indicate that rock music can interfere with reading comprehension, particularly when played at high volumes (<a href="https://rdw.rowan.edu/etd/1229/">Rush, 2004</a>). However, when used in controlled settings, it may facilitate complex cognitive tasks, such as those required in rhythm-based learning applications like playing <span>Rock Band</span> (<a href="https://www.academia.edu/download/105176073/j.1533-1598.2010.01255.x20230821-1-uv12q7.pdf">George, 2010</a>).</p>

<p>From a neurological perspective, music listening has been shown to modulate cognitive performance through its effects on arousal and mood, which may explain why some learners benefit from background rock music while studying (<a href="https://app.scholarai.io/paper?paper_id=DOI:10.1111/j.0963-7214.2005.00389.x&original_url=https%3A%2F%2Fjournals.sagepub.com%2Fdoi%2Fabs%2F10.1111%2Fj.0963-7214.2005.00389.x">Schellenberg, 2005</a>). Moreover, long-term musical training, including rock music, has been linked to improved academic performance (<a href="https://scholarsarchive.byu.edu/intuition/vol13/iss2/9/">Hadlock, 2018</a>).</p>

<p>Interestingly, studies have also explored the effects of rock music on cognitive-related behaviors in animals, suggesting that it could influence neural processing across species (<a href="https://www.academia.edu/download/93632635/3-5-96.pdf">Pereira, 2015</a>).</p>

<p>In summary, while rock music has the potential to enhance learning under certain conditions, its effects are highly dependent on factors like volume, learner preference, and task complexity. For optimal use in education, a strategic approach incorporating controlled exposure to rock music may be beneficial.</p>

<p><strong>The ScholarAI team is building a new app, <a href="https://notilo.ai">Notilo.ai</a>, to be your research second brain! Come try it out.</strong></p>
</div><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[A multi-button detector on a single pin, and saving the results]]></title><description><![CDATA[<p>This is a walkthrough for the second <a href="https://seras.org.uk/2020/06/26/environment-maker-challenge-day-4-with-oli-howson/">IoT Workshop</a> I produceded for SERAS.</p><p>Recording of the workshop:</p><figure class="kg-card kg-embed-card"><iframe width="480" height="270" src="https://www.youtube.com/embed/T8vU8rCTyIY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><ul><li><a href="https://www.dropbox.com/s/8f37j60od6q8ea4/Session%202%20-%20Walkthrough.pptx?dl=0">Walkthrough as a PowerPoint</a></li><li><a href="https://www.dropbox.com/s/kkpjrszbkac44px/Session%202%20-%20Walkthrough.pdf?dl=0">Walkthrough as a PDF</a></li></ul><p>Or Walkthrough as a video on YouTube.</p><figure class="kg-card kg-embed-card"><iframe width="459" height="344" src="https://www.youtube.com/embed/FryP6PYFzQY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>The code, for those that don't like typing...</p><p>Part 1</p><pre><code class="language-C">int buttonValue;

void setup()
{
  Serial.begin(9600);
}

void</code></pre>]]></description><link>https://badllama.net/a-multi-button-detector-on-a-single-pin-and-saving-the-results/</link><guid isPermaLink="false">5efa38aa6e667004e4b6a2c1</guid><dc:creator><![CDATA[Oli Howson]]></dc:creator><pubDate>Mon, 29 Jun 2020 19:12:11 GMT</pubDate><content:encoded><![CDATA[<p>This is a walkthrough for the second <a href="https://seras.org.uk/2020/06/26/environment-maker-challenge-day-4-with-oli-howson/">IoT Workshop</a> I produceded for SERAS.</p><p>Recording of the workshop:</p><figure class="kg-card kg-embed-card"><iframe width="480" height="270" src="https://www.youtube.com/embed/T8vU8rCTyIY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><ul><li><a href="https://www.dropbox.com/s/8f37j60od6q8ea4/Session%202%20-%20Walkthrough.pptx?dl=0">Walkthrough as a PowerPoint</a></li><li><a href="https://www.dropbox.com/s/kkpjrszbkac44px/Session%202%20-%20Walkthrough.pdf?dl=0">Walkthrough as a PDF</a></li></ul><p>Or Walkthrough as a video on YouTube.</p><figure class="kg-card kg-embed-card"><iframe width="459" height="344" src="https://www.youtube.com/embed/FryP6PYFzQY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>The code, for those that don't like typing...</p><p>Part 1</p><pre><code class="language-C">int buttonValue;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  buttonValue = analogRead(A0);
  Serial.println(buttonValue);
  delay(100);
}</code></pre><p>Part 2</p><pre><code class="language-C">int buttonValue;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  buttonValue = analogRead(A0);

  if (buttonValue &lt; 100) {
    prevButton = '0';
  } else if (buttonValue &lt; 200) {
    Serial.println("A");
  } else if (buttonValue &lt; 350) {
    Serial.println("B");
  } else if (buttonValue &lt; 500) {
    Serial.println("C");
  } else {
    Serial.println("D");
  } 
  
  delay(100);
}</code></pre><p>Part 3</p><pre><code class="language-C">int buttonValue;
char prevButton;


void setup()
{
  Serial.begin(9600);
  prevButton = '0';  
}

void loop()
{
  buttonValue = analogRead(A0);

  if (buttonValue &lt; 100) {
    prevButton = '0';
  } else if (buttonValue &lt; 200) {
    if (prevButton == '0') {
      Serial.println("A");
    }
    prevButton = 'A';
  } else if (buttonValue &lt; 350) {
    if (prevButton == '0') {
      Serial.println("B");
    }
    prevButton = 'B';
  } else if (buttonValue &lt; 500) {
    if (prevButton == '0') {
      Serial.println("C");
    }
    prevButton = 'C';
  } else {
    if (prevButton == '0') {
      Serial.println("D");
    }
    prevButton = 'D';
  } 
  
  delay(100);
}</code></pre><p>Part 4</p><pre><code class="language-C">#include &lt;EEPROM.h&gt;

int buttonValue;
char prevButton;


void setup()
{
  Serial.begin(9600);
  prevButton = '0';  
  pinMode(5,INPUT_PULLUP);
  pinMode(6,INPUT_PULLUP);
}

void saveValue(char value) {
  bool carryOn = true;
  int index = 0;
  Serial.println("Saving value");
  do {
    if (EEPROM[index] == 0) {
      carryOn = false;
    } else {
      index = index + 1;
    }
  } while (carryOn == true and index &lt; EEPROM.length());
  Serial.print("Index found: ");
  Serial.println(index);
  EEPROM.write(index,value);
  Serial.println("Saved");
}


void loop()
{
  if (digitalRead(5) == LOW) {
    Serial.println("Showing EEPROM");
    for (int index = 0; index &lt; EEPROM.length(); index++) {
      if (EEPROM[index] &gt; 0) {
        Serial.println(EEPROM[index]);
      }
    }
    Serial.println("All shown.");
  }
  if (digitalRead(6) == LOW) {
    Serial.println("Clearing EEPROM (takes some time)");
    for (int i = 0 ; i &lt; EEPROM.length() ; i++) {
      EEPROM.write(i, 0);
    }
    Serial.println("EEPROM Cleared");
  }

  
  buttonValue = analogRead(A0);

  if (buttonValue &lt; 100) {
    prevButton = '0';
  } else if (buttonValue &lt; 200) {
    if (prevButton == '0') {
      Serial.println("A");
      saveValue('A');
    }
    prevButton = 'A';
  } else if (buttonValue &lt; 350) {
    if (prevButton == '0') {
      Serial.println("B");
      saveValue('B');
    }
    prevButton = 'B';
  } else if (buttonValue &lt; 500) {
    if (prevButton == '0') {
      Serial.println("C");
      saveValue('C');
    }
    prevButton = 'C';
  } else {
    if (prevButton == '0') {
      Serial.println("D");
      saveValue('D');
    }
    prevButton = 'D';
  } 
  
  delay(100);
}</code></pre>]]></content:encoded></item><item><title><![CDATA[A light reader, LED lighter]]></title><description><![CDATA[<p>This is a walkthrough for an <a href="https://seras.org.uk/2020/06/26/environment-maker-challenge-day-4-with-oli-howson/">IoT Workshop</a> I produced for SERAS.</p><p>Recording of the workshop:</p><figure class="kg-card kg-embed-card"><iframe width="480" height="270" src="https://www.youtube.com/embed/paNlSIEElVo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><!--kg-card-begin: markdown--><ul>
<li><a href="https://www.dropbox.com/s/9kbc51vxvipwuwq/Session%201%20-%20Walkthrough.pptx?dl=0">Walkthrough as a PowerPoint</a></li>
<li><a href="https://www.dropbox.com/s/gldjc3qyarpkjvl/Session%201%20-%20Walkthrough.pdf?dl=0">Walkthrough as a PDF</a></li>
</ul>
<p>Or Walkthrough as a video on YouTube.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-embed-card"><iframe width="459" height="344" src="https://www.youtube.com/embed/iUgDiTC3BOI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><!--kg-card-begin: markdown--><pre><code>int photoCellPin = 0;
int photoCellReading;
int LEDPin = 3;
int LEDBrightness;



void setup()
{
  Serial.begin(9600);
  pinMode(LEDPin, OUTPUT);
  pinMode(</code></pre>]]></description><link>https://badllama.net/a-light-reader-led-lighter/</link><guid isPermaLink="false">5ef47db76e667004e4b6a2a1</guid><dc:creator><![CDATA[Oli Howson]]></dc:creator><pubDate>Thu, 25 Jun 2020 10:52:33 GMT</pubDate><content:encoded><![CDATA[<p>This is a walkthrough for an <a href="https://seras.org.uk/2020/06/26/environment-maker-challenge-day-4-with-oli-howson/">IoT Workshop</a> I produced for SERAS.</p><p>Recording of the workshop:</p><figure class="kg-card kg-embed-card"><iframe width="480" height="270" src="https://www.youtube.com/embed/paNlSIEElVo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><!--kg-card-begin: markdown--><ul>
<li><a href="https://www.dropbox.com/s/9kbc51vxvipwuwq/Session%201%20-%20Walkthrough.pptx?dl=0">Walkthrough as a PowerPoint</a></li>
<li><a href="https://www.dropbox.com/s/gldjc3qyarpkjvl/Session%201%20-%20Walkthrough.pdf?dl=0">Walkthrough as a PDF</a></li>
</ul>
<p>Or Walkthrough as a video on YouTube.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-embed-card"><iframe width="459" height="344" src="https://www.youtube.com/embed/iUgDiTC3BOI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><!--kg-card-begin: markdown--><pre><code>int photoCellPin = 0;
int photoCellReading;
int LEDPin = 3;
int LEDBrightness;



void setup()
{
  Serial.begin(9600);
  pinMode(LEDPin, OUTPUT);
  pinMode(photoCellPin,INPUT);
}

void loop()
{
  photoCellReading = analogRead(photoCellPin);
  Serial.print(&quot;Analog reading = &quot;);
  Serial.println(photoCellReading);
  photoCellReading = 1023 - photoCellReading;
  LEDBrightness = map(photoCellReading, 0, 1023, 0, 255);
  Serial.print(&quot;LED output = &quot;);
  Serial.println(LEDBrightness);
  analogWrite(LEDPin, LEDBrightness);
  delay(100);
}
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[IoT Explorations Part 4b: Reporting a Button on a Web Server]]></title><description><![CDATA[<p><a href="https://badllama.net/iot-explorations-part-1/">You may wish to refer to the Part 1 shopping list post.</a> You may also wish to refer back to <a href="https://badllama.net/iot-explorations-part-3/">Part 3</a> and <a href="https://badllama.net/iot-explorations-part-4a/">Part 4a</a> of this series. </p><p>So this section really is just a combination of the previous two parts. Firstly we add the button circuitry to the existing</p>]]></description><link>https://badllama.net/iot-explorations-part-4b/</link><guid isPermaLink="false">5ed3d6786e667004e4b6a250</guid><dc:creator><![CDATA[Oli Howson]]></dc:creator><pubDate>Sun, 31 May 2020 16:36:30 GMT</pubDate><content:encoded><![CDATA[<p><a href="https://badllama.net/iot-explorations-part-1/">You may wish to refer to the Part 1 shopping list post.</a> You may also wish to refer back to <a href="https://badllama.net/iot-explorations-part-3/">Part 3</a> and <a href="https://badllama.net/iot-explorations-part-4a/">Part 4a</a> of this series. </p><p>So this section really is just a combination of the previous two parts. Firstly we add the button circuitry to the existing web server circuit. This means a 10k from one side of the switch, via a jumper wire to the - rail, with another jumper from the same side of the swith do digital pin 5 on the Arduino, then a jumper wire from the other side of the switch to the + rail. This <a href="https://www.tinkercad.com/things/5COZR1bdjRM">circuit can be seen here</a>.</p><p>Then we add a few lines of code; </p><p><code>const int buttonPin = 5; //We will use D5 as the pin reading button</code> goes at the top in the declarations.</p><p><code>pinMode(buttonPin, INPUT); //Open up the chosen pin for input</code> goes in the setup to open up the input pin.</p><p>Finally, we adjust the section of <code>loop()</code> to include a check of the input pin value, and output the corresponding response:</p><pre><code class="language-C">    if (connectionId != -1)
    {
      //build the webpage
      String webpage = "&lt;html&gt;&lt;head&gt;&lt;title&gt;Testing!&lt;/title&gt;&lt;/head&gt;";
      webpage += "&lt;body&gt;&lt;h1&gt;Button Check&lt;/h1&gt;&lt;p&gt;Digital Button 5 is: ";
      if (digitalRead(buttonPin) == HIGH)
      {
        webpage += "High";
      }
      else
      {
        webpage += "Low";
      }
      webpage += "&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;";
      sendWebpage(connectionId, webpage); //Send the webpage
    }</code></pre><!--kg-card-begin: markdown--><p>You can access the<a href="https://create.arduino.cc/editor/ohowson/ad42cda8-4250-4e89-9173-98e5288351d2/preview"> whole modified code here</a> if you are too lazy to type it all in yourself.</p>
<p>And that really much is it. If you hit the same IP address as before in your browser, you should see (without pressing the button):</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://badllama.net/content/images/2020/05/image-3.png" class="kg-image"></figure><p>And then if you hold the button and hit refresh:</p><figure class="kg-card kg-image-card"><img src="https://badllama.net/content/images/2020/05/image-2.png" class="kg-image"></figure><p>Now things are starting to get interesting! If you did some port forwarding, you could access that from work and tell if anyone has broken in to your workshop and pressed your button!</p><p>In the next section we will start looking at the thing that actually triggered this whole series of tutorials, responding to multiple buttons!</p>]]></content:encoded></item><item><title><![CDATA[IoT Explorations Part 4a: A Button]]></title><description><![CDATA[<p><a href="https://badllama.net/iot-explorations-part-1/">You may wish to refer to the Part 1 shopping list post.</a></p><p>The next tutorial is going to be looking at reporting a button state on the web server we built in part 3. First though, we're going to make sure we can build a button that works! I tend</p>]]></description><link>https://badllama.net/iot-explorations-part-4a/</link><guid isPermaLink="false">5ed3b31d6e667004e4b6a1e5</guid><dc:creator><![CDATA[Oli Howson]]></dc:creator><pubDate>Sun, 31 May 2020 14:19:07 GMT</pubDate><content:encoded><![CDATA[<p><a href="https://badllama.net/iot-explorations-part-1/">You may wish to refer to the Part 1 shopping list post.</a></p><p>The next tutorial is going to be looking at reporting a button state on the web server we built in part 3. First though, we're going to make sure we can build a button that works! I tend to say button; you may see switch, tactile switch, momentary switch... I like 'button'. Regardless, you're most likely to have ones that look like this: </p><figure class="kg-card kg-image-card"><img src="https://badllama.net/content/images/2020/05/s-l640.jpg" class="kg-image"></figure><p>Although I always struggle to remember which of the legs are common and not - I have prefer simple ones like these:</p><figure class="kg-card kg-image-card"><img src="https://badllama.net/content/images/2020/05/mini-pcb-pushbutton-switch-2-500x500.jpg" class="kg-image"></figure><p>You can remove out the other circuits if you wish and build this one from scratch. I just disconnected the digital pins from the Arduino and left everything else where it was. </p><p>The simplest way to build such a circuit would be to have a button with one side </p><p>connected to + and one side connected to the digital pin. When the switch is open the pin receives no input (which we call LOW). When the switch is closed, the switch receives input (which we call HIGH). However, there's  bit of a problem here in that when the switch is open, it is called 'floating' and can report false values. </p><p>Instead what we do is connect one side of the switch to + and the other end to -. However this would cause a short circuit so between the - and the switch we put a resistor - 10k being a common choice (though almost anything around that range will do). We then connect the digital pin (in this case D5) to the switch on the - side. </p><p>This is called a <em>pull down resistor</em>. There's nothing special about the resistor, it's a normal resistor that serves a purpose. Having the digital pin connected to - normally (via the resistor) means it is held to 0v - it reports a consistent low. Closing the switch allows the +'ve current to flow through the switch, and as it's easier for the current to go to the digital pin than force it's way through the resistor to ground, that's the route it takes and we get a consistent high signal. There are also pull-up resistors which do the same thing but hold the signal high and closing the switch drags it low. For this system the choice is purely arbitrary.</p><p>For power you could connect to the +3.3v (or even +5v) of the Arduino and run the - from ground on the Arduino. However, this would not be what we want for the next part of the project so we instead will connect the +/- rails to a 3.3v supply from elsewhere and just connect the Arduino ground to the - rail. </p><p>I've <a href="https://www.tinkercad.com/things/52JPvWxgpkh">drawn the circuit out for you here</a>. </p><p>Now for the code. We could just have the LED light up when the button is pressed and out when not, but I like to go a bit overboard so the code below has the LED (I used the built in LED) flash fast if the button is HIGH (closed) and slowly if it is LOW (open). I also have it output the value (as 1 or 0 accordingly) on the serial monitor. </p><pre><code class="language-C">const int buttonPin = 5; //We will use D5 as the pin reading button

void setup() {
  pinMode(LED_BUILTIN, OUTPUT); //Open up the built in LED for output
  pinMode(buttonPin, INPUT); //Open up the chosen pin for input
  Serial.begin(9600); //Use the serial monitor 
}

void loop() {
    Serial.print(digitalRead(buttonPin)); //Ouput the current state of the button to the monitor
    if (digitalRead(buttonPin) == HIGH) {  //If it's high/closed
      digitalWrite(LED_BUILTIN,HIGH);
      delay(100); //flash fast
      digitalWrite(LED_BUILTIN,LOW);
      delay(100);
    } else { //or it's low/closed
      digitalWrite(LED_BUILTIN,HIGH);
      delay(500); //flash slow
      digitalWrite(LED_BUILTIN,LOW);
      delay(500);
    }
}</code></pre><p>Give it a try. Next we will look at combining the button press to and the web server.</p>]]></content:encoded></item><item><title><![CDATA[IoT Explorations Part 3: Basic web server]]></title><description><![CDATA[<p><a href="https://badllama.net/iot-explorations-part-1/">You may wish to refer to the Part 1 shopping list post.</a></p><!--kg-card-begin: markdown--><p>In <a href="https://badllama.net/iot-explorations-part-2/">part 2</a> of this exploration we connected to and programmed an ESP8266 WiFi module from an Arduino Nano. In this part we will modify that solution to hold a static web page.</p>
<p>This is where things started</p>]]></description><link>https://badllama.net/iot-explorations-part-3/</link><guid isPermaLink="false">5ed10c306e667004e4b6a0f0</guid><dc:creator><![CDATA[Oli Howson]]></dc:creator><pubDate>Fri, 29 May 2020 15:40:45 GMT</pubDate><content:encoded><![CDATA[<p><a href="https://badllama.net/iot-explorations-part-1/">You may wish to refer to the Part 1 shopping list post.</a></p><!--kg-card-begin: markdown--><p>In <a href="https://badllama.net/iot-explorations-part-2/">part 2</a> of this exploration we connected to and programmed an ESP8266 WiFi module from an Arduino Nano. In this part we will modify that solution to hold a static web page.</p>
<p>This is where things started getting tricky; most of the examples I found online either simply did not work, or worked very intermittently. The key problem was the attempts to connect to and set up the esp8266 connection automatically - what worked absolutely fine when I was typeing AT commands in just didn't like to work when I was sending the commands in code.</p>
<p>So, this may not be the right way, but it's a way which I have found works. Mostly. And at least when it doesn't it gives you a flashing light to tell you to hit restart!</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>The circuit is the <a href="https://www.tinkercad.com/things/cbrYh6MqiLw">same as last time</a> but the code is substantially different. I based my code off of <a href="https://mjrobot.org/2016/01/19/o-esp8266-parte-2-web-server/">code produced by MJRobot</a> which was the closest I could find to working.</p>
<p>I needed a number of subroutines.</p>
<p><code>doCommand()</code> was designed to send a command to the esp8266, just as if you are sending an AT command. The problem was working out whether it worked, failed, or just needed a bit of time to sort itself out.</p>
<p>My method was to run the command as-is, guessing it would say &quot;OK&quot; when things work and something like &quot;FAIL&quot; when it didn't (both these strings being passed in as parameters). If it detected the &quot;OK&quot; it would return true. If it detected the &quot;FAIL&quot; string it would return false. If it didn't detect either, it would wait msdelay milliseconds and then try again.</p>
<p>If of course things went horribly wrong, I watched the serial monitor and adjusted the OK and FAIL strings checks accordingly :)</p>
<p>I've also included a debug flag which basically outputs all the serial data and a bit extra (eg some lines to split/combine the output) to enable you to figure out what's happening. This function would be a lot shorter without that!</p>
<p>Note I've not included a time-out. This is because at least for now I want it to just keep trying until something works! I may, or may not, add that at some point in the future.</p>
<!--kg-card-end: markdown--><pre><code class="language-C">bool doCommand(String command, String success, String failure, int msdelay, bool debug) {
  String s = "";
  char c = "";
  esp8266.write(command.c_str()); //write the command to the esp8266. Note this has to be a c_string.
  while (true) { //repeat forever (this is where the timeout would have to go I suppose)
    delay(msdelay); //wait a moment before carrying on
    while(esp8266.available()) //If the esp8266 has content
    {
      c = esp8266.read(); //read it
      if (debug) {
        Serial.write(c); //output if debug
      }
      s += c; //add to the received string
    }
    if (debug)
    {
      Serial.print("---");
      Serial.print(s);      //once we have a whole string, output it
      Serial.println("---");
    }
    if (s.indexOf(failure) &gt; 0) //check if the failure string is found. This goes first as sometimes 
    {                           //a 'false success' occurs (ie getting an IP address, it returns 0.0.0.0)
       if (debug)
       {
        Serial.println("Failure detected."); //output if debug
       }
      return false; //leave the loop
    }
    else 
    {
     if (s.indexOf(success) &gt; 0)//check if success string is found
     {
       if (debug)
       {
        Serial.println("Success detected."); //output if debug
       }
       return true; //leave the loop
     }
    }
  }
}</code></pre><p>When the esp8266 receives a request from a web client, it gets a <code>+IPD</code> message which has a connection ID. I wrote a little helper to check if an <code>+IPD</code> had been received and return either the connection ID (-48 for some reason I don't understand but seems to work), or -1 if <code>+IPD</code> isn't found</p><pre><code class="language-C">int checkIfRequest()
{
  if (esp8266.available()) // check if 8266 is sending data
  {
    if (esp8266.find("+IPD,")) //+IPD code detected
    {
      delay(300); //Brief pause
      int connectionId = esp8266.read() - 48; //Get the ID (no idea why -48 but it works)
      return connectionId; //return the ID
    }
  }
  return -1; //Or return -1 if no request made
}</code></pre><p>The act of building up and sending a web page is actually relatively complex. First we have to send an <code>AT+CIPSEND</code> command with the connect ID and the web page length. The OK message for this, weirdly, was <code>keep-alix</code>. I don't know who Alix... Actually I have a confession to make; it awas keep-alix on my first esp8266, on <em>this</em> one which I'm using to test for you lot it comes back as <code>keep-alii</code>. Now I can't pretend to know why this is - but the <code>keep-</code> bit seems stable so I adjusted the code to just use that. <em>Learning on the fly</em>! Then we have to send the webpage data itself. Then we have to send an <code>AT-CIPCLOSE</code> command, again including the connection ID. I thought it best to make a little helper function to do this. </p><pre><code class="language-C">void sendWebpage(int connectionId,String webpage)
{
      String cipSend = "AT+CIPSEND="; //Build up the initialisation string
      cipSend += connectionId;
      cipSend += ",";
      cipSend += webpage.length();
      cipSend += "\r\n";
      doCommand(cipSend,"keep-","FAIL",1000,true); //Send initialisation
      doCommand(webpage,"OK","FAIL",1000,true); //Send the webpage
      String closeCommand = "AT+CIPCLOSE="; //Build up the close string
      closeCommand += connectionId; // append connection id
      closeCommand += "\r\n";
      doCommand(closeCommand,"OK","FAIL",1000,true); //Send the close string
}</code></pre><p>A few initialisation things at the top. You may notice I've changed to using esp8266 rather than ESPSerial. I don't really know why... but the same pins for the Rx/Tx, speed is set as a constant so we can change in future if we want, and I have included a DEBUG constant that can be used to turn on global debugging (which, if turned off, can be overruled with an 'or true' in the function calls). </p><pre><code class="language-C">#include &lt;SoftwareSerial.h&gt;
SoftwareSerial esp8266(2, 3); // RX | TX

#define speed8266 9600 
#define DEBUG false

bool ipFail;</code></pre><p>Then, the setup! This basically runs through the AT commands we did before, and again while they worked perfectly typed in manually, I find these often go wrong. Hence all this palaver (and this is days of experimentation - you're welcome!)</p><p>The one thing that can go wrong is the IP address. If it comes back as 0.0.0.0 then it's a problem - and in the loop I make the LED flash. You need to restart the Arduino. I suppose I <em>could</em> set a loop to check it and run the process again but I'm still learning about this and may come up with a way to stop it happening in the first place. If I have to reset occassionally it will annoy me and I'm more likely to remember to fix it!</p><pre><code class="language-C">void setup() 
{ 
  pinMode(LED_BUILTIN, OUTPUT); //use the built in LED
  esp8266.begin (speed8266);  //set the speed
  Serial.begin(speed8266); //open the serial monitor
  Serial.println("ESP8266 Static Web Server"); //
  Serial.println("Waiting 1 s");
  delay(1000); //Get ready...
  Serial.println("Connecting to network and waiting 1 second.");
  doCommand("AT+CWJAP=\"&gt;&gt;YOUR NETWORK SSID&lt;&lt;\",\"&gt;&gt;YOUR PASSWORD&lt;&lt;\"\r\n","OK","FAIL",1000,DEBUG or true);
  Serial.println("Changing mode and waiting 1 second.");
  doCommand("AT+CWMODE=1\r\n","OK","FAIL",1000,DEBUG or true);
  Serial.println("Showing IP and waiting 1 second.");
  //The next line logs ipFail as to whether 0.0.0.0 was returned (a fail)
  //later on we'll have the LED flash if this is the case and you have 
  // to restart the Arduino
  ipFail = not doCommand("AT+CIFSR\r\n","CIFSR","0.0.0.0",1000,DEBUG or true); 
  Serial.println("Enabling multiple connections and waiting 1 second.");
  doCommand("AT+CIPMUX=1\r\n","OK","FAIL",1000,DEBUG or true);
  Serial.println("Starting comm port 80 and waiting 1 second.");
  doCommand("AT+CIPSERVER=1,80\r\n","OK","FAIL",1000,DEBUG or true);
  Serial.println("Entering loop.");
}</code></pre><p>Now, finally, the main loop! First we check whether an IP address was received, and flash if there's a problem or just turn on if OK. We check if there's a request, and if so build and send the webpage. </p><pre><code class="language-C">void loop() 
{
  if (ipFail) //If the IP came back as 0.0.0.0 then we flash the LED
  {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
  }
  else
  {
    digitalWrite(LED_BUILTIN, HIGH); //If not, just turn the LED on solid 
    //so we know things are good to go.
      while(esp8266.available())
      {
        Serial.write(esp8266.read()); //Get any data from the ESP and echo it
      }
      while(Serial.available())
      {
        esp8266.write(Serial.read()); //Get any data on monitor and send it back
      }
      int connectionId = checkIfRequest(); //Check if we've received a web request
      if (connectionId != -1)
      {
        //build the webpage
        String webpage = "&lt;html&gt;&lt;head&gt;&lt;title&gt;Testing!&lt;/title&gt;&lt;/head&gt;";
        webpage += "&lt;body&gt;&lt;h1&gt;Testing!&lt;/h1&gt;&lt;p&gt;Hello, world!&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;";
        sendWebpage(connectionId,webpage); //Send the webpage
      }
   }
}</code></pre><p>Now of course, you could be a tad lazy and <a href="https://create.arduino.cc/editor/ohowson/562b6ec9-57ed-4274-a17f-03dc3287ec6c/preview">access the whole file here</a>. However, I'm a big fan of typing code, I feel it helps you learn.</p><p>The first time I ran this, I got the following:</p><!--kg-card-begin: markdown--><pre><code>ESP8266 Static Web Server
Waiting 1 s
Connecting to network and waiting 1 second.
AT+CWJAP=&quot;&gt;&gt;YOUR NETWORK SSID&lt;&lt;&quot;,&quot;&gt;&gt;YOUR PASSWORD&lt;&lt;&quot;

busy p..---AT+CWJAP=&quot;&gt;&gt;YOUR NETWORK SSID&lt;&lt;&quot;,&quot;&gt;&gt;YOUR PASSWORD&lt;&lt;&quot;

busy p..---
---AT+CWJAP=&quot;&gt;&gt;YOUR NETWORK SSID&lt;&lt;&quot;,&quot;&gt;&gt;YOUR PASSWORD&lt;&lt;&quot;

busy p..---
---AT+CWJAP=&quot;&gt;&gt;YOUR NETWORK SSID&lt;&lt;&quot;,&quot;&gt;&gt;YOUR PASSWORD&lt;&lt;&quot;

busy p..---
---AT+CWJAP=&quot;&gt;&gt;YOUR NETWORK SSID&lt;&lt;&quot;,&quot;&gt;&gt;YOUR PASSWORD&lt;&lt;&quot;

busy p..---
---AT+CWJAP=&quot;&gt;&gt;YOUR NETWORK SSID&lt;&lt;&quot;,&quot;&gt;&gt;YOUR PASSWORD&lt;&lt;&quot;

busy p..---
---AT+CWJAP=&quot;&gt;&gt;YOUR NETWORK SSID&lt;&lt;&quot;,&quot;&gt;&gt;YOUR PASSWORD&lt;&lt;&quot;

busy p..---
+CWJAP:1

FAIL
---AT+CWJAP=&quot;&gt;&gt;YOUR NETWORK SSID&lt;&lt;&quot;,&quot;&gt;&gt;YOUR PASSWORD&lt;&lt;&quot;

busy p..+CWJAP:1

FAIL
---
Failure detected.
Changing mode and waiting 1 second.
AT+CWMODE=1


OK
---AT+CWMODE=1


OK
---
Success detected.
Showing IP and waiting 1 second.
AT+CIFSR

+CIFSR:STAIP,&quot;0.0.0.0&quot;
+CIFSR:STAMAC,&quot;5c:cf:7f:49:d---AT+CIFSR

+CIFSR:STAIP,&quot;0.0.0.0&quot;
+CIFSR:STAMAC,&quot;5c:cf:7f:49:d---
Failure detected.
Enabling multiple connections and waiting 1 second.
AT+CIPMUX=1


OK
---AT+CIPMUX=1


OK
---
Success detected.
Starting comm port 80 and waiting 1 second.
AT+CIPSERVER=1,80


OK
---AT+CIPSERVER=1,80


OK
---
Success detected.
Entering loop.
</code></pre>
<!--kg-card-end: markdown--><p>Obviously my debug code could be made a bit more succinct, but it does the job. More importantly, I didn't change my SSID/Password...</p><p>The second time I remembered (and no, that's not my password!) and everything seems fine:</p><!--kg-card-begin: markdown--><pre><code>ESP8266 Static Web Server
Waiting 1 s
Connecting to network and waiting 1 second.
AT+CWJAP=&quot;GDog&quot;,&quot;MyPa$$w0rd&quot;

---AT+CWJAP=&quot;GDog&quot;,&quot;MyPa$$w0rd&quot;

---
---AT+CWJAP=&quot;GDog&quot;,&quot;MyPa$$w0rd&quot;

---
---AT+CWJAP=&quot;GDog&quot;,&quot;MyPa$$w0rd&quot;

---
---AT+CWJAP=&quot;GDog&quot;,&quot;MyPa$$w0rd&quot;

---
---AT+CWJAP=&quot;GDog&quot;,&quot;MyPa$$w0rd&quot;

---
WIFI CONNECTED
---AT+CWJAP=&quot;GDog&quot;,&quot;MyPa$$w0rd&quot;

WIFI CONNECTED
---
---AT+CWJAP=&quot;GDog&quot;,&quot;MyPa$$w0rd&quot;

WIFI CONNECTED
---
---AT+CWJAP=&quot;GDog&quot;,&quot;MyPa$$w0rd&quot;

WIFI CONNECTED
---
---AT+CWJAP=&quot;GDog&quot;,&quot;MyPa$$w0rd&quot;

WIFI CONNECTED
---
---AT+CWJAP=&quot;GDog&quot;,&quot;MyPa$$w0rd&quot;

WIFI CONNECTED
---
WIFI GOT IP
---AT+CWJAP=&quot;GDog&quot;,&quot;MyPa$$w0rd&quot;

WIFI CONNECTED
WIFI GOT IP
---

OK
---AT+CWJAP=&quot;GDog&quot;,&quot;MyPa$$w0rd&quot;

WIFI CONNECTED
WIFI GOT IP

OK
---
Success detected.
Changing mode and waiting 1 second.
AT+CWMODE=1


OK
---AT+CWMODE=1


OK
---
Success detected.
Showing IP and waiting 1 second.
AT+CIFSR

+CIFSR:STAIP,&quot;192.168.1.139&quot;
+CIFSR:STAMAC,&quot;5c:cf:7---AT+CIFSR

+CIFSR:STAIP,&quot;192.168.1.139&quot;
+CIFSR:STAMAC,&quot;5c:cf:7---
Success detected.
Enabling multiple connections and waiting 1 second.
AT+CIPMUX=1


OK
---AT+CIPMUX=1


OK
---
Success detected.
Starting comm port 80 and waiting 1 second.
AT+CIPSERVER=1,80

no change

OK
---AT+CIPSERVER=1,80

no change

OK
---
Success detected.
Entering loop.
</code></pre>
<!--kg-card-end: markdown--><p>Shall we test it? Let's grab that IP address and put it into a browser window...</p><figure class="kg-card kg-image-card"><img src="https://badllama.net/content/images/2020/05/image-1.png" class="kg-image"></figure><p>Well that looks good! The code below shows what came over the monitor.</p><!--kg-card-begin: markdown--><pre><code>,433:GET / HTTP/1.1
Host: 192.168.1.139
Connection: keep-alii---,433:GET / HTTP/1.1
Host: 192.168.1.139
Connection: keep-alii---
Success detected.

Recv 99 bytes

SEND OK
---
Recv 99 bytes

SEND OK
---
Success detected.
AT+CIPCLOSE=0

0,CLOSED

OK

+IPD,1,361:GET /favicon.ico H-Language: en-GB,en-US;q=0.9,en;q=0.8

---AT+CIPCLOSE=0

0,CLOSED

OK

+IPD,1,361:GET /favicon.ico H-Language: en-GB,en-US;q=0.9,en;q=0.8

---
Success detected.
</code></pre>
<!--kg-card-end: markdown--><p>Of course, we could (should?) do some filtering of the GET string, return 404 errors or whatever for the favicon.ico and such like. But this is just playing, I'm not trying to write an Arduino-based Apache server!</p><p>There we go then - no wiring up this time, but we've got WiFi and made a very basic web server! On to the next tutorial I suppose...</p>]]></content:encoded></item><item><title><![CDATA[IoT Explorations Part 1: Shopping List]]></title><description><![CDATA[<p>As part of an upcoming series of workshops on IoT I have been endeavouring to learn more about IoT - and specifically IoT on a budget! I'm fortunate enough to have a bunch of Arduino and other electronic bits and bobs laying around from previous explorations, forrays, and a kit</p>]]></description><link>https://badllama.net/iot-explorations-part-1/</link><guid isPermaLink="false">5ecd09e76e667004e4b69ec2</guid><dc:creator><![CDATA[Oli Howson]]></dc:creator><pubDate>Thu, 28 May 2020 10:10:09 GMT</pubDate><content:encoded><![CDATA[<p>As part of an upcoming series of workshops on IoT I have been endeavouring to learn more about IoT - and specifically IoT on a budget! I'm fortunate enough to have a bunch of Arduino and other electronic bits and bobs laying around from previous explorations, forrays, and a kit I was bought for Christmas. But this is not always the case. So part one of this exploration is to put together a minimal list of what I have used for the projects that follow. This may not be the bare bones list - I mean you could connect the Arduino by putting female jumpers onto the pins rather than using a breadboard - but it's the minimum I have used, and what I will be putting together into a little kit for the workshops.</p><p>Note: I know the esp8266 can be used as a microcontroller in it's own right. This set of workshops was based around having an easy to use yet affordable microcontroller - the Arduino Nano - but then using the esp8266 as a cheap and (relatively) simple way to get the Nano online. You can get Arduino's with wifi built in - but where's the fun in that?</p><h2 id="part-2-getting-connected-to-wifi"><a href="https://badllama.net/iot-explorations-part-2/">Part 2: Getting connected to WiFi</a></h2><p></p><ul><li>Arduino Nano (other flavours exist; I used a cheap and cheerful nano from eBay) </li><li>USB cable</li><li>ESP8266	(again I went with the cheapest and cheerfullest)</li><li>Breadboard</li><li>5x M-F jumper wires</li><li>2x M-M jumper wires </li><li>3.3v power supply</li><li>10kΩ resistor</li><li>1kΩ resistor</li><li>2.2kΩ resistor</li></ul><p>For the 3.3v power I initially I used 2xAAA batteries together in series. They didn't last long so now use a power adaptor that came with an Arduino kit and a variable voltage plug that I got from Maplins years ago. You cannot run the ESP8266 from the Arduino 3.3v supply.  </p><h2 id="part-3-basic-web-server">Part 3: Basic web server</h2><p><em><strong>Note: This uses the same circuit as part 2 and so the parts are identical...</strong></em></p><ul><li>Arduino Nano (other flavours exist; I used a cheap and cheerful nano from eBay) </li><li>USB cable</li><li>ESP8266	(again I went with the cheapest and cheerfullest)</li><li>Breadboard</li><li>5x M-F jumper wires</li><li>2x M-M jumper wires </li><li>3.3v power supply</li><li>10kΩ resistor</li><li>1kΩ resistor</li><li>2.2kΩ resistor</li></ul><h2 id="part-4a-a-button">Part 4a: A Button</h2><p>This is for a single switch (we're just testing!). </p><ul><li>Arduino Nano (other flavours exist; I used a cheap and cheerful nano from eBay) </li><li>USB cable</li><li>Breadboard</li><li>4x M-M jumper wires </li><li>3.3v power supply</li><li>Momentary / push button switch</li><li>10kΩ resistor</li></ul><h2 id="part-4b-reporting-a-button-on-a-web-server">Part 4b: Reporting a button on a Web Server</h2><p>This is for a single switch (we're just testing!). Each additional switch would need two more M-M jumper wires, one more 10kΩ resistor. And of course an additional switch!</p><ul><li>Arduino Nano (other flavours exist; I used a cheap and cheerful nano from eBay) </li><li>USB cable</li><li>ESP8266	(again I went with the cheapest and cheerfullest)</li><li>Breadboard</li><li>5x M-F jumper wires</li><li>5x M-M jumper wires </li><li>3.3v power supply</li><li>2x 10kΩ resistor</li><li>1kΩ resistor</li><li>2.2kΩ resistor</li><li>Momentary / push button switch</li></ul><!--kg-card-begin: html--><font color="red">FROM HERE ON THE BLOGS ARE UNPUBLISHED AND SUBJECT TO CHANGE</font><!--kg-card-end: html--><h2 id="project-total">Project Total</h2><p>If you want to just order everything to cover the whole project then you want to use this complete list.</p><ul><li>Arduino Nano (other flavours exist; I used a cheap and cheerful nano from eBay) </li><li>USB cable</li><li>ESP8266	(again I went with the cheapest and cheerfullest)</li><li>Breadboard</li><li>5x M-F jumper wires</li><li>5x M-M jumper wires </li><li>3.3v power supply</li><li>2x 10kΩ resistor</li><li>1kΩ resistor</li><li>2.2kΩ resistor</li><li>Momentary / push button switch</li></ul>]]></content:encoded></item><item><title><![CDATA[IoT Explorations Part 2: Getting connected to WiFi]]></title><description><![CDATA[<p><a href="https://badllama.net/iot-explorations-part-1/">You may wish to refer to the Part 1 shopping list post.</a></p><p>So we have this little esp8266 thing; it's supposed to connect to WiFi. But how do we do that? Well one way is to use a programmer device to connect to it and tell it what to do.</p>]]></description><link>https://badllama.net/iot-explorations-part-2/</link><guid isPermaLink="false">5ece8df06e667004e4b69f49</guid><dc:creator><![CDATA[Oli Howson]]></dc:creator><pubDate>Wed, 27 May 2020 18:56:24 GMT</pubDate><content:encoded><![CDATA[<p><a href="https://badllama.net/iot-explorations-part-1/">You may wish to refer to the Part 1 shopping list post.</a></p><p>So we have this little esp8266 thing; it's supposed to connect to WiFi. But how do we do that? Well one way is to use a programmer device to connect to it and tell it what to do. This is a nice solution (and one which I will explore at a later date). But in the interest of getting started cheaply, we don't <em>have</em> a programmer. We <em>do</em> have an Arduino. And as that's what we're going to be using it with anyway, we may as well use that to control it right through. </p><p>To step through this, I've taken a brand-new out of the packet esp8266. Everything I experience, you will experience.</p><p>So firstly, what we <em>should</em> be doing here in terms of wiring. We need to know the pinout of the esp8266. I made this lovely diagram which I've got stuck on a whiteboard near my desk while I'm working. A bit of Googling found it, then I drew it special for you!</p><figure class="kg-card kg-image-card"><img src="https://badllama.net/content/images/2020/05/esp8266.png" class="kg-image"></figure><ol><li>Rx</li><li>GPIO 0</li><li>GPIO 2</li><li>Gnd</li><li>Tx</li><li>CH-PD</li><li>RST</li><li>Vcc</li></ol><p>We need M-F jumpers to wire most of this up. On my breadboard I've got a 3.3v power supply at one end with + and - stuck in the corresponding rails, and the Arduino at the other end. More on the 3.3v later! The hardest thing is rotating your diagram and the actual esp8266 the right way -  I kept spinning mine or having it with the pins facing up!</p><!--kg-card-begin: markdown--><ol>
<li>Pin 4 to - rail on the breadboard</li>
<li>Pin 8 to the + rail on the breadboard</li>
<li>Pin 6 to a line on the breadboard, then a 10kΩ resistor from that line to the + rail</li>
<li>Pin 5 to digital pin 2 (D2) on Arduino</li>
<li>Pin 1 is the tricky one. First we use an M-F jumper to put it to a space on the breadboard. Then we have a 2.2kΩ resistor between that line and the - rail. This I believe drags it down to 0v to stop it floating when there is no signal. <em>Then</em> we need a 2.2kΩ resistor from the same line to a new line, and <em>finally</em> a M-M jumper to the pin 3 (D3) on Arudino.</li>
<li>A M-M jumper from Arduino ground to the - rail</li>
</ol>
<p>I know number 5 sounds squiffy - it's really not that difficult. Hopefully the circuit I show below should help. The resistor to the - rail stops the voltage floating when not in use (which can cause problems) and is, I believe, called a pull-down resistor. The other resistor is, I assume, a voltage divider and is, again I assume, because the Arduino can output 5v and more than 3.3v can make the esp8266 stop working. It may - and probably will - work if you just go straight through. But then it may not.</p>
<p>At this point I must add I didn't have the right resistors, so used a 2kΩ in place of 2.2kΩ and two 470Ω in series in place of the 1kΩ. They're close enough and seem to be ok!</p>
<p>It's also worth noting that if you have a different Arduino you can probably connect through to one of the other Serial lines. The Nano only has one which will be in use by the Arduino/PC connection. So figured may as well use SoftwareSerial to do it for us. I believe it's slower, but it's what the rest of the tutorials will be doing, and it's fast enough. I wanted something that should work for everyone.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Hopefully <a href="https://www.tinkercad.com/things/cbrYh6MqiLw">this tinkercad diagram</a> will help make that all clear.</p>
<!--kg-card-end: markdown--><p>Now for the code; I've been using the <a href="https://create.arduino.cc/">Arduino web editor</a> though the same should work on an installed version.</p><pre><code class="language-C">#include &lt;SoftwareSerial.h&gt; //Enables us to use digital ports as serial connection
SoftwareSerial ESPserial(2, 3); // RX | TX

void setup()
{
  Serial.begin(9600);  // communication with the host computer
  ESPserial.begin(115200); //set the esp8266 communication speed
  Serial.println("Ready"); //Are you?
  Serial.println("");
}

void loop()
{
  if ( ESPserial.available() ) //if there is data on serial line
  {
    Serial.write( ESPserial.read() ); //read it and put on monitor
  }

  if ( Serial.available() ) //if there's data on the monitor
  {
    ESPserial.write( Serial.read() ); //read it and put it on the serial line
  }
}</code></pre><p>Now how to get that on to the Arduino? This is always a bit of fun. I prefer to use the web-based developer at  on the <a href="https://create.arduino.cc/">Arduino website</a> though you might want to download and use the offline one. Either copy and paste, or type in (my preference - you learn more) that code. I've <a href="https://create.arduino.cc/editor/ohowson/cf6cdb25-a2b5-45a5-a05d-88268ddeb4f5/preview">linked to the sketch here</a>.</p><ul><li>Power on your 3.3v to fire up the esp8266</li><li>Plug your Arduino into the computer</li><li>At the top, you need to choose the board. I chose the **Arduino Nano** (I knew that bit) then fiddled with the options until I got the right one (mine is using the old bootloader and COM7).</li><li>(If you've not used your Arduino before you may want to try <a href="https://create.arduino.cc/editor/ohowson/5c867e3a-3c5a-4eb1-8c80-40a866835b86/preview">this code</a> which just blinks the in-built LED slowly. I use this rather than the standard 'blink' code as that sometimes comes built in and you don't know if yours has worked or not!)</li><li>On the left hand side of the screen, under <strong>&gt;EDITOR</strong> there is a Monitor button - click that so you can see what the Arduino is doing. In the left hand dropdown choose <strong>Both NL &amp; CR</strong> (this uses \r\n as a line terminator which is what the ESP8266 uses) and select <strong>9600 baud</strong> in the other one - this is the speed we have told the Arduino to communicate with the computer at.</li><li>Now press the right arrow to upload (hopefully) to your Nano.</li><li>Hopefully the avrdude will say 'done. Thank you.' and in the monitor window it will say 'Ready'</li></ul><figure class="kg-card kg-image-card"><img src="https://badllama.net/content/images/2020/05/image.png" class="kg-image"></figure><p>Mistakes I made (in the interest of honesty) I originally used an alternative connection having the reset pin high and the CH_PD to D4 but that didn't work (probably because my program didn't match!). I also forgot to ground the Arduino...</p><p>Now let's have a play with this ESP8266 and see whether we can get it to work? </p><!--kg-card-begin: markdown--><p>If you type in:<br>
<code>AT</code> and hit <code>Enter</code><br>
The ESP8266, via the Arduino, should return <code>OK</code><br>
It may or may not also return a bunch of gibberish. My first one did because it couldn't cope with the communication speed (or maybe the Arduino couldn't I don't know), my second one oddly didn't. Either way we will tell the ESP8266 to reduce down to 9600 baud which we know will work.<br>
<code>AT+UART_DEF=9600,8,1,0,0</code> and hit <code>Enter</code></p>
<p>Now we need to adjust the code - change line 7 to read 9600 - I've <a href="https://create.arduino.cc/editor/ohowson/9e396a26-2365-4eb6-8bcb-7f18ef4aca0a/preview">linked to the updated code here</a>.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Reflash and enter <code>AT</code> again to make sure everything is still Ok.<br>
Let's make sure we can connect to the WiFi shall we?<br>
Enter these commands:</p>
<p><code>AT+CWMODE=1</code><br>
This sets the mode to 1 meaning it will act as a station (client). You should get OK back.</p>
<p><code>AT+CWLAP</code> Gets a list of networks the ESP8266 can see. For example I can see:</p>
<pre><code>+CWLAP:(3,&quot;SHELL 1567AF&quot;,-84,&quot;a4:91:b1:15:67:af&quot;,6,53)
+CWLAP:(4,&quot;GDog&quot;,-41,&quot;48:8d:36:1d:8a:cf&quot;,11,56)
+CWLAP:(3,&quot;PLUSNET-T6TJ&quot;,-78,&quot;b8:ee:0e:f0:7a:04&quot;,11,28)
</code></pre>
<p>In the barackets the first number is the type of security, SHELL and PLUSNET use WPA2 and PSK, GDog uses WPA, WPA2 and PSK. Then there's the names, and finally the MAC address of the access point.</p>
<p><code>AT+CWJAP=&quot;YOUR_SSID&quot;,&quot;YOUR_PASSWORD&quot;</code> connects to the WiFi network with the given SSID (network name) and password.</p>
<p>When I ran this I got:</p>
<pre><code>WIFI DISCONNECT
WIFI CONNECTED
WIFI GOT IP

OK
</code></pre>
<p>Which is fairly clear, it disconnects if relevant, reconnects, gets an IP address and then say's all is OK.</p>
<p>Finally:<br>
<code>AT+CIFSR</code> Get's and reports the IP address and MAC address of the ESP8266. I got:</p>
<pre><code>+CIFSR:STAIP,&quot;192.168.1.139&quot;
+CIFSR:STAMAC,&quot;5c:cf:7f:49:d4:ca&quot;
</code></pre>
<p>And to prove this worked, I can open up a terminal/command line on my PC and ping that address:</p>
<p><img src="https://badllama.net/content/images/2020/05/ping.png" alt="ping"></p>
<p>A useful <a href="https://room-15.github.io/blog/2015/03/26/esp8266-at-command-reference/">list of known AT commands for the ESP8266 is available here</a>.</p>
<!--kg-card-end: markdown--><p>And that's pretty much us; we've successfully connected the ESP8266 to WiFi, via our Arduino (the cheapest one available not an expensive Mega or Uno or anything) and can move on to the next tutorial. Whoo.</p>]]></content:encoded></item><item><title><![CDATA[CPD in a Box]]></title><description><![CDATA[<p>Maybe not the most influential idea I've ever had, but one which has proven effective and others have shown interest in.</p><p>As I mentioned in my <a href="https://badllama.net/brown-box-computing/">previous blog post</a>, I was once stuck with a decent number of teachers needing CPD. In a pub. In Bletchley. Additional challenges included some</p>]]></description><link>https://badllama.net/cpd-in-a-box/</link><guid isPermaLink="false">5e357ca7df31ef04bc4bdc4d</guid><dc:creator><![CDATA[Oli Howson]]></dc:creator><pubDate>Sat, 01 Feb 2020 13:39:07 GMT</pubDate><content:encoded><![CDATA[<p>Maybe not the most influential idea I've ever had, but one which has proven effective and others have shown interest in.</p><p>As I mentioned in my <a href="https://badllama.net/brown-box-computing/">previous blog post</a>, I was once stuck with a decent number of teachers needing CPD. In a pub. In Bletchley. Additional challenges included some teachers being KS3 only, some being A-level, some being new, some being experienced; the traditional stand up and talk CPD was never going to work. In fact, why do we ever think that's best? Teachers are constantly being told not to lecture, then sit there and expect to be lectured at CPD!</p><p>So a new concept was needed - and CPD in a Box was invented. While I have the intention of producing these, the concept is simple:</p><!--kg-card-begin: markdown--><ol>
<li>Take a box. This will be the box which your CPD will be in. Choose your box carefully. You should choose for space, compactness, robustness... or whatever you have lying around. I chose your common or garden <a href="https://www.amazon.co.uk/gp/slredirect/picassoRedirect.html/ref=pa_sp_atf_aps_sr_pg1_1?ie=UTF8&amp;adId=A06000842NCB46S3RD7T5&amp;url=%2FOffice-Files-Colourful-Spring-Foolscap%2Fdp%2FB07Q6297VZ%2Fref%3Dsr_1_1_sspa%3Fcrid%3D3HN04IPGQ121Y%26keywords%3Dbox%2Bfiles%26qid%3D1580563936%26sprefix%3Dbox%2Bfiles%252Caps%252C394%26sr%3D8-1-spons%26psc%3D1&amp;qualifier=1580563936&amp;id=1871820638028697&amp;widgetName=sp_atf">box file</a>.</li>
<li>Choose a CPD topic. Try and keep it to a single topic. I created the <a href="https://badllama.net/brown-box-computing/">PCH BBC LTE</a>, one on graphics, and two-three others.</li>
<li>Create a booklet to deliver the CPD theory. I made mine in PowerPoint and printed out at about postcard size, laminated, bound (with a treasury tag). These included specification links, QR codes to further information and/or videos, simple step-by-step theory, and anything else relevant.</li>
<li>Include props. I actually think this is the most important bit - props make CPD fun. Be it the mini brown box computers, cards to draw on for bitmap theory, things to sort and search... this is what makes the boxes actually useful.</li>
</ol>
<!--kg-card-end: markdown--><p>My teachers split themselves into 4-5 groups, each with a box, and worked through them as a group. Each group had roughly 20 minutes before cleaning, re-packing and swapping around.</p><p>The novelty was good, the CPD was effective, and fun was had. What more could one want?</p><p></p><p>Prebuilt versions will be on sale soon: <a href="mailto:info@ictsoeasy.co.uk?subject=CPD In a Box">ask to be kept in the loop</a>.</p>]]></content:encoded></item><item><title><![CDATA[Brown Box Computing]]></title><description><![CDATA[<h2 id="where-did-this-idea-come-from">Where did this idea come from?</h2><p>Firstly it is important to be clear about names. The full name is 'The Paul Curzon Honorary Brown Box Computer'; </p><p><a href="https://www.eecs.qmul.ac.uk/~pc/">Professor Paul Curzon</a> is a bit of a hero of mine. In a time when I was looking for every opportunity under the sun</p>]]></description><link>https://badllama.net/brown-box-computing/</link><guid isPermaLink="false">5e2ffed3df31ef04bc4bdb80</guid><category><![CDATA[school]]></category><category><![CDATA[teaching]]></category><category><![CDATA[pedagogy]]></category><category><![CDATA[computer science]]></category><category><![CDATA[computing]]></category><category><![CDATA[unplugged]]></category><category><![CDATA[function]]></category><category><![CDATA[subroutine]]></category><category><![CDATA[procedure]]></category><category><![CDATA[children]]></category><category><![CDATA[learning]]></category><dc:creator><![CDATA[Oli Howson]]></dc:creator><pubDate>Tue, 28 Jan 2020 10:18:23 GMT</pubDate><media:content url="https://badllama.net/content/images/2020/01/child-in-box.jpg" medium="image"/><content:encoded><![CDATA[<h2 id="where-did-this-idea-come-from">Where did this idea come from?</h2><img src="https://badllama.net/content/images/2020/01/child-in-box.jpg" alt="Brown Box Computing"><p>Firstly it is important to be clear about names. The full name is 'The Paul Curzon Honorary Brown Box Computer'; </p><p><a href="https://www.eecs.qmul.ac.uk/~pc/">Professor Paul Curzon</a> is a bit of a hero of mine. In a time when I was looking for every opportunity under the sun to computerise learning, he introduced me to the concept of <a href="https://csunplugged.org/en/">unplugged computing</a>. The concept of teaching Computer Science concepts without using computers is novel, non-obvious, and once you have tried it and tried it well, bloody amazing. I have used many suggestions from Paul and other sources in my teaching and have rolled it up into lessons, interviews, teacher training and CPD delivery.</p><p>One problem I faced as a teacher (of many!) was the concept of teaching procedural programs and effective decomposition. I mean - ok - how do you teach these concepts without actually using a computer? Another problem I - and every teacher in the world - have faced is that some children are <strong>annoying</strong>. So annoying that sometimes it would be nice to just put them in a box out of the way somewhere. All teachers have thought this - some of them just don't admit it. </p><p>One day a magical combination came together; I was pondering this problem, it was an inset day not ruled by hours of 'new initiatives', and the right thing came up on Facebook Marketplace: boxes. Big boxes. Boxes from a double bed. The spark happened and, having a <a href="https://www.themobilelandlords.co.uk/">boss</a> (he didn't run the coolest bar in Southern England then!) who for some reason trusted me I jumped in the school minibus and tootled over to Croydon to pick them up.</p><p>Now; How does this work then? Well it's still a work in progress and more possibilities are coming to my mind all the time.</p><h2 id="version-1"><strong>Version 1</strong></h2><p>These boxes were big and awesome. I wrote out an algorithm that I could easily decompose into three subroutines - in this case Pythagoras' theorem. The subroutines were <strong>add</strong>, <strong>power</strong> and <strong>root</strong>. Each box had one or more entry slots cut in and one output slots cut in underneath. Slots were about 1/2" high and wide enough for A4 paper. The insides of each slot were named (eg) <strong>a</strong> and <strong>b</strong> and the output slot was named <strong>return</strong>. Different names were labelled on the outside. On the inside of each box was pasted a set of instructions such as 'take the input of a and b. Add them together. Write them on the output card. Post it through the output slot.' Each input and output was on a piece of A4 which was laminated and folded over an inch so it could go through and 'hook' on to the slots. A student sat in each 'subroutine' box with no communication other than the slots and the instructions on the inside of the box. The boxes were open backed - if they are not a torch may be useful. A 'main code' student sat outside with the overall algorithm and used similar input/output 'cards' to collect user input, write it on the cards with a board marker, and pass it in/out of the subroutines until finally they had an output. Hurrah! In this way we were able to demonstrate the decomposition of a program, how subroutines can be used to take in data and put out data, and how the internal names of parameters does not need to correlate to the variable names. </p><h2 id="lessons-learnt">Lessons Learnt</h2><!--kg-card-begin: markdown--><ul>
<li>Put bottom slots low enough so input doesn't cover it!</li>
<li>Use wide masking tape to hold the boxes togther - stick-on velcro doesn't work.</li>
<li>Don't jam the boxes into a Seat Cordoba and drive through central london; your vision will be impaired and you may miss congestion zone instructions.</li>
</ul>
<!--kg-card-end: markdown--><h2 id="version-2">Version 2</h2><p>An initial improvement was the idea of 'swapping out' a subroutine. In this case when we ran through the first time we used a power subroutine that read like this:</p><blockquote>Take input a<br>Take input b<br>Calculate a ^ b (I know - this was for demonstration purposes remember!)<br>Count to 100 in your head<br>Write the result on output<br>Post the output card through the return slot</blockquote><p>We then looked at the algorithm and worked out how to make it faster. One method was to not count to 100, another was to use a cleverer student. We opted for the first method, and 'swapped out' the subroutine box for another one and observed the improvement. This also led to discussion about the importance of prototyping. </p><h2 id="version-3">Version 3</h2><p>The final implemented version is merely an observation. I was running some CPD for a large number of CS teachers across London and made a slight miscalculation - instead of a whole day at <a href="https://www.tnmoc.org/">The National Museum of Computing</a>, we had only two hours. So I did the responsible thing and asked the <a href="https://www.eightbellesbletchley.co.uk/index">local pub</a> if we could go there. They said we could, and I built a number of "CPD in a box" (that's a whole other blog post I reckon!). I wanted to take The PCH BBC (see what I did there?) but really - it wouldn't fit. So with a bit of fiddling we found that toner boxes cut in half can do in a pinch. This is called the PCH BBC LTE (Paul Curzon Honorary Brown Box Computer, LapTop Edition). Mini-post it notes are used for input/output cards, and unless your participants are extra small umpa-lumpa's that can get in a 5" square box they can just sit them on the table in front of them. Much fun was had!</p><h2 id="future-versions">Future Versions</h2><p>This blog post was initiated by a facebook conversation looking for something to do as a large-scale activity and I figured "why not?". The students can be introduced into the concept with an example such as the one above, and then given a bunch of boxes, scissors, card and pens and a problem, and sent to 'build' the program. No coding needed - can be a useful way discuss the use of pseudo-code, structured English or flowcharts, and later on with the collaboration tools in the likes of <a href="https://repl.it">repl.it</a> they could code up the program as well. The possibilities are huge!</p><h2 id="reflections">Reflections</h2><p>This project has had two outcomes apparent upon reflection. It did not turn my students into amazing programmers overnight, but when built as a descriptive tool it helped them comprehend something they were getting caught up in, and when used (latterly) as an introduction tool early on in the teaching phase (why are subroutines normally left so late?!?) it formed a natural progression point which lessened the pain of introducing a concept. </p><p>Secondly is the interest and engagement. Students <em>enjoyed</em> learning in this way, which I believe increases their enjoyment and engagement with the subject. Other staff, visitors, and victims - I mean delegates - of my CPD enjoyed engaging with the concept, discussing it, and being inspired to try new things. Sadly I never got the opportunity to work this with an Ofsted inspection going on - I'm sure they would appreciate children in a box!</p>]]></content:encoded></item><item><title><![CDATA[Write your own Adventure Programs for your Microcomputer: A blast from the past]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>While doing some training with <a href="https://www.linkedin.com/in/tasha-board-775523121/?originalSubdomain=uk">Tasha Board</a> quite some years ago, we were based in a Youth Club-cum-school wherein we found a hoard of Usborne books from the '80s. Amongst these was one entitled 'Write your own adventure programs for your microcomputer' - ISBN <a href="https://www.amazon.co.uk/Adventure-Programmes-Usborne-Computers-Electronics/dp/0860207412/ref=sr_1_2?qid=1573637463&amp;refinements=p_27%3AL.+Howarth&amp;s=books&amp;sr=1-2&amp;text=L.+Howarth">0-86020-741-2</a> if you want to try</p>]]></description><link>https://badllama.net/write-your-own-adventure-programs-for-your-microcomputer-a-blast-from-the-past/</link><guid isPermaLink="false">5dcbccc47ed93f04d04f69cf</guid><category><![CDATA[python]]></category><category><![CDATA[jupyter]]></category><category><![CDATA[adventure game]]></category><category><![CDATA[bbc]]></category><category><![CDATA[basic]]></category><dc:creator><![CDATA[Oli Howson]]></dc:creator><pubDate>Wed, 13 Nov 2019 09:40:30 GMT</pubDate><media:content url="https://badllama.net/content/images/2019/11/9468520.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://badllama.net/content/images/2019/11/9468520.jpg" alt="Write your own Adventure Programs for your Microcomputer: A blast from the past"><p>While doing some training with <a href="https://www.linkedin.com/in/tasha-board-775523121/?originalSubdomain=uk">Tasha Board</a> quite some years ago, we were based in a Youth Club-cum-school wherein we found a hoard of Usborne books from the '80s. Amongst these was one entitled 'Write your own adventure programs for your microcomputer' - ISBN <a href="https://www.amazon.co.uk/Adventure-Programmes-Usborne-Computers-Electronics/dp/0860207412/ref=sr_1_2?qid=1573637463&amp;refinements=p_27%3AL.+Howarth&amp;s=books&amp;sr=1-2&amp;text=L.+Howarth">0-86020-741-2</a> if you want to try and purchase your own copy from Amazon. Published in the heady days of 1983, this veritable tome includes a guide on writing and planning an adventure game, and code listings for the 48K Spectrum, TRS-80, Apple, Dragon, Vic, ZX81, Oric, Pet, and of course the BBC.</p>
<p>I grew up typing in programs from Amstrad Action into my Amstrad CPC464. I was never interested in playing the games, I enjoyed the programming. I thought about installing a BBC Micro emulator on my PC or Mac and typing it in. Then I had a thought: who the hell would want to do - or read about - that? So I went one better and re-wrote the program in Python. Following on from my previous <a href="https://badllama.net/python-opening-files/">blog update</a> this is very much not in a pythonic methodology - I have tried to emulate the BASIC methodology as closely as possible as written by the authors. I've had to make some changes, GOTO/GOSUB featured heavily in the original, as did using) (eg) V and V$ as integer and string variables (yes, they're different) and of course 'loading' data into 1-indexed arrays proved loads of fun. But I've tried to stay as closely as possible.</p>
<p>My next trick will be to re-write using (slightly) more modern approaches to make the same game more re-usable, as I would like to get around to writing an adventure game with my daughters. Again, it won't be totally pythonic, because I'm writing for myself not for other people. It will be Olithonic.<br>
The Pythonised version is available in a <a href="https://jupyter.org/">Juptyter</a> notebook through this <a href="https://github.com/ICTSoEasy/Write-Your-Own-Adventure-Games">Git repository</a>. I am, slowly, working on building up a Jupyter hub host for some students and if I get around to it I will work out a way to host this on their for people to play with and may, or may not, come back and update this post then.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Python - Opening files]]></title><description><![CDATA[<p>An ex-colleague and good friend asked me to look at some code for her recently - she's trying to learn to code and that's a good thing. I helped her fix a few things but it got me thinking about how many learning points there can be from one snippet.</p>]]></description><link>https://badllama.net/python-opening-files/</link><guid isPermaLink="false">5d69381093792504e13e9ed1</guid><dc:creator><![CDATA[Oli Howson]]></dc:creator><pubDate>Fri, 30 Aug 2019 15:00:53 GMT</pubDate><content:encoded><![CDATA[<p>An ex-colleague and good friend asked me to look at some code for her recently - she's trying to learn to code and that's a good thing. I helped her fix a few things but it got me thinking about how many learning points there can be from one snippet.</p><!--kg-card-begin: markdown--><pre><code class="language-Python">songs = open(&quot;Songs list.txt&quot;,&quot;r&quot;)
songs_list = songs.read().splitlines()
songs.close()
</code></pre>
<!--kg-card-end: markdown--><p>So where do we start? Firstly, that file name. I won't comment on the choice (I don't like spaces or capitalisation,  but that's just me!) More importantly, this should be defined as a constant. A constant is a named memory location which can't (or in the case of Python shouldn't) be changed at runtime. We indicate this in Python by using all capitals for the identifier:</p><!--kg-card-begin: markdown--><pre><code class="language-Python">SONGSFILE = &quot;Songs list.txt&quot;
songs = open(SONGSFILE,&quot;r&quot;)
songs_list = songs.read().splitlines()
songs.close()
</code></pre>
<!--kg-card-end: markdown--><p>Now what? Well, what if that file doesn't exist? When a file can't be found, Python will raise an error called an exception. What we should do as a minimum is try to catch that and die gracefully. In this case we raise our own exception (SystemExit) which is an elegant way to close the program.</p><!--kg-card-begin: markdown--><pre><code class="language-Python">SONGSFILE = &quot;Songs list.txt&quot;
try:
    songs = open(SONGSFILE,&quot;r&quot;)
except:
    print(&quot;Sorry, I couldn't find the file!&quot;)
	raise SystemExit
songs_list = songs.read().splitlines()
songs.close()
</code></pre>
<!--kg-card-end: markdown--><p>But wait - maybe we moved the file? Or changed the name? We can be a little bit clever and give the user the chance to fix the error! Note I'm now using songsfile as a variable (and initialising it with a value) so have changed case.</p><!--kg-card-begin: markdown--><pre><code class="language-Python">songsfile = &quot;Songs list.txt&quot;
while True:
    try:
        songs = open(songsfile,&quot;r&quot;)
        break
    except:
        print(&quot;Sorry, I couldn't find the file!&quot;)
        songsfile = input('Enter a correct file name, or hit enter to quit')
        if (songsfile == ''):
            raise SystemExit
songs_list = songs.read().splitlines()
songs.close()
</code></pre>
<!--kg-card-end: markdown--><p>Now we are going to continue trying until we decide to stop. If we get <em>past</em> the <code>open</code> command, then we must have successfully opened the file so we can break out of the loop. If not, then instead of exiting straight away, we ask the user to enter the file name. If they choose to hit enter (i.e. enter an empty string), we exit as before. However, if they do enter something then we go around the loop and try again. </p><p>There is of course potential to look at the data and start deciding whether this data file was valid/correct, but that's a different issue. And it was lovely seeing my friend remembered the <code>close</code> command. Normally you won't notice this is missing, until you go to move/delete/edit the data file and find it's locked!</p><!--kg-card-begin: markdown--><h1 id="update">Update</h1>
<p>A colleague quite rightly contacted me recently pointing out a lack of pythonic 'correctness' on this page; I have included this below, but thought I'd take the opportunity to explain my reasons.</p>
<ol>
<li>I learnt to program a <em>long</em> time ago and fell into Python for dubious reasons; therefore I don't always <em>know</em> about Pythonic methods.</li>
<li>I've taught programming in many languages - (most/many?) other languages don't support this syntax.</li>
<li>It feels icky to me - trusting the computer to close a file feels risky to me.</li>
</ol>
<p>That being said, it's always good to explore different methodologies and I'm more than happy to use and abuse Python as it suits me. So here's <a href="https://sites.google.com/site/undercertainty/home">Alistair</a>'s method.</p>
<pre><code class="language-Python">SONGSFILE = &quot;Songs list.txt&quot;
try:
    with open(SONGSFILE,&quot;r&quot;) as songs:
  songs_list = songs.read().splitlines()
except:
    print(&quot;Sorry, I couldn't find the file!&quot;)
raise SystemExit
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[What exams are we inflicting on our young people?]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>In preparation for an upcoming book I have spent a little bit of time collating some data. My personal feelings are that we put young people through too many formal assessments at age 16. I've gone through the three biggest exam boards in the UK (<a href="https://www.aqa.org.uk/">AQA</a>, <a href="https://www.ocr.org.uk/">OCR</a> and <a href="https://qualifications.pearson.com/en/home.html">Edexcel</a>) and</p>]]></description><link>https://badllama.net/what-exams-are-we-inflicting-on-our-young-people/</link><guid isPermaLink="false">5d36e63a1a123204ea92adcc</guid><dc:creator><![CDATA[Oli Howson]]></dc:creator><pubDate>Tue, 23 Jul 2019 11:20:08 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>In preparation for an upcoming book I have spent a little bit of time collating some data. My personal feelings are that we put young people through too many formal assessments at age 16. I've gone through the three biggest exam boards in the UK (<a href="https://www.aqa.org.uk/">AQA</a>, <a href="https://www.ocr.org.uk/">OCR</a> and <a href="https://qualifications.pearson.com/en/home.html">Edexcel</a>) and looked at what an averagely bright student might have to sit. This is making some assumptions:</p>
<ol>
<li>They sit all exams with a single exam board (with the exception of OCR who no longer offer MFL GCSEs).</li>
<li>They take a minimal amount of subjects. Some (many?) schools have their students sit more than the minimum - particularly as English Literature often leads to poorer grades than language, so will be included to double-up the English grade in Progress 8, but a different subject included for the actual grade needed.</li>
</ol>
<p>Some times were rounded slightly.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://badllama.net/content/images/2019/07/image-11.png" class="kg-image"></figure><!--kg-card-begin: markdown--><p>What does this mean in real world terms? Secondary age children spend 190 days in school each year. With an average of 5 hours a day of lessons, this is 950 hours a year, or 1,900 across two years. Very roughly ten weeks of this is lost in Year 11 so that's 250 hours gone, leaving children with 1,650 hours of key stage 4 education.</p>
<p>What about Physical education? Religious education (still mandatory within the UK)? If we were to give these one hour a week each (and it could be argued that one hour a week of PE isn't enough to get them changed never mind actually exercising), then that's an extra 152 hours we need - taking us down to 1498 hours. Any teacher will tell you that they lose probably 5-8 minutes of each lesson due to change over, getting equipment out, etc etc. So if we assume hour lessons we're taking 13% off of each one, 1,298 hours left.</p>
<p>Many schools will assess at the end of each term, and at least approximating the real assessments, so that's five sets of mocks/assessments at 31 hours each (again, if we're using worst cases here), 155 hours. 1,143 hours left.</p>
<p>If we look at the worst case scenario of Edexcel having 31 hours of examinations, this leaves us with 143 hours per subject, or less than 37 hours of teaching for each hour of assessment.</p>
<p>What's the old maxim? It takes 1,000 hours to master something?</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Coding With Kids: A Story of Abstraction]]></title><description><![CDATA[<p>This is a follow up to <a href="https://www.badllama.net/ks2-collaborative-coding/">this blog post</a>. I was contacted by the Head of IT/Computing at St. Michael's Prep School in Kent for some help in a code-a-thon they were running. As part of the <a href="https://instituteofcoding.org/outreach-partners/">outreach</a> within the <a href="https://instituteofcoding.org/">Institute of Coding</a> I agreed to help them out</p>]]></description><link>https://badllama.net/coding-with-kids-a-story-of-abstraction/</link><guid isPermaLink="false">5d0b351e1a123204ea92ace8</guid><category><![CDATA[python]]></category><category><![CDATA[ioc]]></category><category><![CDATA[coding]]></category><category><![CDATA[abstraction]]></category><category><![CDATA[computer science]]></category><category><![CDATA[code]]></category><category><![CDATA[education]]></category><category><![CDATA[open source]]></category><dc:creator><![CDATA[Oli Howson]]></dc:creator><pubDate>Thu, 20 Jun 2019 08:32:47 GMT</pubDate><media:content url="https://badllama.net/content/images/2019/06/Slide8-1.jpeg" medium="image"/><content:encoded><![CDATA[<img src="https://badllama.net/content/images/2019/06/Slide8-1.jpeg" alt="Coding With Kids: A Story of Abstraction"><p>This is a follow up to <a href="https://www.badllama.net/ks2-collaborative-coding/">this blog post</a>. I was contacted by the Head of IT/Computing at St. Michael's Prep School in Kent for some help in a code-a-thon they were running. As part of the <a href="https://instituteofcoding.org/outreach-partners/">outreach</a> within the <a href="https://instituteofcoding.org/">Institute of Coding</a> I agreed to help them out by putting on a session.</p><p>As a teacher of Secondary age pupils I have used <a href="https://docs.python.org/3.3/library/turtle.html?highlight=turtle">Turtle Graphics</a> successfully within Python for both one-off sessions and whole schemes of learning. My go-to is maze solving, navigating the turtle from an entrance to a green piece of 'grass'. However there are challenges and my experience of younger pupils is limited to my own 5 and 8 year old children. </p><h1 id="let-s-consider-the-challenges-faced-">Let's consider the challenges faced:</h1><ul><li>Any accidental changes or deletions of surrounding code (for creating the windows, importing Turtle, drawing the maze, etc) brings the system crashing down.</li><li>Spelling errors and syntactical errors are a common issue which, when used as a scheme of learning are excellent teaching points but when used in a single 50 minute session with unknown children can slow things down to a crawl.</li><li>Getting a turtle through a maze can be time consuming. Children are not known for their ability to focus for long periods of time and get bored quickly.</li><li>Paired programming is a powerful tool but in the traditional environments (Idle, PyScripter, <a href="http://trinket.io">Trinket.io</a>) that I have used means two children sitting around one computer. Although I have no empirical data, my own observations of this suggest one pupil does all the work while the other sits and stares into space.</li><li>Getting software set up on school networks can be challenging. Getting multiple bits of software set up (eg an interpreter and an IDE) can be even more challenging and as most IT technicians are not programmers, can be difficult to check.</li></ul><h1 id="so-what-was-the-solution">So what was the solution?</h1><p>I wrote a piece of software to abstract the complexities away from the students. </p><ul><li>I wrote a Google script to automatically create and then share for anonymous editing a large number of blank Google documents. This was organised into a single folder which could be linked to by the students, and sub-folders for each 'challenge' (each challenge being a maze).</li><li>All code is entered into this Google document and can be edited by multiple pupils at once, enabling a simple shared programming methodology. The added bonus is that Google documents take care of some of the spelling issues!</li><li>I wrote a Python program designed to be run with a double-click and minimal input - the current challenge and the team number.</li><li>All dependencies were included with the program so as to avoid the need (and time) to install dependencies (and possible version conflicts) on machines by non-expert IT technicians.</li><li>The program interpreted the code from the Google document line by line and attempted to run it. Any lines that couldn't be run resulted in an error message but did not stop execution. One unpredicted advantage of this was allowing students to collaborate by writing notes to one another at the bottom of the page.</li></ul><h1 id="discussion">Discussion</h1><ul><li>The Google script is limited to producing only a couple of hundred documents per day, and tends to time out after about 100. These limitations can be overcome with a paid Google account (I think). </li><li>One thing highlighted by this project is that shared programming is not something that can just happen. Students were, generally, happy to take turns typing but there was minimal job-sharing or, for want of a better term, modular coding. Perhaps this is a training issue, but if so 50 minutes is not enough time to be able to make that training happen. Having students both sat side-by-side and separately was tried, with the side-by-side method seeming to bring forth greater progress.</li><li>While running the program was not a problem for the students, they did mess up typing in the numbers sometimes. While this in itself wasn't a major problem having to close the Turtle window and re-run/re-enter the details each time meant it did crop up, with the additional issue that the students sometimes closed the wrong window, needing assistance. Either a GUI or some sort of close-redraw prompted loop would reduce this problem.</li><li>Links to the documents and the coding of the mazes were hard-coded into the program. More flexibility could be achieved by having this loaded dynamically from a central repository.</li><li>A number of common syntactical errors were dealt with in a 'soft' manner, including capitalisation, rogue spaces and some previously detected spelling errors. Much like the links and mazes, flexibility could have been added by having alternative spellings in a central location that could be updated 'on the fly' as new errors were spotted.</li></ul><!--kg-card-begin: markdown--><h1 id="todowishlist">To-Do/Wish-list</h1>
<ul>
<li>A GUI or at least code-try-recode-retry looped program rather than having to re-run the program each time.</li>
<li>A way to couple document creation with the main program.</li>
<li>Logging and telemetry for data analysis.</li>
<li>Further development of the accepted language:
<ul>
<li>Variables (usable in loops and/or distances/angles)</li>
<li>Input (for assigning to variables)</li>
<li>Collision detection (for hitting walls and/or arriving at grass)</li>
</ul>
</li>
</ul>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h1 id="conclusion">Conclusion</h1>
<p>The project, and the day, were a success. The children enjoyed themselves and made progress, although I've not heard back from the school regarding any direct feedback from the pupil survey yet. Some students who have never programmed before have now done so, and left the room excited about coding and Computer Science in general. That's a win.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2019/06/Slide8.jpeg" width="720" height="498" alt="Coding With Kids: A Story of Abstraction"></div><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2019/06/D9WCWw-X4AAXJYb.jpg" width="2048" height="1365" alt="Coding With Kids: A Story of Abstraction"></div><div class="kg-gallery-image"><img src="https://badllama.net/content/images/2019/06/D9VQVHzWwAE3AvK.jpg" width="2048" height="1365" alt="Coding With Kids: A Story of Abstraction"></div></div></div><figcaption>Photos copyright St. Michael's Prep School, Kent</figcaption></figure><p>All files are available on <a href="https://github.com/ICTSoEasy/TurtleIt">GitHub</a></p>]]></content:encoded></item></channel></rss>