Source Code Snippets of "Generate_HTML.py"

Mike Dinder

The entire contents of the "Generate_HTML.py" file as code examples with syntax highlighting

Auto Generated Using Generate_HTML.py script to auto format each of these pages in a standardized template.

On smaller viewports/windows, please scroll or use your touch/finger to scroll left to right to view all the code displayed.

Generate_HTML Python Home
                            # Use this file to generate HTML Files that embed Python Files as display code on that page, for educational and
# resume purposes only.
from os import listdir
from os.path import isfile, join


def generate_html_with_code(filename=None, fn_no_ext=None, output_html_path=None, directory=None) -> None:
"""
Generate an single HTML file, one for each Python file found in the directory specified. Generates using a
pre-formatted code snippet template for displaying code in a clean and user friendly way on the internet.

:param filename: String, the filename of the code that is being generated.
:param fn_no_ext: String, the filename without the file extension of the code that is being generated.
:param output_html_path: String, output path that represents where the generated file will be created.
:param directory: String, path that represents the working directory of this file.
:returns: Nothing
:rtype: None
"""
human_readable_name = filename.replace('_', ' ')
human_readable_name = human_readable_name.replace('.py', '')

try:
with open(directory + filename, 'r', encoding='utf-8') as f:
code_content = f.read()
except FileNotFoundError:
print(f'Error: The READ File "{filename}" Was Not Found.')
except Exception as e:
print(f'An Error Occurred: {e}')
else:
# HTML Template with <pre> and <code> Tags
html_content = f"""
<!DOCTYPE html>
<html lang="en">
    <head>
        <!-- Character Encoding -->
        <meta charset="UTF-8">

        <!-- Viewport for Responsive Design -->
        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <!-- Page Title -->
        <title>Python {filename} Source Code</title>

        <!-- Meta Description for SEO -->
        <meta name="description" content="A practice code page for displaying Python {human_readable_name} Code Snippets.">

        <!-- Meta Keywords -->
        <meta name="keywords" content="code, snippets, python, programming, syntax highlighting, development">

        <!-- Author Information -->
        <meta name="author" content="Mike Dinder">

        <!-- HTTP Equiv Headers -->
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

        <!-- Robots Meta Tag -->
        <meta name="robots" content="index, follow">

        <!-- Meta Description for SEO -->
        <meta name="description" content="A personal Mike Dinder project dedicated to Python {human_readable_name} Code Snippets.">

        <!-- Meta Keywords -->
        <meta name="keywords" content="mike dinder, michael dinder, python projects, python code, python">

        <!-- Open Graph Meta Tags for Social Media -->
        <meta property="og:title" content="Display Python {human_readable_name} Code Snippets">
        <meta property="og:description" content="A practice code page for displaying Python {human_readable_name} Code Snippets.">
        <meta property="og:type" content="website">
        <meta property="og:url" content="https://python.mikedinder.com/{output_html_path}">
        <meta property="og:image" content="https://python.mikedinder.com/Images/python-3d.jpg">

        <!-- Twitter Card Meta Tags -->
        <meta name="twitter:card" content="summary_large_image">
        <meta name="twitter:title" content="Display Python {human_readable_name} Code Snippets">
        <meta name="twitter:description" content="A practice code page for displaying Python {human_readable_name} Code Snippets.">
        <meta name="twitter:image" content="https://python.mikedinder.com/Images/python-3d.jpg">

        <!-- All Browser Legacy Support -->
        <link rel="icon" type="image/x-icon" href="https://python.mikedinder.com/favicon.ico">

        <!-- Fallback for browsers that don't support SVG favicons -->
        <link rel="icon" type="image/png" sizes="32x32" href="https://python.mikedinder.com/Images/favicon-32x32.png">
        <link rel="icon" type="image/png" sizes="16x16" href="https://python.mikedinder.com/Images/favicon-16x16.png">

        <!-- Apple Touch Icons (iOS/iPadOS home screen) -->
        <link rel="apple-touch-icon" sizes="180x180" href="https://python.mikedinder.com/Images/apple-touch-icon.png">

        <!-- Android Chrome -->
        <link rel="icon" type="image/png" sizes="192x192" href="https://python.mikedinder.com/Images/android-chrome-192x192.png">
        <link rel="icon" type="image/png" sizes="512x512" href="https://python.mikedinder.com/Images/android-chrome-512x512.png">

        <!-- Theme Color for Mobile Browsers -->
        <meta name="theme-color" content="#ffd43b">

        <!-- Font Awesome -->
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">

        <!-- Preconnect to CDN for Performance -->
        <!-- <link rel="preconnect" href="https://cdnjs.cloudflare.com"> -->

        <!-- Highlight.js for Syntax Highlighting -->
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>

        <!-- Run Python in the Clients Web Browser with WebAssembly -->
        <link rel="preconnect" href="https://fonts.googleapis.com">
        <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;700&family=Syne:wght@400;700;800&display=swap" rel="stylesheet">
        <!-- <script src="https://cdn.jsdelivr.net/pyodide/v0.25.0/full/pyodide.js"></script> -->
        <script src="https://cdn.jsdelivr.net/pyodide/v0.29.3/full/pyodide.js"></script>

        <!-- Custom Styles -->
        <style type="text/css">
            * {{
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }}

            :root {{
                --bg: #0d0d0f;
                --surface: #141416;
                --border: #252528;
                --accent: #7fff6e;
                --accent2: #4fc3f7;
                --text: #e8e8ec;
                --muted: #666672;
                --error: #ff6b6b;
                --warn: #ffd166;
            }}

            body {{
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
                line-height: 1.6;
                color: #e2e8f0;
                background: #030b1a;
                min-height: 100vh;
                padding: 20px;
                display: flex;
                flex-direction: column;
            }}

            .mobile-br {{
                display: none;
            }}

            .container {{
                max-width: 1160px;
                margin: 0 auto;
                z-index: 3;
            }}

            /* Stars background */
            #stars-canvas {{
                position: fixed;
                top: 0; left: 0;
                width: 100%; height: 100%;
                z-index: 0;
                pointer-events: none;
            }}

            header {{
                text-align: center;
                margin-bottom: 40px;
                padding: 20px;
            }}

            h1 {{
                font-size: 2.4em;
                color: #60a5fa;
                margin-bottom: 10px;
            }}

            .subtitle {{
                color: #94a3b8;
                font-size: 1.1em;
            }}

            .snippet-container {{
                background: #1e293b;
                border-radius: 12px;
                box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
                margin-bottom: 30px;
                overflow: hidden;
                border: 1px solid #334155;
            }}

            .snippet-header {{
                background: #0f172a;
                padding: 15px 20px;
                border-bottom: 1px solid #334155;
                display: flex;
                justify-content: space-between;
                align-items: center;
            }}

            .snippet-title {{
                color: #f1f5f9;
                font-size: 1.1em;
                font-weight: 600;
            }}

            .language-badge {{
                background: #062557;
                color: white;
                padding: 5px 12px;
                border-radius: 20px;
                border: 1px solid transparent;
                font-size: 0.85em;
                font-weight: 500;
                text-decoration: none;
                transition: all 0.3s ease;
            }}

            .language-badge:hover,
            .language-badge:active,
            .language-badge:focus {{
                background: #01183c;
                border: 1px solid #4380e2;
            }}

            .snippet-body {{
                position: relative;
            }}

            pre {{
                margin: 0;
                padding: 2.6em 0 0.5em;
                overflow-x: auto;
                position: relative;
                z-index: 4;
            }}

            code {{
                font-family: 'Courier New', Courier, monospace;
                font-size: 0.95em;
            }}

            .run-dialog {{
                width: 100%;
                position: absolute;
                bottom: 0;
                padding: 0 1em 1em;
                white-space: pre-line;
                display: flex;
                justify-content: space-between;
                align-items: center;
            }}

            .run-dialog p:before {{
                content: '*';
                position: absolute;
                top: 0;
                left: 0.25em;
                font-size: 0.9em;
            }}

            .run-btn {{
                width: 126px;
                background: #3b82f6;
                color: white;
                border: 1px solid transparent;
                padding: 0.5em;
                border-radius: 17.5px;
                cursor: pointer;
                font-size: 0.9em;
                transition: all 0.3s ease;
                flex-shrink: 0;
            }}

            .run-btn:hover,
            .run-btn:active,
            .run-btn:focus {{
                background: #2563eb;
                border: 1px solid #95bdfd;
            }}

            .copy-button {{
                position: absolute;
                top: 10px;
                right: 20px;
                background: #3b82f6;
                color: white;
                border: 1px solid transparent;
                padding: 8px 16px;
                border-radius: 17.5px;
                cursor: pointer;
                font-size: 0.9em;
                transition: all 0.3s ease;
                z-index: 5;
            }}

            .copy-button:hover,
            .copy-button:active,
            .copy-button:focus {{
                background: #2563eb;
                border: 1px solid #95bdfd;
            }}

            /* Footer */
            footer {{
                text-align: center;
                padding: 50px 0;
                border-top: 1px solid rgba(51, 102, 153, 0.1);
            }}

            footer p {{
                color: var(--muted);
            }}

            .social-links {{
                display: flex;
                justify-content: center;
                gap: 30px;
                margin-bottom: 20px;
            }}

            .social-link {{
                color: var(--accent);
                font-size: 1.5em;
                transition: all 0.3s ease;
            }}

            .social-link:hover {{
                transform: translateY(-5px) scale(1.2);
                text-shadow: 0 0 20px var(--accent);
            }}

            .input-header {{
                padding: 18px 28px;
                border-bottom: 1px solid var(--border);
                display: flex;
                align-items: center;
                gap: 16px;
                background: var(--surface);
                flex-shrink: 0;
            }}

            .logo {{
                font-family: 'Syne', sans-serif;
                font-weight: 800;
                font-size: 1.1em;
                letter-spacing: -0.02em;
                color: var(--accent);
            }}

            .logo span {{ color: var(--text); opacity: 0.4; }}

            .status {{
                margin-left: auto;
                display: flex;
                align-items: center;
                gap: 8px;
                font-size: 0.72em;
                color: var(--muted);
                letter-spacing: 0.05em;
                text-transform: uppercase;
            }}

            .dot {{
                width: 7px; height: 7px;
                border-radius: 50%;
                background: var(--muted);
                transition: background 0.3s;
            }}
            .dot.ready {{ background: var(--accent); box-shadow: 0 0 8px var(--accent); }}
            .dot.loading {{ background: var(--warn); animation: pulse 1s ease-in-out infinite; }}

            @keyframes pulse {{ 0%,100%{{opacity:1}} 50%{{opacity:0.4}} }}

            #output {{
                flex: 1;
                overflow-y: auto;
                padding: 20px 28px;
                display: flex;
                flex-direction: column;
                gap: 2px;
                scroll-behavior: smooth;
            }}

            .entry {{
                display: flex;
                flex-direction: column;
                gap: 3px;
                padding: 10px 0;
                border-bottom: 1px solid #1a1a1e;
                animation: fadeIn 0.15s ease;
            }}

            @keyframes fadeIn {{ from {{ opacity: 0; transform: translateY(4px); }} to {{ opacity: 1; transform: none; }} }}

            .input-line {{
                display: flex;
                gap: 10px;
                align-items: flex-start;
            }}

            .prompt {{ color: var(--accent); user-select: none; flex-shrink: 0; }}
            .prompt.cont {{ color: var(--muted); }}

            .code-display {{
                color: var(--accent2);
                white-space: pre-wrap;
                word-break: break-all;
                flex: 1;
                line-height: 1.6;
            }}

            .result {{
                padding-left: 28px;
                white-space: pre-wrap;
                word-break: break-all;
                line-height: 1.6;
                font-size: 0.9em;
            }}
            .result.stdout {{ color: var(--text); opacity: 0.85; }}
            .result.value {{ color: var(--warn); }}
            .result.error {{ color: var(--error); }}

            .loading-indicator {{
                padding-left: 28px;
                color: var(--muted);
                font-size: 0.8em;
                animation: pulse 1s infinite;
            }}

            #input-area {{
                border-top: 1px solid var(--border);
                background: var(--surface);
                padding: 16px 28px;
                flex-shrink: 0;
            }}

            .input-row {{
                display: flex;
                align-items: flex-start;
                gap: 10px;
            }}

            #code-input {{
                flex: 1;
                background: transparent;
                border: none;
                outline: none;
                color: var(--accent2);
                font-family: 'JetBrains Mono', monospace;
                font-size: 0.9em;
                resize: none;
                line-height: 1.6;
                min-height: 24px;
                max-height: 200px;
                overflow-y: auto;
                caret-color: var(--accent);
            }}

            #code-input::placeholder {{ color: var(--muted); }}

            .hint {{
                margin-top: 10px;
                font-size: 0.7em;
                color: var(--muted);
                display: flex;
                gap: 20px;
                letter-spacing: 0.03em;
            }}

            .hint kbd {{
                background: var(--border);
                padding: 1px 5px;
                border-radius: 3px;
                font-family: inherit;
                color: var(--text);
                font-size: 0.68em;
            }}

            #output::-webkit-scrollbar {{ width: 4px; }}
            #output::-webkit-scrollbar-track {{ background: transparent; }}
            #output::-webkit-scrollbar-thumb {{ background: var(--border); border-radius: 2px; }}

            .welcome {{
                color: var(--muted);
                font-size: 0.8em;
                padding: 12px 0;
                line-height: 1.8;
                border-bottom: 1px solid #1a1a1e;
            }}
            .welcome .hi {{ color: var(--accent); font-family: 'Syne', sans-serif; font-weight: 700; font-size: 1em; }}

            /* Rocket Ship */
            .rocket {{
                position: fixed;
                width: 20px;
                height: 32px;
                z-index: 2;
                pointer-events: none;
                filter: drop-shadow(0 0 10px var(--star-gold));
                animation: rocketFly 90s infinite linear;
            }}

            .rocket .rocket-ship {{
                width: 100%;
                height: 100%;
                display: block;
            }}

            @keyframes rocketFly {{
                0% {{ left: 0%; top: 48%; transform: rotate(-72deg); opacity: 1; }}
                4.75% {{ left: 10%; top: 38%; transform: rotate(-36deg); opacity: 1; }}
                9.5% {{ left: 20%; top: 28%; transform: rotate(0deg); opacity: 1; }}
                14.25% {{ left: 30%; top: 18%; transform: rotate(36deg); opacity: 1; }}
                19% {{ left: 40%; top: 8%; transform: rotate(72deg); opacity: 1; }}
                23.75% {{ left: 50%; top: 0%; transform: rotate(108deg); opacity: 1; }}
                28.5% {{ left: 60%; top: 8%; transform: rotate(144deg); opacity: 1; }}
                33.25% {{ left: 70%; top: 18%; transform: rotate(180deg); opacity: 1; }}
                38% {{ left: 80%; top: 28%; transform: rotate(216deg); opacity: 1; }}
                42.75% {{ left: 90%; top: 38%; transform: rotate(252deg); opacity: 1; }}
                47.5% {{ left: 100%; top: 48%; transform: rotate(288deg); opacity: 1; }}
                52.1% {{ left: 105%; top: 48%; transform: rotate(288deg); opacity: 1; }}
                52.15% {{ left: 105%; top: 48%; transform: rotate(288deg); opacity: 0; }}

                52.2% {{ left: 0%; top: 48%; transform: rotate(288deg); opacity: 0; }}
                52.25% {{ left: 0%; top: 48%; transform: rotate(288deg); opacity: 1; }}
                57% {{ left: 10%; top: 58%; transform: rotate(252deg); opacity: 1; }}
                61.75% {{ left: 20%; top: 68%; transform: rotate(216deg); opacity: 1; }}
                66.5% {{ left: 30%; top: 78%; transform: rotate(180deg); opacity: 1; }}
                71.25% {{ left: 40%; top: 88%; transform: rotate(144deg); opacity: 1; }}
                76% {{ left: 50%; top: 98%; transform: rotate(108deg); opacity: 1; }}
                80.75% {{ left: 60%; top: 88%; transform: rotate(72deg); opacity: 1; }}
                85.5% {{ left: 70%; top: 78%; transform: rotate(36deg); opacity: 1; }}
                90.5% {{ left: 80%; top: 68%; transform: rotate(0deg); opacity: 1; }}
                95.25% {{ left: 90%; top: 58%; transform: rotate(-36deg); opacity: 1; }}
                100% {{ left: 100%; top: 48%; transform: rotate(-72deg); opacity: 1; }}
            }}

            /* Responsive Design */
            /* ----------------- */

            /* 1200 Design */
            @media (max-width: 1399px) {{
                .container {{
                    max-width: 1160px;
                }}
            }}

            /* 1024 Design */
            @media (max-width: 1199px) {{
                .container {{
                    max-width: 984px;
                }}

                h1 {{
                    font-size: 2.2em;
                }}
            }}

            /* 768 Design */
            @media (max-width: 1023px) {{
                body {{
                    padding: 15px;
                }}

                .container {{
                    max-width: 738px;
                }}

                .subtitle-1 {{
                    padding: 0 8em 1.5em;
                }}

                .subtitle-2 {{
                    padding: 0 6em;
                }}

                h1 {{
                    font-size: 2em;
                }}

                pre {{
                    padding: 2.6em 0 1.5em;
                }}

                .run-dialog p {{
                    padding: 0 1em 0 0;
                }}
            }}

            /* 640 Design */
            @media (max-width: 767px) {{
                body {{
                    padding: 10px;
                }}

                .container {{
                    max-width: 620px;
                }}

                .subtitle {{
                    font-size: 1em;
                }}

                .subtitle-1 {{
                    padding: 0 5em 1.4em;
                }}

                .subtitle-2 {{
                    padding: 0 4em;
                }}

                h1 {{
                    font-size: 1.8em;
                }}

                h2 {{
                    font-size: 1.4em;
                }}

                pre {{
                    padding: 2.6em 0 2em;
                }}

                .run-dialog p:before {{
                    top: 0;
                    font-size: 0.88em;
                }}
            }}

            /* 480 Design */
            @media (max-width: 639px) {{
                body {{
                    padding: 6px;
                }}

                .container {{
                    max-width: 468px;
                }}

                .subtitle {{
                    font-size: 0.9em;
                }}

                .subtitle-1 {{
                    padding: 0 3em 1.2em;
                }}

                .subtitle-2 {{
                    padding: 0;
                }}

                h1 {{
                    font-size: 1.6em;
                }}

                h2 {{
                    font-size: 1.2em;
                }}

                pre {{
                    padding: 2.6em 0 8.5em;
                }}

                .run-dialog {{
                    padding: 0 1em 1em;
                    display: block;
                    justify-content: unset;
                    align-items: unset;
                }}

                .run-dialog p {{
                    text-align: justify;
                }}

                .run-dialog p:before {{
                    top: 1.75em;
                    font-size: 0.86em;
                }}

                .run-btn {{
                    display: inline-block;
                    float: right;
                }}

                .mobile-br {{
                    display: inline-block;
                }}
            }}

            /* 320 Design */
            @media (max-width: 479px) {{
                body {{
                    padding: 5px;
                }}

                .container {{
                    max-width: 310px;
                }}

                .subtitle-1 {{
                    padding: 0 0 1em;
                }}

                .subtitle-2 {{
                    padding: 0;
                }}

                h1 {{
                    font-size: 1em;
                }}

                h2 {{
                    font-size: 1em;
                }}

                .rocket {{
                    animation: rocketFly 45s infinite linear;
                }}

                pre {{
                    padding: 2.6em 0 13.5em;
                }}
            }}

            /* Below 320 Design */
            @media (max-width: 319px) {{
                body {{
                    padding: 3px;
                }}

                .container {{
                    max-width: 234px;
                }}

                pre {{
                    padding: 2.6em 0 16.5em;
                }}
            }}
        </style>
    </head>

    <body>
        <canvas id="stars-canvas"></canvas>

        <!-- Rocket Ship -->
        <div class="rocket" aria-hidden="true">
            <img src="../Images/Rocket.png" alt="Rocket Ship" class="rocket-ship" />
        </div>

        <div class="container">
            <header>
                <h1>Source Code Snippets of "{filename}"</h1>
                <h2>Mike Dinder</h2>
                <p class="subtitle subtitle-1">The entire contents of the "{filename}" file as code examples with syntax highlighting</p>
                <p class="subtitle subtitle-2">
                    Auto Generated Using <a href="https://python.mikedinder.com/Generated_HTML/Generate_HTML.html" title="Generate HTML Python Script" aria-label="Generate HTML Python Script">Generate_HTML.py</a> script to auto format each of these pages in a standardized template.
                    <br /><br />
                    On smaller viewports/windows, please scroll or use your touch/finger to scroll left to right to view all the code displayed.
                </p>
            </header>

            <main>
                <!-- Python Snippet -->
                <div class="snippet-container">
                    <div class="snippet-header">
                        <span class="snippet-title">{fn_no_ext}</span>
                        <a href="https://python.mikedinder.com" class="language-badge" title="Python Home Page" aria-label="Python Home Page">Python Home</a>
                    </div>

                    <div class="snippet-body">
                        <button class="copy-button" onclick="copyCode(this)">Copy</button>
                        <pre>
                            <code class="language-python">{code_content}</code>

                            <div class="run-dialog">
                                <p>Runs the entire script above. Open your Console Window in Inspect Code to view the output of the script above.<br /><br class="mobile-br" />A prompt popup will ask you for various input() commands.</p>
                                <button class="run-btn" title="Run the Python code shown above" aria-label="Run the Python code shown above" onclick="runMyPythonCode()">Run Python Code</button>
                            </div></pre>
                    </div>
                </div>

                <!-- Execute Python Snippet -->
                <div id="output">
                    <div class="welcome">
                        <div class="hi">Python in Your Browser</div>
                        <p>
                            Client-side execution via Pyodide · No server · Full stdlib · numpy, pandas, matplotlib available via micropip
                            <br /><br />
                        </p>
                        <p>
                            Mobile users will want to use this method. Copy snippets or the entire script from above. You may also copy this script exactly as it is shown and you can run it on your own machine using the Command-Line Interface (CLI).
                            <br /><br />
                        </p>
                    </div>
                </div>
            </main>

            <section>
                <div class="input-header">
                    <div class="logo">py<span>//</span>repl</div>
                    <div class="status">
                        <div class="dot loading" id="status-dot"></div>
                        <span id="status-text">Loading Pyodide...</span>
                    </div>
                </div>

                <div id="input-area">
                    <div class="input-row">
                        <span class="prompt" id="main-prompt">>>></span>
                        <textarea id="code-input" rows="1" placeholder="Type Python Code... Or Copy & Paste Snippets From Above..." disabled spellcheck="false" autocomplete="off"></textarea>
                    </div>

                    <div class="hint">
                        <span><kbd>Enter</kbd> run</span>
                        <span><kbd>Shift+Enter</kbd> new line</span>
                        <span><kbd>↑↓</kbd> history</span>
                    </div>
                </div>
            </section>

            <!-- Footer -->
            <footer id="contact">
                <div class="container">
                    <div class="social-links">
                        <a href="https://www.mikedinder.com" class="social-link" title="Mike Dinder Home Page/Resume" aria-label="Mike Dinder Home Page/Resume"><i class="fa-solid fa-house-chimney-window"></i></a>
                        <a href="https://www.linkedin.com/in/mikedinder/" target="_blank" class="social-link" title="LinkedIn" aria-label="LinkedIn"><i class="fa-brands fa-linkedin"></i></a>
                        <a href="https://github.com/dindermike" target="_blank" class="social-link" title="GitHub" aria-label="GitHub"><i class="fa-brands fa-github"></i></a>
                        <a href="mailto:dindermike@hotmail.com" target="_blank" class="social-link" title="Primary Email" aria-label="Primary Email"><i class="fa-solid fa-envelope"></i></a>
                        <a href="mailto:mike@mikedinder.com" target="_blank" class="social-link" title="Secondary Email" aria-label="Secondary Email"><i class="fa-solid fa-envelope"></i></a>
                    </div>
                    <p>© 2026 MikeDinder.com, All Rights Reserved. Built with AI, Python, HTML, CSS, JavaScript and Some Code Generated Using <a href="https://claude.ai" target="_blank">Claude.AI</a></p>
                </div>
            </footer>
        </div>

        <!-- Initialize Highlight.js -->
        <script type="text/javascript">
            // Initialize syntax highlighting
            hljs.highlightAll();

            // Copy code function
            function copyCode(button) {{
                const codeBlock = button.nextElementSibling.querySelector('code');
                const code = codeBlock.textContent;

                navigator.clipboard.writeText(code).then(() => {{
                    const originalText = button.textContent;
                    button.textContent = 'Copied!';
                    button.style.background = '#10b981';

                    setTimeout(() => {{
                        button.textContent = originalText;
                        button.style.background = '#3b82f6';
                    }}, 2000);
                }}).catch(err => {{
                    console.error('Failed to copy code:', err);
                    button.textContent = 'Error!';
                    button.style.background = '#ef4444';

                    setTimeout(() => {{
                        button.textContent = 'Copy';
                        button.style.background = '#3b82f6';
                    }}, 2000);
                }});
            }}

            async function runMyPythonCode() {{
                let pyodide1 = await loadPyodide();
                // The input() call below will open a browser prompt dialog
                pyodide1.runPython(`
import sys, io
from js import prompt

def input(prompt_text=""):
return prompt(prompt_text)

# Override the built-in input
__builtins__.input = input

{code_content}
                `);
            }}

            const output = document.getElementById('output');
            const input = document.getElementById('code-input');
            const dot = document.getElementById('status-dot');
            const statusText = document.getElementById('status-text');
            const mainPrompt = document.getElementById('main-prompt');

            let pyodide = null;
            let history = [];
            let histIdx = -1;
            let running = false;

            // Auto-resize textarea
            input.addEventListener('input', () => {{
                input.style.height = 'auto';
                input.style.height = Math.min(input.scrollHeight, 200) + 'px';
            }});

            async function initPyodide() {{
                pyodide = await loadPyodide();

                // Redirect stdout/stderr
                pyodide.runPython(`
                    import sys, io
                    from js import prompt

                    def input(prompt_text=""):
                        return prompt(prompt_text)

                    # Override the built-in input
                    __builtins__.input = input

                    class _Capture(io.StringIO):
                        pass

                    sys.stdout = _Capture()
                    sys.stderr = _Capture()
                `);

                dot.className = 'dot ready';
                statusText.textContent = 'Python ' + pyodide.runPython('import sys; sys.version.split()[0]');
                input.disabled = false;
            }}

            function addEntry(code, stdout, value, error) {{
                const entry = document.createElement('div');
                entry.className = 'entry';

                const lines = code.split('\\n');
                lines.forEach((line, i) => {{
                    const row = document.createElement('div');
                    row.className = 'input-line';
                    const p = document.createElement('span');
                    p.className = 'prompt' + (i > 0 ? ' cont' : '');
                    p.textContent = i === 0 ? '>>>' : '...';
                    const c = document.createElement('span');
                    c.className = 'code-display';
                    c.textContent = line;
                    row.appendChild(p);
                    row.appendChild(c);
                    entry.appendChild(row);
                }});

                if (stdout) {{
                    const r = document.createElement('div');
                    r.className = 'result stdout';
                    r.textContent = stdout;
                    entry.appendChild(r);
                }}

                if (value !== undefined && value !== null && String(value) !== 'None' && value !== '') {{
                    const r = document.createElement('div');
                    r.className = 'result value';
                    r.textContent = String(value);
                    entry.appendChild(r);
                }}

                if (error) {{
                    const r = document.createElement('div');
                    r.className = 'result error';
                    r.textContent = error;
                    entry.appendChild(r);
                }}

                output.appendChild(entry);
                output.scrollTop = output.scrollHeight;
            }}

            async function runCode(code) {{
                if (!pyodide || running || !code.trim()) return;
                running = true;
                input.disabled = true;
                mainPrompt.style.color = 'var(--muted)';

                // Clear captured output
                pyodide.runPython(`sys.stdout.truncate(0); sys.stdout.seek(0); sys.stderr.truncate(0); sys.stderr.seek(0)`);

                let resultVal = undefined;
                let errorMsg = null;

                try {{
                    const result = await pyodide.runPythonAsync(code);
                    resultVal = result;
                }} catch (err) {{
                    // Clean up traceback
                    errorMsg = err.message.split('\\n').slice(-3).join('\\n').trim();
                }}

                const stdout = pyodide.runPython(`sys.stdout.getvalue()`).trimEnd();
                const stderr = pyodide.runPython(`sys.stderr.getvalue()`).trimEnd();

                addEntry(code, stdout || (stderr && !errorMsg ? stderr : ''), resultVal, errorMsg || (stderr && errorMsg ? stderr : null));

                running = false;
                input.disabled = false;
                input.style.height = 'auto';
                mainPrompt.style.color = 'var(--accent)';
                input.focus();
            }}

            input.addEventListener('keydown', async (e) => {{
                if (e.key === 'Enter' && !e.shiftKey) {{
                    e.preventDefault();
                    const code = input.value;
                    if (!code.trim()) return;
                    history.unshift(code);
                    histIdx = -1;
                    input.value = '';
                    await runCode(code);
                }} else if (e.key === 'ArrowUp' && !e.shiftKey) {{
                    if (histIdx < history.length - 1) {{
                    histIdx++;
                    input.value = history[histIdx];
                    input.dispatchEvent(new Event('input'));
                    setTimeout(() => input.setSelectionRange(input.value.length, input.value.length), 0);
                    }}
                    e.preventDefault();
                }} else if (e.key === 'ArrowDown' && !e.shiftKey) {{
                    if (histIdx > 0) {{
                    histIdx--;
                    input.value = history[histIdx];
                    }} else {{
                    histIdx = -1;
                    input.value = '';
                    }}
                    input.dispatchEvent(new Event('input'));
                    e.preventDefault();
                }}
            }});

            initPyodide().catch(err => {{
                statusText.textContent = 'Failed to load';
                dot.style.background = 'var(--error)';
            }});

            // --- Stars canvas ---
            const canvas = document.getElementById('stars-canvas');
            const ctx = canvas.getContext('2d');
            let stars = [];

            function resize() {{
                canvas.width = window.innerWidth;
                canvas.height = window.innerHeight;
            }}
            resize();
            window.addEventListener('resize', () => {{ resize(); initStars(); }});

            function initStars() {{
                stars = [];
                const count = Math.floor((canvas.width * canvas.height) / 3500);
                for (let i = 0; i < count; i++) {{
                    stars.push({{
                        x: Math.random() * canvas.width,
                        y: Math.random() * canvas.height,
                        r: Math.random() * 1.4 + 0.2,
                        alpha: Math.random(),
                        speed: Math.random() * 0.003 + 0.001,
                        phase: Math.random() * Math.PI * 2,
                        color: Math.random() > 0.92 ? '#00d4ff' : Math.random() > 0.85 ? '#ffd166' : '#e8f4ff'
                    }});
                }}
            }}
            initStars();

            function drawStars(t) {{
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                stars.forEach(s => {{
                    const a = 0.3 + 0.6 * (0.5 + 0.5 * Math.sin(t * s.speed + s.phase));
                    ctx.beginPath();
                    ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2);
                    ctx.fillStyle = s.color;
                    ctx.globalAlpha = a;
                    ctx.fill();
                }});
                ctx.globalAlpha = 1;
            }}

            let t = 0;
            function starLoop() {{
                t += 1;
                drawStars(t);
                requestAnimationFrame(starLoop);
            }}
            starLoop();
        </script>
    </body>
</html>
"""  # noqa: E501

try:
with open(output_html_path, 'w', encoding='utf-8') as f_html:
    f_html.write(html_content)
except FileNotFoundError:
print(f'Error: The WRITE File "{filename}" Was Not Found.')
except Exception as e:
print(f'An Error Occurred: {e}')
else:
print(f'Successfully Generated HTML File: {filename}')


if __name__ == '__main__':
directory1 = '/home/mike/Python/'
directory2 = '/home/mike/Python/Requests/'
directory3 = '/home/mike/Python/SQL_Practice/'

directories = [directory1, directory2, directory3]

files_list1 = [f for f in listdir(directory1) if isfile(join(directory1, f))]
files_list2 = [f for f in listdir(directory2) if isfile(join(directory2, f))]
files_list3 = [f for f in listdir(directory3) if isfile(join(directory3, f))]

files_list = [files_list1,  files_list2,  files_list3]

for di, directory in enumerate(directories):
for fi, file in enumerate(files_list[di]):
if file.startswith('.'):
    file = file[1:]

filename_list = file.split('.')

if filename_list[-1] == 'py':
    generate_html_with_code(
        file,
        filename_list[0],
        'Generated_HTML/' + filename_list[0] + '.html',
        directory
    )
Python in Your Browser

Client-side execution via Pyodide · No server · Full stdlib · numpy, pandas, matplotlib available via micropip

Mobile users will want to use this method. Copy snippets or the entire script from above. You may also copy this script exactly as it is shown and you can run it on your own machine using the Command-Line Interface (CLI).

Loading Pyodide...
>>>
Enter run Shift+Enter new line ↑↓ history