webtrekker Posted December 12, 2024 Share Posted December 12, 2024 (edited) A good while ago, I coded my own web app to produce some nice-looking dials that showed me the current weather for locations all over the globe. This week, I decided I'd like to have a weather charting app that pulled weather data (from the openweathermap.org API) for my location every hour of every day and produced charts of the data so that I had a historical record of the local weather. Now then, although I'm quite capable of producing such an app, it is very time-consuming, so I thought I'd give ChatGPT AI a go at producing the code for me. After numerous prompts to tweak things and get ChatGPT to correct its errors, it finally produced something worthwhile and capable of doing the job, with no actual code written by me! What the code does is, it calls a PHP script every hour that retrieves the data (in JSON format) from openweathermap, parses it, adds a timestamp, then saves it as a CSV file on my server. To view the data logged so far, an HTML/JS file can be run in any browser that gets the CSV data from the server and produces charts of it using a JS script called 'chart.js.' I'm logging data for Temperature, Humidity, Windspeed and Pressure, and these can be shown on 4 different charts using the Radio Buttons above the chart area. The charts can be zoomed and panned as needed, and a Tooltip appears when hovering over any data point to show the time and value of that point. I've only logged 10 hours so far, but everything is working fine and, as time progresses, I will have some valuable data to look back on. All in all, not bad for a FREE weather station that requires NO CODING! (Of course, your AI prompts need to be well-thought-out though, so previous coding knowledge is advantageous). Edited December 12, 2024 by webtrekker 1 Quote Link to comment Share on other sites More sharing options...
Campion Posted December 12, 2024 Share Posted December 12, 2024 Nice one @webtrekker , I'm a bit envious because I'm trying to teach myself some coding (in python) but only making slow progress. Quote Link to comment Share on other sites More sharing options...
webtrekker Posted December 13, 2024 Author Share Posted December 13, 2024 (edited) 4 hours ago, Campion said: Nice one @webtrekker , I'm a bit envious because I'm trying to teach myself some coding (in python) but only making slow progress. I've had a look at Python before but, as most of my interest lies in producing web apps, I decided to stick with PHP for the back-end (server-side) and HTML + JavaScript for the front-end (Client/Browser-side). It all depends on your end goals, really. Mind you, I'm not saying I'm an expert in any of these languages, but I get by, and there's a ton of help and code-snippets on the net to make things easier. All of my work is done inside Notepad++ (no fancy IDE's for me!). I use 123Reg (previously TSO-Host) for webspace and simply edit my code in Notepad++ and upload it directly from there. One thing I'm tending to use more and more is AI. I find ChatGPT is very good at writing code (PHP, JS, Python, ... you name it!) from prompts. I can then copy the code and paste it into NP++, upload it, and try running it in the browser. Any issues can usually be corrected with further prompts in ChatGPT to refine the code until it performs in the way I had intended. With regard to JavaScript, there are many JS Libraries that can be included in your HTML to perform certain tasks, such as the charts produced in my Weather app, which uses chart.js to handle the donkey work. Whatever language you decide to use for the back-end, I'd definitely say you need to learn JavaScript (as well as HTML, for the mark-up) on the front-end too. Of course, if your intention is to produce apps that execute outside of the browser environment, then you can learn any programming language, even BASIC. I've grown fond of web apps, though, as I can run them on any device anywhere in the world that has an internet connection. I once wrote a program for handling Gift Cards for my daughter's sweet shop. The app used PHP and MySQL Database to scan and record data from barcodes that had been printed on the cards. It ran in the Opera browser on the screen of the POS (Point-Of-Sale) till she had on the counter. Anyway, I'm starting to bore even myself now, so I'll leave it there for the time being! [PS. A word of warning! When coding for the web, make sure any user input to your code (Client-side or Server-side) is properly 'Sanitized' before you upload the code. ChatGPT is particularly good at sanitizing PHP and JS code for you. I know it's extra work, but you don't want to learn the hard way by having all of your server files attacked and deleted, or corrupted!]. Edited December 13, 2024 by webtrekker 1 Quote Link to comment Share on other sites More sharing options...
webtrekker Posted December 13, 2024 Author Share Posted December 13, 2024 Here is ChatGPT in action... I gave it a simple enough Prompt to produce a Biorhythm Chart - It eventually produced HTML and JS code, which I uploaded and ran in Firefox to produce the following Biorhythm Chart for Elvis Presley (8 Jan 1935)... The curves can be toggled on/off using the coloured buttons in the Legend It's as easy as that! (well, sort of) using just ChatGPT AI to write your code. 1 Quote Link to comment Share on other sites More sharing options...
webtrekker Posted December 13, 2024 Author Share Posted December 13, 2024 Here's the Biorhythm code for anyone interested in running it themselves ... bio_chart.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Biorhythm Chart</title> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <style> body { font-family: Arial, sans-serif; margin: 0; padding: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; overflow: hidden; } canvas { width: 100vw; height: 75vh; } form { margin-bottom: 20px; } </style> </head> <body> <h1>Biorhythm Chart</h1> <form id="dob-form"> <label for="dob">Enter your date of birth:</label> <input type="date" id="dob" name="dob" required> <button type="submit">Generate Chart</button> </form> <canvas id="biorhythmChart"></canvas> <script> document.getElementById('dob-form').addEventListener('submit', function(event) { event.preventDefault(); // Prevent form submission const dobInput = document.getElementById('dob').value; // Sanitize input if (!dobInput || !/^\d{4}-\d{2}-\d{2}$/.test(dobInput)) { alert('Please enter a valid date of birth.'); return; } const dob = new Date(dobInput); if (isNaN(dob.getTime())) { alert('Invalid date. Please try again.'); return; } const today = new Date(); const dates = []; const physical = []; const emotional = []; const intellectual = []; for (let i = 0; i < 30; i++) { const currentDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + i); dates.push(currentDate.toISOString().split('T')[0]); const daysAlive = Math.floor((currentDate - dob) / (1000 * 60 * 60 * 24)); physical.push(Math.sin((2 * Math.PI * daysAlive) / 23)); emotional.push(Math.sin((2 * Math.PI * daysAlive) / 28)); intellectual.push(Math.sin((2 * Math.PI * daysAlive) / 33)); } const ctx = document.getElementById('biorhythmChart').getContext('2d'); new Chart(ctx, { type: 'line', // Changed chart type to 'line' which supports filling the area data: { labels: dates, datasets: [ { label: 'Physical', data: physical, borderColor: 'red', backgroundColor: 'rgba(255, 0, 0, 0.2)', // Filled area with semi-transparent color fill: true, tension: 0.1 }, { label: 'Emotional', data: emotional, borderColor: 'blue', backgroundColor: 'rgba(0, 0, 255, 0.2)', // Filled area with semi-transparent color fill: true, tension: 0.1 }, { label: 'Intellectual', data: intellectual, borderColor: 'green', backgroundColor: 'rgba(0, 255, 0, 0.2)', // Filled area with semi-transparent color fill: true, tension: 0.1 } ] }, options: { responsive: true, maintainAspectRatio: false, scales: { x: { title: { display: true, text: 'Date' }, ticks: { autoSkip: true, maxRotation: 45, minRotation: 45, padding: 10 // Padding for the ticks to avoid overlap } }, y: { title: { display: true, text: 'Value' }, suggestedMin: -1, suggestedMax: 1 } }, plugins: { legend: { position: 'top', } }, layout: { padding: { bottom: 40 // Increased padding to give more space for x-axis labels } } } }); }); </script> </body> </html> 1 Quote Link to comment Share on other sites More sharing options...
webtrekker Posted December 13, 2024 Author Share Posted December 13, 2024 (edited) I've added an 'Average' option to the Biorhythm chart which averages the 3 curves for each day and plots a new curve (Black, dashed). I've also reformatted the X-axis labels to make them easier to read. Here's the complete code for anyone interested ... bio_chart.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Biorhythm Chart</title> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/moment.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment"></script> <style> body { font-family: Arial, sans-serif; margin: 0; padding: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; overflow: hidden; } canvas { width: 100vw; height: 75vh; } form { margin-bottom: 20px; } </style> </head> <body> <h1>Biorhythm Chart</h1> <form id="dob-form"> <label for="dob">Enter your date of birth:</label> <input type="date" id="dob" name="dob" required> <button type="submit">Generate Chart</button> </form> <canvas id="biorhythmChart"></canvas> <script> document.getElementById('dob-form').addEventListener('submit', function(event) { event.preventDefault(); // Prevent form submission const dobInput = document.getElementById('dob').value; // Input sanitization if (!dobInput || !/\d{4}-\d{2}-\d{2}/.test(dobInput)) { alert('Please enter a valid date in the format YYYY-MM-DD.'); return; } const dob = new Date(dobInput); if (isNaN(dob.getTime())) { alert('Invalid date. Please try again.'); return; } const today = new Date(); const dates = []; const physical = []; const emotional = []; const intellectual = []; const average = []; for (let i = 0; i < 30; i++) { const currentDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + i); const formattedDate = moment(currentDate).format('YYYY-MM-DD'); // Properly formatted date dates.push(formattedDate); const daysAlive = Math.floor((currentDate - dob) / (1000 * 60 * 60 * 24)); const phys = Math.sin((2 * Math.PI * daysAlive) / 23); const emo = Math.sin((2 * Math.PI * daysAlive) / 28); const intel = Math.sin((2 * Math.PI * daysAlive) / 33); physical.push(phys); emotional.push(emo); intellectual.push(intel); // Calculate the average average.push((phys + emo + intel) / 3); } const ctx = document.getElementById('biorhythmChart').getContext('2d'); new Chart(ctx, { type: 'line', data: { labels: dates, // Dates formatted in ISO 8601 datasets: [ { label: 'Physical', data: physical, borderColor: 'red', backgroundColor: 'rgba(255, 0, 0, 0.2)', fill: true, tension: 0.1 }, { label: 'Emotional', data: emotional, borderColor: 'blue', backgroundColor: 'rgba(0, 0, 255, 0.2)', fill: true, tension: 0.1 }, { label: 'Intellectual', data: intellectual, borderColor: 'green', backgroundColor: 'rgba(0, 255, 0, 0.2)', fill: true, tension: 0.1 }, { label: 'Average', data: average, borderColor: 'black', borderDash: [5, 5], // Dashed line for average fill: false, tension: 0.1 } ] }, options: { responsive: true, maintainAspectRatio: false, scales: { x: { type: 'time', // Set x-axis as time time: { parser: 'YYYY-MM-DD', // Parse input dates correctly unit: 'day', displayFormats: { day: 'MMM D' // Format for x-axis labels (e.g., Dec 13) } }, title: { display: true, text: 'Date' }, ticks: { autoSkip: true, maxRotation: 45, minRotation: 45, padding: 10 } }, y: { title: { display: true, text: 'Value' }, suggestedMin: -1, suggestedMax: 1, grid: { drawOnChartArea: true, color: (context) => { return context.tick.value === 0 ? 'black' : 'rgba(0, 0, 0, 0.1)'; }, lineWidth: (context) => { return context.tick.value === 0 ? 2 : 1; } } } }, plugins: { legend: { position: 'top', } }, layout: { padding: { bottom: 40 } } } }); }); </script> </body> </html> The result (current Biorhythm for Nikola Tesla ) ... Edited December 13, 2024 by webtrekker 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.