<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ David Clinton - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ David Clinton - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 16:29:50 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/dbclinton/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Use Keycloak for Identity and Access Management ]]>
                </title>
                <description>
                    <![CDATA[ Whether your deployment requires logins from hundreds of thousands of end users or just a few remote admins, there's no escaping the need to properly control access to your infrastructure. And integrating those logins with industry-standard tools lik... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/keycloak-identity-and-access-management/</link>
                <guid isPermaLink="false">67924b2d0a4e059db2a7577f</guid>
                
                    <category>
                        <![CDATA[ authentication ]]>
                    </category>
                
                    <category>
                        <![CDATA[ IAM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ keycloak ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SSO ]]>
                    </category>
                
                    <category>
                        <![CDATA[ single sign on ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Thu, 23 Jan 2025 13:59:09 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1737640179567/36b76fb3-3e9f-4124-a4d5-bb7d11428a6c.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Whether your deployment requires logins from hundreds of thousands of end users or just a few remote admins, there's no escaping the need to properly control access to your infrastructure. And integrating those logins with industry-standard tools like LDAP and Active Directory can cut down the amount of work it'll take to get yourself up and running.</p>
<p>Keycloak is an enterprise-ready, open source identity access management (IAM) solution that's scalable, extensible, and robust. And it really doesn't need all that much care and feeding to launch a simple implementation.</p>
<p>This article will introduce you to the technology and the ways it can integrate best-practice authentication into your infrastructure.</p>
<p><em>Note on Hitachi Contributions to Keycloak:</em></p>
<p>Takashi Norimatsu works for Hitachi and has been the official maintainer of Keycloak since late 2021. Hitachi has been actively contributing to Keycloak since at least 2018.</p>
<p><a target="_blank" href="https://www.hitachi.com/New/cnews/month/2024/11/241108.html">Hitachi appears to be doing more strategically with open source in general</a> and Keycloak in particular. I believe strong, continued corporate support as part of an open source project is a positive sign, but at the very least, you should be aware of the corporate support for Keycloak during your assessment.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737406737359/1fc95289-7777-4c9f-a651-00bd8a44b517.png" alt="1fc95289-7777-4c9f-a651-00bd8a44b517" class="image--center mx-auto" width="751" height="589" loading="lazy"></p>
<h2 id="heading-getting-started-with-keycloak">Getting Started with Keycloak</h2>
<p>I'll begin with a brief "quick start". As you can see from this screenshot, Keycloak will run happily on multiple platforms. And their <a target="_blank" href="https://www.keycloak.org/guides">product documentation is excellent</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737406768154/a84122e2-1e72-43a8-86f2-aeaddd0c3a3b.png" alt="a84122e2-1e72-43a8-86f2-aeaddd0c3a3b" class="image--center mx-auto" width="1280" height="720" loading="lazy"></p>
<p>But here's some very simple one-command Docker syntax that will create a fully-functioning live Keycloak instance on your local machine:</p>
<pre><code class="lang-bash">docker run -p 8080:8080 \
     -e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
     -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:26.0.7 start-dev
</code></pre>
<p>That's it. After a minute or two, you can open the administration interface on your browser using the appropriate variation of:</p>
<p><a target="_blank" href="http://localhost:8080">localhost:8080</a></p>
<p>Based on the Docker command defaults, you'll log in using admin and admin. Spend a few minutes digging into the environment to get a feel for the tools that are available.</p>
<h2 id="heading-what-keycloak-offers">What Keycloak Offers</h2>
<p>Ok. So why do you need Keycloak? Because it supports all the functionality demanded by modern deployments. That'll include Single Sign-On (SSO) to allow seamless authentication across multiple applications and services, OAuth2, OpenID Connect, SAML protocol compliance, and federated identities using existing LDAP or Active Directory setups or through social media logins like Google.</p>
<p>Keycloak incorporates the use of Multi-factor Authentication (MFA), built-in token revocation and expiration mechanisms, fine-grained permission management through Role-based Access Control (RBAC), and end-to-end encryption for sensitive communications. GDPR, HIPAA, and PCI DSS compliance are all possible.</p>
<p>Keycloak comes with a RESTful API for scripted and programmatic interactions. That will encourage task automation to further optimize your authentication processes. And your developers can build their own custom plugins to fill any usability gaps you encounter.</p>
<h2 id="heading-the-business-case-for-keycloak">The Business Case for Keycloak</h2>
<p>Because Keycloak is open source, there'll be no license fees to worry about. But open source gives you a lot more than just "cheap".</p>
<p>Keycloak cuts out vendor lock-in, allowing you to work with any platform or cloud provider – or move between them whenever necessary. It can also reduce overall operational costs through its simplified deployments (how much time did it take you to get that Docker image up and running?), automated updates, and no limits or cost penalties for even millions of monthly API calls or active users.</p>
<p>Having out-of-the-box (and free) access to the full feature set (including RBAC and MFA) also simplifies planning and execution. There's nothing "more" efficient than having to wait a week to access paywalled functionality until you get a response to your request for more project funding. All Keycloak features are just a click away.</p>
<p>This radar chart illustrates the feature and functionality differences between Keycloak and its major commercial peers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737407002045/d9a45f49-afbb-4709-a9da-016782d7c6ae.png" alt="Differences between Keycloak, Okta, Auth0, and Azure AD" class="image--center mx-auto" width="1750" height="1424" loading="lazy"></p>
<h3 id="heading-what-to-consider">What to Consider</h3>
<p>As much as Keycloak has to offer, it won't be the ideal choice for every use-case. And there are issues about which you should be aware up front.</p>
<p>For instance, while getting started may be easy, fully configuring, say, clustering and high availability for Keycloak can be complex for teams without experience in identity management. Managing latency issues for very large deployments can be challenging.</p>
<p>And while the documentation is generally excellent, it may not fully address specific complexities or edge-case scenarios. Similarly, there's no resource within the Keycloak community that offers guaranteed support. Although there are excellent third-party providers out there.</p>
<p>It's possible that, because you're not working with a commercial product, demonstrating regulatory compliance could be a bit more involved. You may also need to adapt your logging functionality to comply with various audit trail requirements.</p>
<p>Finally, customizable environments risk introducing destabilizing complexity. The further off the beaten trail your plugins and API implementations wander, the greater the odds that something will eventually break – especially around version upgrades.</p>
<h2 id="heading-your-next-steps">Your Next Steps</h2>
<p>It's always helpful to explore the journeys other people took with a new technology.</p>
<p>So <a target="_blank" href="https://www.redhat.com/en/blog/keycloak-success-stories-from-the-openshift-commons-gathering-amsterdam-2023">this page</a> includes information on a fascinating case study involving a Japanese bank that was looking for an API solution and decided on Keycloak because of its high level API security features. Yuichi Nakamura’s presentation <a target="_blank" href="https://youtu.be/jH7-tyrUP9E?si=6gKMdYH-o0LMiYFZ&amp;t=490">at the OpenShift Commons event in 2023</a> gives details how the bank successfully used Keycloak to secure their APIs. Nakamura, Hitachi Chief OSS Strategist, has recently been appointed as Head of Hitachi Open Source Program Office (OSPO).</p>
<p>And <a target="_blank" href="https://hossted.com/knowledge-base/case-studies/infrastructure-and-network/security/enhancing-authentication-services-with-freeipa-and-keycloak/">this is an account</a> of a university that implemented Kerberos Single Sign-On (SSO) for FreeIPA and configured Keycloak to connect with FreeIPA. The university successfully achieved user authentication from Keycloak by leveraging the SSSD option under “user federation” instead of relying on Kerberos or LDAP.</p>
<p>I’m no stranger to Keycloak myself, having taught a <a target="_blank" href="https://www.pluralsight.com/courses/keycloak-getting-started">Getting Started with Keycloak course on Pluralsight</a>. For beginners, this may be a good place to start. A 10 day free trial is available.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use LangChain and GPT to Analyze Multiple Documents ]]>
                </title>
                <description>
                    <![CDATA[ Over the past year or so, the developer universe has exploded with ingenious new tools, applications, and processes for working with large language models and generative AI. One particularly versatile example is the LangChain project. The overall goa... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-langchain-and-gpt-to-analyze-multiple-documents/</link>
                <guid isPermaLink="false">672b941f0c32c8c8cd6159a9</guid>
                
                    <category>
                        <![CDATA[ generative ai ]]>
                    </category>
                
                    <category>
                        <![CDATA[ langchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Wed, 06 Nov 2024 16:06:55 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1730909200914/e75f3725-7453-49c0-b4e9-8b14fbc3b783.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Over the past year or so, the developer universe has exploded with ingenious new tools, applications, and processes for working with large language models and generative AI.</p>
<p>One particularly versatile example is <a target="_blank" href="https://www.langchain.com/">the LangChain project</a>. The overall goal involves providing easy integrations with various LLM models. But the LangChain ecosystem is also host to a growing number of (sometimes experimental) projects pushing the limits of the humble LLM.</p>
<p>Spend some time browsing <a target="_blank" href="https://www.langchain.com/">LangChain’s website</a> to get a sense of what's possible. You'll see how many tools are designed to help you build more powerful applications.</p>
<p>But you can also use it as an alternative for connecting your favorite AI with the live internet. Specifically, this demo will show you how to use it to programmatically access, summarize, and analyze long and complex online documents.</p>
<p>To make it all happen, you’ll need a Python runtime environment (like Jupyter Lab) and a valid OpenAI API key.</p>
<h3 id="heading-prepare-your-environment">Prepare Your Environment</h3>
<p>One popular use for LangChain involves loading multiple PDF files in parallel and asking GPT to analyze and compare their contents.</p>
<p>As you can see for yourself in <a target="_blank" href="https://python.langchain.com/docs/integrations/toolkits/document_comparison_toolkit">the LangChain documentation,</a> existing modules can be loaded to permit PDF consumption and natural language parsing. I'm going to walk you through a use-case sample that's loosely based on the example in that documentation. Here's how that begins:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> os
os.environ[<span class="hljs-string">'OPENAI_API_KEY'</span>] = <span class="hljs-string">"sk-xxx"</span>
<span class="hljs-keyword">from</span> pydantic <span class="hljs-keyword">import</span> BaseModel, Field
<span class="hljs-keyword">from</span> langchain.chat_models <span class="hljs-keyword">import</span> ChatOpenAI
<span class="hljs-keyword">from</span> langchain.agents <span class="hljs-keyword">import</span> Tool
<span class="hljs-keyword">from</span> langchain.embeddings.openai <span class="hljs-keyword">import</span> OpenAIEmbeddings
<span class="hljs-keyword">from</span> langchain.text_splitter <span class="hljs-keyword">import</span> CharacterTextSplitter
<span class="hljs-keyword">from</span> langchain.vectorstores <span class="hljs-keyword">import</span> FAISS
<span class="hljs-keyword">from</span> langchain.document_loaders <span class="hljs-keyword">import</span> PyPDFLoader
<span class="hljs-keyword">from</span> langchain.chains <span class="hljs-keyword">import</span> RetrievalQA
</code></pre>
<p>That code will build your environment and set up the tools necessary for:</p>
<ul>
<li><p>Enabling OpenAI Chat (ChatOpenAI)</p>
</li>
<li><p>Understanding and processing text (OpenAIEmbeddings, CharacterTextSplitter, FAISS, RetrievalQA)</p>
</li>
<li><p>Managing an AI agent (Tool)</p>
</li>
</ul>
<p>Next, you'll create and define a <code>DocumentInput</code> class and a value called <code>llm</code> which sets some familiar GPT parameters that'll both be called later:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DocumentInput</span>(<span class="hljs-params">BaseModel</span>):</span>
    question: str = Field()
llm = ChatOpenAI(temperature=<span class="hljs-number">0</span>, model=<span class="hljs-string">"gpt-3.5-turbo-0613"</span>)
</code></pre>
<h3 id="heading-load-your-documents">Load Your Documents</h3>
<p>Next, you'll create a couple of arrays. The three <code>path</code> variables in the <code>files</code> array contain the URLs for recent financial reports issued by three software/IT services companies: Alphabet (Google), Cisco, and IBM.</p>
<p>We're going to have GPT dig into three companies’ data simultaneously, have the AI compare the results, and do it all without having to go to the trouble of downloading PDFs to a local environment.</p>
<p>You can usually find such legal filings in the Investor Relations section of a company's website.</p>
<pre><code class="lang-python">tools = []
files = [
    {
        <span class="hljs-string">"name"</span>: <span class="hljs-string">"alphabet-earnings"</span>,
        <span class="hljs-string">"path"</span>: <span class="hljs-string">"https://abc.xyz/investor/static/pdf/2023Q1\
        _alphabet_earnings_release.pdf"</span>,
    },
    {
        <span class="hljs-string">"name"</span>: <span class="hljs-string">"Cisco-earnings"</span>,
        <span class="hljs-string">"path"</span>: <span class="hljs-string">"https://d18rn0p25nwr6d.cloudfront.net/CIK-00\
            00858877/5b3c172d-f7a3-4ecb-b141-03ff7af7e068.pdf"</span>,
    },
    {
        <span class="hljs-string">"name"</span>: <span class="hljs-string">"IBM-earnings"</span>,
        <span class="hljs-string">"path"</span>: <span class="hljs-string">"https://www.ibm.com/investor/att/pdf/IBM_\
            Annual_Report_2022.pdf"</span>,
    },
    ]
</code></pre>
<p>This <code>for</code> loop will iterate through each value of the <code>files</code> array I just showed you. For each iteration, it'll use <code>PyPDFLoader</code> to load the specified PDF file, <code>loader</code> and <code>CharacterTextSplitter</code> to parse the text, and the remaining tools to organize the data and apply the embeddings. It'll then invoke the <code>DocumentInput</code> class we created earlier:</p>
<pre><code class="lang-python"><span class="hljs-keyword">for</span> file <span class="hljs-keyword">in</span> files:
    loader = PyPDFLoader(file[<span class="hljs-string">"path"</span>])
    pages = loader.load_and_split()
    text_splitter = CharacterTextSplitter(chunk_size=<span class="hljs-number">1000</span>, \
        chunk_overlap=<span class="hljs-number">0</span>)
    docs = text_splitter.split_documents(pages)
    embeddings = OpenAIEmbeddings()
    retriever = FAISS.from_documents(docs, embeddings).as_retriever()
<span class="hljs-comment"># Wrap retrievers in a Tool</span>
tools.append(
    Tool(
        args_schema=DocumentInput,
        name=file[<span class="hljs-string">"name"</span>],
        func=RetrievalQA.from_chain_type(llm=llm, \
            retriever=retriever),
    )
)
</code></pre>
<h3 id="heading-prompt-your-model">Prompt Your Model</h3>
<p>At this point, we're finally ready to create an agent and feed it our prompt as <code>input</code>.</p>
<pre><code class="lang-python">llm = ChatOpenAI(
    temperature=<span class="hljs-number">0</span>,
    model=<span class="hljs-string">"gpt-3.5-turbo-0613"</span>,
)
agent = initialize_agent(
    agent=AgentType.OPENAI_FUNCTIONS,
    tools=tools,
    llm=llm,
    verbose=<span class="hljs-literal">True</span>,
)
    agent({<span class="hljs-string">"input"</span>: <span class="hljs-string">"Based on these SEC filing documents, identify \
        which of these three companies - Alphabet, IBM, and Cisco \
        has the greatest short-term debt levels and which has the \
        highest research and development costs."</span>})
</code></pre>
<p>The output that I got was short and to the point:</p>
<blockquote>
<p>‘output’: ‘Based on the SEC filing documents:\n\n- The company with the greatest short-term debt levels is IBM, with a short-term debt level of $4,760 million.\n- The company with the highest research and development costs is Alphabet, with research and development costs of $11,468 million.’</p>
</blockquote>
<h3 id="heading-wrapping-up">Wrapping Up</h3>
<p>As you’ve seen, LangChain lets you integrate multiple tools into generative AI operations, enabling multi-layered programmatic access to the live internet and more sophisticated LLM prompts.</p>
<p>With these tools, you’ll be able to automate applying the power of AI engines to real-world data assets in real time. Try it out for yourself.</p>
<p><em>This article is excerpted from</em> <a target="_blank" href="https://www.amazon.com/dp/1633436985"><em>my Manning book, The Complete Obsolete Guide to Generative AI</em></a><em>.  But you can find plenty more technology goodness at</em> <a target="_blank" href="https://bootstrap-it.com/"><em>my website</em></a><em>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use GPT to Analyze Large Datasets ]]>
                </title>
                <description>
                    <![CDATA[ Absorbing and then summarizing very large quantities of content in just a few seconds truly is a big deal. As an example, a while back I received a link to the recording of an important 90 minute business video conference that I'd missed a few hours ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-gpt-to-analyze-large-datasets/</link>
                <guid isPermaLink="false">66cf65275dfeea789e899e2b</guid>
                
                    <category>
                        <![CDATA[ #ai-tools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ generative ai ]]>
                    </category>
                
                    <category>
                        <![CDATA[ analytics ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Wed, 28 Aug 2024 17:57:59 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724798393633/8ad22b7c-646c-4c02-894d-6a6b08447049.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Absorbing and then summarizing very large quantities of content in just a few seconds truly is a big deal. As an example, a while back I received a link to the recording of an important 90 minute business video conference that I'd missed a few hours before.</p>
<p>The reason I'd missed the live version was because I had no time (I was, if you must know, rushing to finish my <a target="_blank" href="https://amzn.to/3yLFT3b">Manning book, The Complete Obsolete Guide to Generative AI</a> – from which this article is excerpted).</p>
<p>Well, a half a dozen hours later I still had no time for the video. And, inexplicably, the book was still not finished.</p>
<p>So here's how I resolved the conflict the GPT way:</p>
<ul>
<li><p>I used OpenAI Whisper to generate a transcript based on the audio from the recording</p>
</li>
<li><p>I exported the transcript to a PDF file</p>
</li>
<li><p>I uploaded the PDF to ChatPDF</p>
</li>
<li><p>I prompted ChatPDF for summaries connected to the specific topics that interested me</p>
</li>
</ul>
<p>Total time to "download" the key moments from the 90 minute call: 10 minutes. That's 10 minutes to convert a dataset made up of around 15,000 spoken words to a machine-readable format, and to then digest, analyze, and summarize it.</p>
<h3 id="heading-how-to-use-gpt-for-business-analytics">How to Use GPT for Business Analytics</h3>
<p>But all that's old news by now. The <em>next-level</em> level will solve the problem of business analytics.</p>
<p>Ok. So what <em>is</em> the "problem with business analytics"? It's the hard work of building sophisticated code that parses large datasets to make them consistently machine readable (also known as "data wrangling"). It then applies complex algorithms to tease out useful insights. The figure below broadly outlines the process.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/gai-8-1.png" alt="A diagram illustrating the data wrangling process" width="600" height="400" loading="lazy"></p>
<p>A lot of the code that fits that description is incredibly complicated, not to mention clever. Inspiring clever data engineers to write that clever code can, of course, cost organizations many, many fortunes. The "problem" then, is the cost.</p>
<p>So solving that problem could involve leveraging a few hundred dollars worth of large language model (LLM) API charges. Here's how I plan to illustrate that.</p>
<p>I'll need a busy spreadsheet to work with, right? The best place I know for good data is the <a target="_blank" href="https://www.kaggle.com/">Kaggle website</a>.</p>
<p>Kaggle is an online platform for hosting datasets (and data science competitions). It's become in important resource for data scientists, machine learning practitioners, and researchers, allowing them to showcase their skills, learn from <a target="_blank" href="https://www.kaggle.com/">others,</a> and collaborate on projects. The platform offers a wide range of public and private datasets, as well as tools and features to support data exploration and modeling.</p>
<h3 id="heading-how-to-prepare-a-dataset">How to Prepare a Dataset</h3>
<p><a target="_blank" href="https://www.kaggle.com/datasets/snassimr/data-for-investing-type-prediction">The "Investing Program Type Prediction"</a> dataset associated with this code should work perfectly. From what I can tell, this was data aggregated by a bank somewhere in the world that represents its customers' behavior.</p>
<p>Everything has been anonymized, of course, so there's no way for us to know which bank we're talking about, who the customers were, or even where in the world all this was happening. In fact, I'm not even 100% sure what each column of data represents.</p>
<p>What <em>is</em> clear is that each customer's age and neighborhood are there. Although the locations have been anonymized as <code>C1</code>, <code>C2</code>, <code>C3</code> and so on, some of the remaining columns clearly contain financial information.</p>
<p>Based on those assumptions, my ultimate goal is to search for statistically valid relationships between columns. For instance, are there specific demographic features (income, neighborhood, age) that predict a greater likelihood of a customer purchasing additional banking products? For this specific example I'll see if I can identify the geographic regions within the data whose average household wealth is the highest.</p>
<p>For normal uses, such vaguely described data would be worthless. But since we're just looking to demonstrate the process it'll do just fine. I'll <em>make up</em> column headers that more or less fit the shape of their data. Here's how I named them:</p>
<ul>
<li><p>Customer ID</p>
</li>
<li><p>Customer age</p>
</li>
<li><p>Geographic location</p>
</li>
<li><p>Branch visits per year</p>
</li>
<li><p>Total household assets</p>
</li>
<li><p>Total household debt</p>
</li>
<li><p>Total investments with bank</p>
</li>
</ul>
<p>The column names need to be very descriptive because those will be the only clues I'll give GPT to help it understand the data. I did have to add my own customer IDs to that first column (they didn't originally exist).</p>
<p>The fastest way I could think of to do that was to insert the <code>=(RAND())</code> formula into the top data cell in that column (with the file loaded into spreadsheet software like Excel, Google Sheets, or LibreOffice Calc) and then apply the formula to the rest of the rows of data. When that's done, all the 1,000 data rows will have unique IDs, albeit IDs between 0 and 1 with many decimal places.</p>
<h3 id="heading-how-to-apply-llamaindex-to-the-problem">How to Apply LlamaIndex to the Problem</h3>
<p>With my data prepared, I'll use <a target="_blank" href="https://www.llamaindex.ai/">LlamaIndex</a> to get to work analyzing the numbers. As before, the code I'm going to execute will:</p>
<ul>
<li><p>Import the necessary functionality</p>
</li>
<li><p>Add my OpenAI API k<a target="_blank" href="https://www.llamaindex.ai/">ey</a></p>
</li>
<li><p>Read the data file that's in the directory called <code>data</code></p>
</li>
<li><p>Build the nodes from which we'll populate our index</p>
</li>
</ul>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> os
<span class="hljs-keyword">import</span> openai
<span class="hljs-keyword">from</span> llama_index <span class="hljs-keyword">import</span> SimpleDirectoryReader
<span class="hljs-keyword">from</span> llama_index.node_parser <span class="hljs-keyword">import</span> SimpleNodeParser
<span class="hljs-keyword">from</span> llama_index <span class="hljs-keyword">import</span> GPTVectorStoreIndex

os.environ[<span class="hljs-string">'OPENAI_API_KEY'</span>] = <span class="hljs-string">"sk-XXXX"</span>

documents = SimpleDirectoryReader(<span class="hljs-string">'data'</span>).load_data()
parser = SimpleNodeParser()
nodes = parser.get_nodes_from_documents(documents)
index = GPTVectorStoreIndex.from_documents(documents)
</code></pre>
<p>Finally, I'll send my prompt:</p>
<pre><code class="lang-python">response = index.query(
    <span class="hljs-string">"Based on the data, which 5 geographic regions had the highest average household net wealth? Show me nothing more than the region codes"</span>
)
print(response)
</code></pre>
<p>Here it is again in a format that's easier on the eyes:</p>
<blockquote>
<p><em>Based on the data, which 5 geographic regions had the highest household net wealth?</em></p>
</blockquote>
<p>I asked this question primarily to confirm that GPT understood the data. It's always good to test your model just to see if the responses you're getting seem to reasonably reflect what you already know about the data.</p>
<p>To answer properly, GPT would need to figure out what each of the column headers means and the relationships <em>between</em> columns. In other words, it would need to know how to calculate net worth for each row (account ID) from the values in the <code>Total household assets</code>, <code>Total household debt</code>, and  <code>Total investments with bank</code> columns. It would then need to aggregate all the net worth numbers that it generated by <code>Geographic location</code>, calculate averages for each location and, finally, compare all the averages and rank them.</p>
<p>The result? I <em>think</em> GPT nailed it. After a minute or two of deep and profound thought (and around $0.25 in API charges), I was shown five location codes (G0, G90, G96, G97, G84, in case you're curious). This tells me that GPT understands the location column the same way I did and is at least attempting to infer relationships between location and demographic features.</p>
<p>What did I mean "I think"? Well I never actually checked to confirm that the numbers made sense. For one thing, this isn't real data anyway and, for all I know, I guessed the contents of each column incorrectly.</p>
<p>But also because <em>every</em> data analysis needs checking against the real world so, in that sense, GPT-generated analysis is no different. In other words, whenever you're working with data that's supposed to represent the real world, you should always find a way to calibrate your data using known values to confirm that the whole thing isn't a happy fantasy.</p>
<p>I then asked a second question that reflects a real-world query that would interest any bank:</p>
<blockquote>
<p><em>Based on their age, geographic location, number of annual visits to bank branch, and total current investments, who are the ten customers most likely to invest in a new product offering? Show me only the value of the</em> <code>customer ID</code> columns for those ten customers.</p>
</blockquote>
<p>Once again GPT spat back a response that at least <em>seemed</em> to make sense. This question was also designed to test GPT on its ability to correlate multiple metrics and submit them to a complex assessment ("...most likely to invest in a new product offering").</p>
<p>I'll rate that as another successful experiment.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>GPT – and other LLMs – are capable of independently parsing, analyzing, and deriving insights from large data sets.</p>
<p>There will be limits to the magic, of course. GPT and its cousins can still hallucinate – especially when your prompts give it too much room to be "creative" or, sometimes, when you've been gone too deep into a single prompt thread. And there are also some hard limits to how much data OpenAI will allow you to upload.</p>
<p>But, overall, you can accomplish more and faster than you can probably imagine right now.</p>
<p>While all that greatly simplifies the data analytics process, success still depends on understanding the real-world context of your data and coming up with specific and clever prompts. That'll be your job.</p>
<p><em>This article is excerpted from</em> <a target="_blank" href="https://amzn.to/3yLFT3b"><em>my Manning book, The Complete Obsolete Guide to Generative AI.</em></a> <em>There's plenty more technology goodness available through</em> <a target="_blank" href="https://bootstrap-it.com"><em>my website</em></a><em>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Secure Your Container Deployments with Chainguard ]]>
                </title>
                <description>
                    <![CDATA[ You don't need to convince me that containers are absolutely the best thing to come out of the virtualization revolution. I use containers of one flavor or another just about every day.  But the beauty of template-it-once-and-deploy-it-everywhere com... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/secure-container-deployment-with-chainguard/</link>
                <guid isPermaLink="false">66b9962da3099de4654e61b2</guid>
                
                    <category>
                        <![CDATA[ containers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ virtualization ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Fri, 05 Apr 2024 01:46:19 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/frank-mckenna-tjX_sniNzgQ-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>You don't need to convince me that containers are absolutely the best thing to come out of the virtualization revolution. I use containers of one flavor or another just about every day. </p>
<p>But the beauty of template-it-once-and-deploy-it-everywhere comes with a cost: what if a single layer within that template contains a security vulnerability? And if there was a vulnerability tucked away down there, how would you even know? </p>
<p>In this article, I'll to show you how to use Chainguard (and Docker Scout) to manage security for all your images.</p>
<p>You can watch the video version of this article here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/ao1Upn3Yooo" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>When you build your software infrastructure on a physical server the traditional way, you'll manually acquire and install each element of the stack one piece at a time. The odds are that you'll be pulling the latest version of everything straight from the official source. And you'll at the very least be thinking about each layer. </p>
<p>But most modern containers are built from complicated templates. It's easy to just copy and paste the code and fire it up. It's very possible that you might not even be <em>aware</em> of all the software that's powering your application. And even if you are, it would easily take you hours of research into each and every element to figure out where you stand.</p>
<p>That's the problem that <a target="_blank" href="https://www.chainguard.dev/">Chainguard</a> exists to solve. Chainguard provides <a target="_blank" href="https://images.chainguard.dev/?category=featured">hundreds of well-maintained custom versions of many of the most popular container images out there</a>. </p>
<p>Of course, you're free to pull, say, the official MariaDB image into your Dockerfile, but going with the Chainguard version instead will be a far safer choice. That's because Chainguard is constantly analyzing their image layers for vulnerabilities and building images that are as up-to-date and secure as possible.</p>
<p>Let's find out how all of this actually works in the real world. Before we get started with building new images, I should tell you how we're going to visualize each image's vulnerabilities so we can quantify the Chainguard advantage. </p>
<p>First though, I should explain that infrastructure vulnerabilities are generally defined using the <a target="_blank" href="https://www.cve.org/">Common Vulnerabilities and Exposures – or CVE – system</a> based on the National Vulnerability Database maintained by the US government's NIST. There are hundreds of thousands of CVE definitions that have been identified and categorized by the CVE system, with each one rated by severity. The existence of this database – along with a number of important related tools – allows us to automate our security assessments. </p>
<p>Docker Scout is one of those tools. <a target="_blank" href="https://docs.docker.com/scout/install/">This page</a> gives you installation instructions for using Scout on Docker Engine, but it should run out of the box if you're using Docker Desktop. The <code>curl</code> command will simply download the <code>install-scout</code> Bash script that'll make everything happen.</p>
<pre><code class="lang-bash">curl -fsSL https://raw.githubusercontent.com/docker/scout-cli/main install.sh -o install-scout.sh
</code></pre>
<h2 id="heading-how-to-choose-the-right-image">How to Choose the Right Image</h2>
<p>I created a Dockerfile that'll pull the official MariaDB image from Docker Hub:</p>
<pre><code>FROM mariadb:latest

ENV MYSQL_ROOT_PASSWORD=my_root_password
ENV MYSQL_DATABASE=my_database

ENV MYSQL_USER=my_user
ENV MYSQL_PASSWORD=my_user_password
</code></pre><p>We'll pretend that the image will be used for a multi-tiered deployment, so we'll create a root database and password, and a new user account with it's own password. There might be an application tier instance that'll use those credentials to access the database at some point. </p>
<p>Either way, I'll build the image the usual way, giving it the name <code>mariadb_standard</code>. </p>
<pre><code>docker build -t mariadb_standard .
</code></pre><p>There's another Dockerfile that's exactly the same as the first one, except that we're pulling the special Chainguard image of MariaDB. </p>
<pre><code>
FROM chainguard/mariadb

ENV MYSQL_ROOT_PASSWORD=my_root_password
ENV MYSQL_DATABASE=my_database

ENV MYSQL_USER=my_user
ENV MYSQL_PASSWORD=my_user_password
</code></pre><p>That image came from Docker Hub, but we could have just as easily pulled it from Chainguard's own repo:</p>
<pre><code>docker pull cgr.dev/chainguard/mariadb:latest
</code></pre><p>Build this image the same way you did for the official image.  When you scan the two images, here's what you'll see:</p>
<pre><code>$ docker images
REPOSITORY         TAG       IMAGE ID       CREATED       SIZE
mariadb_cg         latest    <span class="hljs-number">50</span>a484d1ded3   <span class="hljs-number">7</span> days ago    <span class="hljs-number">556</span>MB
mariadb_standard   latest    <span class="hljs-number">67949</span>ccf8eb5   <span class="hljs-number">6</span> weeks ago   <span class="hljs-number">405</span>MB
</code></pre><p>The Chainguard image is, as you can see, quite larger. But note how it's actually a whole lot more recent. </p>
<h2 id="heading-how-to-scan-your-image">How to Scan Your Image</h2>
<p>Now it's time to put <code>docker scout</code> to work. Here's how that'll work. I'll point Scout to the <code>mariadb_standard</code> image first:</p>
<pre><code>$ docker scout qv mariadb_standard
</code></pre><p><code>qv</code>, by the way, is short for <code>quickview</code>. </p>
<p>Here's what the output should look like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/scan1.png" alt="Image" width="600" height="400" loading="lazy">
<em>docker scout output</em></p>
<p>The standard image is made up of three layers, beginning with the Ubuntu 23.10, then Ubuntu 22.04 long term support release, and then MariaDB on top. Ubuntu has 10 Low and 9 Medium vulnerabilities. Alarmingly, the MariaDB layer has 2 Critical and 28 High problems. </p>
<p>This should be enough to keep an admin up at night. And sorting through all of those to figure out which are show stoppers and which aren't such a big deal for your environment will take you a lot of time.</p>
<p>Now I'll run Scout against the Chainguard image: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/scan2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>First off, we can see that there's only one layer here. I suspect that's one way that Chainguard maintains control over their images. Those two Critical vulnerabilities are still there, but there are only 5 High severity and no Medium or Low at all. </p>
<p>If you wanted, you could dive deeper to display all the individual vulnerabilities. Here's the command to do that with an excerpt of the output:</p>
<pre><code>$ docker scout cves local:<span class="hljs-comment">//mariadb_cg</span>
    ✗ CRITICAL GHSA-xfg6<span class="hljs-number">-62</span>px-cxc2 [OWASP Top Ten <span class="hljs-number">2017</span> Category A9 - Using Components <span class="hljs-keyword">with</span> Known Vulnerabilities]
      <span class="hljs-attr">https</span>:<span class="hljs-comment">//scout.docker.com/v/GHSA-xfg6-62px-cxc2</span>
      Affected range : &lt;42.2.8                                         
      Fixed version  : 42.7.2, 42.6.1, 42.5.5, 42.4.4, 42.3.9, 42.2.8  
      CVSS Score     : 10.0                                            
      CVSS Vector    : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H    

    ✗ CRITICAL CVE-2024-1597 [Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')]
      https://scout.docker.com/v/CVE-2024-1597
      Affected range : &lt;42.2.28                                      
      Fixed version  : 42.2.28                                       
      CVSS Score     : 10.0                                          
      CVSS Vector    : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
</code></pre><p>We can research each of those using the standard CVE tools and databases to understand them better. But it'll be a whole lot easier than it would have been researching all 28 High severity vulnerabilities in the standard MariaDB image.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>So if you're worried about container image security – and you'd better be – then Docker Scout is an excellent tool for maintaining visibility in your stacks. And Chainguard's cleaner images can give you a significant head start.</p>
<p><em>There's more IT goodness in the form of books, courses, and videos available at <a target="_blank" href="https://bootstrap-it.com">my Bootstrap IT site</a>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How Do Open Source Software Lifecycles Work? ]]>
                </title>
                <description>
                    <![CDATA[ Software projects follow identifiable milestones as they move towards a successful completion. If you want to give your project the best chances of success, it's important to understand what those milestones mean and how they're defined. This article... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/understanding-open-source-software-lifecycles/</link>
                <guid isPermaLink="false">66b99657c39234149cf0110b</guid>
                
                    <category>
                        <![CDATA[ lifecycle methods ]]>
                    </category>
                
                    <category>
                        <![CDATA[ open source ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Tue, 26 Mar 2024 17:01:50 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/03/danial-igdery-FCHlYvR5gJI-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Software projects follow identifiable milestones as they move towards a successful completion. If you want to give your project the best chances of success, it's important to understand what those milestones mean and how they're defined.</p>
<p>This article comes from my Complete LPI Open Source Essentials Exam Study Guide <a target="_blank" href="https://www.udemy.com/course/complete-lpi-open-source-essentials-exam-study-guide/?referralCode=05B999CE18EF4D6E243C">Udemy course</a> and <a target="_blank" href="https://www.amazon.com/dp/B0CK3Q8DCF">book</a>. You can also <a target="_blank" href="https://youtu.be/eZ_4DLVxs7Q">view the video version</a>.</p>
<h2 id="heading-what-are-software-releases">What are Software Releases?</h2>
<p>There are several types of software releases and some related versioning methods used to keep track of software changes and to communicate them to users. We'll start with releases.</p>
<ul>
<li>There's the <strong>alpha release</strong> – an initial version of software that is typically not feature-complete and is not intended for use by the general public. It is used for testing and internal use only. </li>
<li>A <strong>beta release</strong> is a pre-release version of software that is feature-complete but may still have bugs or other issues. It is released to a limited audience for testing and feedback before the final release. </li>
<li>Next will be a <strong>release candidate</strong>, which is a version of software that is considered stable and ready for release, pending final testing and bug fixes. </li>
<li>And finally you'll produce a <strong>general availability release</strong> as the final version of software that's released to the general public.</li>
</ul>
<h2 id="heading-what-is-software-versioning">What is Software Versioning?</h2>
<p>Software versioning (sometimes known as semantic versioning) is the practice of assigning unique version numbers to different releases of software. </p>
<p>Here's a useful example:</p>
<pre><code>vmlinuz<span class="hljs-number">-5.19</span><span class="hljs-number">.0</span><span class="hljs-number">-40</span>-generic
</code></pre><p>In some approaches, the first number in the version number ("5" in this case) is the major version. A major version change indicates significant changes or new features that are not backward compatible with previous versions. </p>
<p>The second number ("19") is the minor version. A minor version change indicates new features or functionality that are backward compatible with previous versions.</p>
<p>The third number in the version number ("0") is the patch version. A patch version change indicates bug fixes or minor changes that are backward compatible with previous versions.</p>
<p>Why distinguish between major and minor releases? Major releases are typically used for significant changes or new features that are not backward compatible with previous versions. Major releases are usually announced to users and customers with a lot of fanfare, as they represent a significant milestone in the development of the software.</p>
<p>Minor releases, on the other hand, are used for smaller changes or new features that are backward compatible with previous versions. Minor releases are typically released more frequently and are intended to provide users with incremental improvements to the software.</p>
<h2 id="heading-what-does-backward-compatibility-mean">What Does Backward Compatibility Mean?</h2>
<p>Backward compatibility is the ability of a newer version of software or system to work with files, data, and other components created in an older version of that software or system. This means that users can upgrade to the newer version without losing access to their existing data or files.</p>
<p>For example, let's assume a user has created a document in an older version of a word processing program. If the newer version of the program is backward compatible, the user can open and edit the same document without any issues. This is because the newer version of the program is designed to read and interpret the file format used in the older version. </p>
<p>However, if the newer version of the program is not backward compatible, the user may not be able to open or edit the file created in the older version without first converting or re-creating it in the newer version. This can be a significant inconvenience for users and can lead to compatibility issues and data loss.</p>
<p>Here are some more quick – but important – definitions.</p>
<h2 id="heading-feature-freeze">Feature Freeze</h2>
<p>Feature freeze is a stage in the software development process where no new features are added to the product or project. It is typically implemented as a deadline by which all new features must be completed and approved before the release of the software product.</p>
<p>The primary goal of a feature freeze is to stabilize the software product in preparation for release. By setting a feature freeze deadline, developers can focus on completing and testing existing features rather than introducing new ones. This allows time for rigorous testing and bug fixing, improving the overall quality and reliability of the software product.</p>
<h2 id="heading-roadmaps">Roadmaps</h2>
<p>A roadmap is a high-level strategic document that outlines the goals, objectives, and timeline for a software product's development. It provides a visual representation of the product development plan, outlining key milestones and the expected timeline for completion. </p>
<p>Roadmaps are useful for communicating the overall direction of a software product to stakeholders, including developers, product managers, investors, and customers.</p>
<h2 id="heading-milestones">Milestones</h2>
<p>Milestones are specific, measurable achievements that mark progress towards the completion of a software product. They're typically set at regular intervals throughout the development process and are used to track progress and ensure that the project stays on schedule. </p>
<p>Examples of milestones might include the completion of a specific feature, the successful completion of a testing phase, or the release of a beta version of the software product.</p>
<h2 id="heading-changelog">Changelog</h2>
<p>A changelog is a document that lists the changes made to a software product over time, including bug fixes, new features, and other updates. Changelogs allow developers and other stakeholders to understand what's been updated and when. </p>
<p>Changelogs are particularly useful for software products that are updated frequently or have a large number of contributors.</p>
<h2 id="heading-long-term-support-lts">Long Term Support (LTS)</h2>
<p>Long term support refers to a software version that is designated for longer-term support and maintenance, typically for a period of several years. During this time, the software vendor provides ongoing support, including bug fixes, security updates, and other maintenance activities. </p>
<p>LTS versions are often used in enterprise environments where stability and reliability are critical. In April of each even year, for example, Canonical will release an LTS version of Ubuntu. These versions are normally supported for four or five years.</p>
<h2 id="heading-end-of-life-eol">End of Life (EOL)</h2>
<p>On the other hand, end-of-life refers to a point in time when a software version is no longer supported by the vendor. This means that the vendor will no longer provide updates or fixes for the software, and any security vulnerabilities or bugs that are discovered will not be addressed. This can leave users with unsupported software that may be prone to security risks and other issues.</p>
<p>When a software product reaches its end-of-life, it is typically retired, and users are encouraged to upgrade to a newer version or switch to a different product. The EOL process is often gradual, with the vendor providing advance notice and guidance to users to help them migrate to a new version or product.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>You've seen how it's important to understand the stages through which successful software projects will move. And this isn't just theoretical, because this knowledge gives you the tools to track your progress and quickly identify when things are going off rails.</p>
<p><em>This article comes from my</em> <a target="_blank" href="https://www.udemy.com/course/complete-lpi-open-source-essentials-exam-study-guide/?referralCode=05B999CE18EF4D6E243C"><em>Complete LPI</em></a> Open Source <em>Essentials Study Guide course__.</em> <em>And there's much more technology goodness available at <a target="_blank" href="https://bootstrap-it.com/">bootstrap-it.com</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Ensure Open Source License Compliance in Your Business ]]>
                </title>
                <description>
                    <![CDATA[ If you're using open source code in your operations, you'll want to manage things properly or potentially face legal issues, financial penalties, and damage to your reputation.  You don't need a law degree to avoid problems, but you should definitely... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/ensure-open-source-license-compliance-in-business/</link>
                <guid isPermaLink="false">66b995db77e922646120d72d</guid>
                
                    <category>
                        <![CDATA[ business ]]>
                    </category>
                
                    <category>
                        <![CDATA[ open source ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Tue, 05 Mar 2024 11:01:08 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/03/romain-dancre-doplSDELX7E-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you're using open source code in your operations, you'll want to manage things properly or potentially face legal issues, financial penalties, and damage to your reputation. </p>
<p>You don't need a law degree to avoid problems, but you should definitely familiarize yourself with some basic principles.</p>
<p>This article comes from my Complete LPI Open Source Essentials Exam Study Guide <a target="_blank" href="https://www.udemy.com/course/complete-lpi-open-source-essentials-exam-study-guide/?referralCode=05B999CE18EF4D6E243C">Udemy course</a> and <a target="_blank" href="https://www.amazon.com/dp/B0CK3Q8DCF">book</a>. You can also view the video version here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/u3zGMRAPAiI" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>We'll begin with some best practices:</p>
<ul>
<li>Conduct an inventory of all open source software used in your business workflow, including third-party libraries and dependencies. This will help you identify the licenses and terms of use associated with each piece of software. You'll also want to implement a system for tracking licenses and their terms of use. This can include using tools or software that automatically identify open source software and their associated licenses.</li>
<li>Create a license policy that outlines the procedures and guidelines for using open source software in your business workflow. This policy should be communicated to all employees and stakeholders involved in the software development process.</li>
<li>Use only approved open source licenses that comply with your license policy. This can help you avoid legal issues and ensure compliance with regulations.</li>
<li>Monitor changes to open source software licenses and updates to ensure continued compliance. This can include subscribing to notifications or alerts about license changes and updating your license inventory accordingly.</li>
<li>Document all steps taken to ensure compliance with open source licenses, including license reviews, approvals, and renewals. This documentation can help you demonstrate compliance in the event of an audit or legal challenge.</li>
</ul>
<p>That sounds like a lot of work. Well, you might consider creating an Open Source Program Office. Let's see how that works.</p>
<h2 id="heading-open-source-program-offices-ospo">Open Source Program Offices (OSPO)</h2>
<p>An OSPO is an organizational unit or team within a company or organization that's responsible for managing open source software and its use within the organization.</p>
<p>An OSPO helps organizations effectively manage the use of open source software by providing guidelines, policies, and procedures that ensure legal and regulatory compliance, proper usage, and contribution to the open source community. </p>
<p>The OSPO can also help organizations to establish a strategic direction for open source use, including identifying opportunities for collaboration with other organizations or contributing to industry-wide initiatives.</p>
<p>Typically, an OSPO is responsible for ensuring that the organization complies with the terms of open source licenses, including understanding license obligations, tracking license usage, and managing compliance risk. It'll also work to:</p>
<ul>
<li>Build relationships with the open source community, contributing to projects, and promoting internal contributions to open source projects</li>
<li>Develop and implement policies and governance frameworks that guide the organization's use of open source software</li>
<li>Develop and execute strategic plans for open source software use within the organization</li>
<li>Provide training and education to employees and stakeholders on the use of open source software, including compliance, governance, and community engagement.</li>
</ul>
<p>There are some useful business tools that can help simplify the administration of your software resources.</p>
<h2 id="heading-software-package-data-exchanges-spdx">Software Package Data Exchanges (SPDX)</h2>
<p>A Software Package Data Exchange, for instance, is a standard format for exchanging data related to software packages, including open source licenses, copyrights, and other related information. </p>
<p>SPDX is intended to simplify the sharing of information between developers, software vendors, and other stakeholders in the software supply chain. SPDX provides a common language for describing software packages and their associated licenses, making it easier to understand the terms of use and comply with license obligations.</p>
<p>The primary purpose of SPDX is to promote license compliance and facilitate the management of open source software. SPDX allows developers and organizations to easily identify the open source software components in their software products and track license obligations associated with each component.</p>
<h2 id="heading-the-software-bill-of-materials">The Software Bill of Materials</h2>
<p>A Software Bill of Materials (SBOM) is a list of all the components and dependencies that make up a software application or system. The SBOM provides information about the software's components, such as open source libraries, commercial software components, and proprietary code. </p>
<p>The goal of an SBOM is to improve transparency and accountability in software supply chains by providing a detailed inventory of the software components used in a product.</p>
<p>An SBOM typically includes information about the version, license, and origin of each component. An SBOM can help identify security vulnerabilities in a software system. By providing a complete list of all software components, developers and security teams can more easily identify and address security risks. </p>
<p>An SBOM can also helps ensure compliance with open source licenses and other legal requirements by providing information about the licenses associated with each component. And an SBOM can help manage supply chain risks by providing visibility into the software components used in a product. By knowing what components are used and where they come from, companies can more easily assess the risks associated with each component and make informed decisions about their use.</p>
<p>We should also take some time to talk about lawyers. Or, at least, the things that might get lawyers all excited. By which I mean to say that open source business models can carry legal risks, including risks related to product liability and export regulations. It's important for companies that use or distribute open source software to understand these risks and take appropriate measures to manage them.</p>
<h2 id="heading-product-liability">Product Liability</h2>
<p>Product liability is a legal concept that holds manufacturers or distributors of products liable for any harm caused to consumers by defects in the products. When a company uses or distributes open source software as part of its products, it assumes responsibility for any defects in the software that could cause harm to consumers. This could result in legal claims for product liability, which can be costly and damaging to the company's reputation.</p>
<p>To manage product liability risks associated with open source software, companies should implement effective quality assurance processes to ensure that the software is free from defects and meets industry standards. Companies should also work closely with their legal teams to understand the legal implications of using and distributing open source software, including any potential product liability risks.</p>
<p>Export regulations are another area of concern for companies that use or distribute open source software. Export regulations are laws and regulations that govern the export of goods and technology from one country to another. These regulations can restrict the export of certain types of technology or require companies to obtain licenses or certifications before exporting certain types of products.</p>
<p>Like any other technology, open source software can be subject to export regulations. Companies that use or distribute open source software should be aware of these regulations and ensure that their use and distribution of open source software comply with all applicable laws and regulations.</p>
<h2 id="heading-mergers-and-acquisitions">Mergers and Acquisitions</h2>
<p>One more lawyerly thing: mergers and acquisitions can have a significant impact on the use of open source software within organizations. When two companies merge or one company acquires another, they may have different approaches to the use of open source software and different policies and practices for managing open source licensing and compliance. This can create challenges and risks related to the integration of open source software.</p>
<p>One potential impact is that the acquiring company may need to conduct due diligence to understand the open source licensing and compliance practices of the acquired company. This can be a complex and time-consuming process, especially if the acquired company has a large and diverse software portfolio. The merged company may also need to reconcile different approaches to open source licensing and compliance. For example, if one company has a more permissive approach to open source licensing than the other, the merged company may need to develop a new policy or approach that takes both approaches into account.</p>
<p>Mergers and acquisitions can also impact the use of open source software in terms of product development and innovation. For example, if the acquiring company has a different technology stack or development process than the acquired company, it may need to integrate or replace open source components used by the acquired company. This can result in delays and added costs.</p>
<p>And don't forget that mergers and acquisitions can also impact the open source community. If a company that is an active contributor to an open source project is acquired, the new company may change its approach to the project or reduce its contributions. This can have a negative impact on the project and the community that supports it.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The bottom line? Building software can be fun and profitable and can change people's lives in positive ways. But, if you're not careful, it can also get you into a lot of trouble. </p>
<p>So take some time to educate yourself on your business and compliance responsibilities. </p>
<p><em>This article comes from my</em> <a target="_blank" href="https://www.udemy.com/course/complete-lpi-open-source-essentials-exam-study-guide/?referralCode=05B999CE18EF4D6E243C"><em>Complete LPI</em></a> Open Source <em>Essentials Study Guide course__.</em> <em>And there's much more technology goodness available at <a target="_blank" href="https://bootstrap-it.com/">bootstrap-it.com</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How Do Open Source Licenses Work? Permissive and Protective Software Licenses Explained ]]>
                </title>
                <description>
                    <![CDATA[ If you're going to use or work with open source resources, you'll need to understand the fine print on various classes of an open source license. Otherwise, how can you be sure you're not infringing on someone else's rights?  This article will introd... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/permissive-and-protective-software-licenses/</link>
                <guid isPermaLink="false">66b9962194b336889c60043e</guid>
                
                    <category>
                        <![CDATA[ open source ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Wed, 28 Feb 2024 17:07:49 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/02/katerina-pavlyuchkova-FQYCJSqER_0-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you're going to use or work with open source resources, you'll need to understand the fine print on various classes of an open source license. Otherwise, how can you be sure you're not infringing on someone else's rights? </p>
<p>This article will introduce you to the big players and concepts in the open source license universe.</p>
<p>This article comes from my Complete LPI Open Source Essentials Exam Study Guide <a target="_blank" href="https://www.udemy.com/course/complete-lpi-open-source-essentials-exam-study-guide/?referralCode=05B999CE18EF4D6E243C">Udemy course</a> and <a target="_blank" href="https://www.amazon.com/dp/B0CK3Q8DCF">book</a>. You can also view the video version here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/G7S5wY0PKkw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>In broad terms, we'll divide those classes into two categories. We'll discuss both permissive and restrictive licenses here.</p>
<h2 id="heading-working-with-permissive-software-licenses">Working with Permissive Software Licenses</h2>
<p>Permissive open source software licenses are a type of software license that allows for a wide range of uses of the licensed software. Some examples of permissive open source software licenses — that we'll explore in greater depth a bit later — include Apache, BSD, and MIT.</p>
<p>In general, permissive open source software licenses give you the right to use the software for any purpose – including commercial purposes – and the right to modify the software to suit your needs. </p>
<p>You'll get the right to distribute the software to others, either in its original form or as a modified version and the right to sublicense the software to others, allowing them to exercise the same rights as the original licensee. You'll also have the right to use any patents or trademarks associated with the software, as long as they comply with any applicable laws.</p>
<p>At the same time, permissive open source software licenses also impose certain obligations on users. You might be required to include a copyright notice when making further copies or distributions of the software. </p>
<p>You could also need to include a copy of the license in subsequent distributions. You might need to disclaim any warranties or liability for damages that may arise from the use of the software. And you'll often have to give attribution to the original software authors or contributors. Although there might also be times when using the names of those authors without explicit permission is <em>forbidden</em>.</p>
<p>The bottom line: make sure you read the fine print.</p>
<p>Now let's take a more detailed look at some actual permissive licenses.</p>
<h3 id="heading-the-2-clause-bsd-license">The 2-Clause BSD License</h3>
<p>The 2-Clause BSD License, also known as the Simplified BSD License, is a permissive open source software license that allows for a wide range of uses of the licensed software. </p>
<p>The license permits users to use, copy, modify, and distribute the software, as long as they include a copyright notice and disclaimer of any warranties or liability. The 2-Clause BSD License is commonly used for software that is released as open source but also used in proprietary software products.</p>
<h3 id="heading-the-3-clause-bsd-license">The 3-Clause BSD License</h3>
<p>The 3-Clause BSD License, also known as the New BSD License, is similar to the 2-Clause BSD License but includes an additional clause that requires users to include a copy of the license and copyright notice in any distributions of the software. This license is commonly used for open source software projects that want to ensure proper attribution and give credit to the original authors or contributors.</p>
<p>"BSD", by the way, stands for "Berkeley Software Distribution". The license is associated with the version of the Unix operating system that was developed at the University of California, Berkeley in the late 1970s and early 1980s.</p>
<h3 id="heading-the-mit-license">The MIT License</h3>
<p>The MIT License is a permissive open source software license that allows users to use, copy, modify, and distribute the software, as long as they include a copyright notice and disclaimer of any warranties or liability. </p>
<p>The license is similar to the 2-Clause BSD License but is often preferred for its brevity and simplicity. The MIT License is commonly used for open source software projects, especially those related to web development and programming languages.</p>
<p>"MIT", of course, stands for Massachusetts Institute of Technology, a private research university located in Cambridge, Massachusetts, USA. The MIT License is named after the university because it was developed by the university's computer science department and used for its open source software releases.</p>
<h3 id="heading-the-apache-license">The Apache License</h3>
<p>The Apache License version 2.0 is widely used for open source software projects, especially those related to web and server software. The license permits users to use, copy, modify, and distribute the software, as long as they include a copyright notice, disclaimer of any warranties or liability, and a notice of any changes made to the original software. </p>
<p>The license also includes patent grant provisions that protect users against patent infringement lawsuits. The Apache License version 2.0 is often considered to be one of the most permissive open source software licenses available.</p>
<h3 id="heading-the-eclipse-public-license-epl">The Eclipse Public License (EPL)</h3>
<p>The EPL is a permissive open source software license that was developed by the Eclipse Foundation for use with the Eclipse software development environment. On the other hand, EPL is <em>not</em> a permissive open source software license. In fact, EPL kind of straddles the border between permissive and restrictive. I'll describe it here, but bear in mind that it actually shares some features with the restrictive copyleft licenses we'll talk about later.</p>
<p>At any rate, the license is designed to be compatible with other open source software licenses and allows for the creation of derivative works.</p>
<p>The EPL version 1.0 is a copyleft license that requires any modifications or derivative works to be released under the same license. The license also includes a patent license grant that allows users to use any patents associated with the software, as long as they comply with the terms of the license.</p>
<p>The EPL version 2.0, released in 2017, is also a copyleft license but includes several updates and improvements over the previous version. The license has been updated to address some of the legal issues that arose with the previous version and to make it more compatible with other open source software licenses. One notable change in version 2.0 is the addition of a patent non-assertion covenant, which assures users that the software's licensors will not assert their patents against the user for using or distributing the licensed software.</p>
<h2 id="heading-working-with-protective-software-licenses">Working with Protective Software Licenses</h2>
<p>Copyleft software licenses aim to ensure that the licensed software remains free and open for future users and developers. These licenses use copyright law to achieve this goal by requiring any derivative works of the software to be licensed under the same license terms.</p>
<p>This means that anyone who modifies or distributes the software must also make their changes and additions available to others under the same license.</p>
<p>The most well-known copyleft software license is the GNU General Public License (GPL), but there are many other copyleft licenses such as the Lesser General Public License (LGPL), the Mozilla Public License (MPL), and the Affero General Public License (AGPL).</p>
<p>The rights and obligations defined by copyleft software licenses can vary depending on the specific license, but some common aspects include rights, typically granting users the right to use, modify, and distribute the software. The licenses often require that any derivative works be licensed under the same terms, which ensures that the software remains free and open for future use and development.</p>
<p>Copyleft software licenses also impose certain obligations on users and developers of the software. These obligations can include requirements to include a copy of the license with any distributions of the software, to make the source code available, and to maintain copyright notices and attribution to the original authors.</p>
<p>Copyleft licenses can have implications for compatibility with other licenses. For example, using individual software components licensed as copyleft as <em>part</em> of a larger project may require the entire project to be released under a copyleft license. This is because the copyleft license requires any derivative works to be licensed under the same terms.</p>
<p>Let's work through some of the more popular copyleft templates, one at a time.</p>
<h3 id="heading-the-gnu-general-public-license">The GNU General Public License</h3>
<p>The GPL is developed by the Free Software Foundation (FSF). It requires any derivative works of the licensed software to be licensed under the same terms. </p>
<p>The GPL has several versions, including version 2.0 (GPLv2) and version 3.0 (GPLv3). The GPL is widely used for software development projects and is often seen as a key component of the free software movement. </p>
<p>GPLv2 (that is, "version 2") of the GPL includes provisions for distributing the source code and making modifications to the software. GPLv3 added provisions for preventing "tivoization" (meaning, the practice of using digital restrictions to prevent users from modifying the software) and for addressing patent issues.</p>
<h3 id="heading-the-gnu-lesser-general-public-license">The GNU Lesser General Public License</h3>
<p>The LGPL is another license developed by the FSF that allows for more flexibility in the use of the licensed software. The LGPL has two versions, version 2 (LGPLv2) and version 3 (LGPLv3). </p>
<p>The LGPL is commonly used for software libraries and other software components that are designed to be linked with other software. LGPLv2 and LGPLv3 added more flexibility in the use of the licensed software, particularly for software libraries. Later versions also worked to add greater compatibility with the GPLv3.</p>
<h3 id="heading-the-gnu-affero-general-public-license">The GNU Affero General Public License</h3>
<p>The AGPL also comes from the FSF. It's similar to the GPL but includes additional requirements for software that is distributed over a network. </p>
<p>The AGPL is often used for software that's designed to be run on servers and accessed over a network, such as web applications. </p>
<p>Version 3 (AGPLv3) includes additional requirements for software that is distributed over a network. It requires anyone who uses the software over a network to make the source code available and to provide a copy of the license to users.</p>
<h3 id="heading-the-mozilla-public-license">The Mozilla Public License</h3>
<p>The MPL was developed by the Mozilla Foundation – the people behind the Firefox browser. It is a copyleft license that allows for the distribution of the licensed software under both proprietary and open source terms. The MPL is compatible with the GNU General Public License (GPL), allowing code to be shared between MPL-licensed software and GPL-licensed software. The MPL is also compatible with other open source licenses such as Apache and MIT.</p>
<p>The MPL requires that the source code for any modified versions of the licensed software be made available. This allows others to see and modify the code, promoting the growth and development of the software. The MPL also requires that any distribution of the licensed software, whether in its original or modified form, be made under the MPL. </p>
<p>This means that anyone who distributes the software must provide a copy of the license with the software and make the source code available. The MPL includes provisions to protect users from patent claims related to the licensed software. These provisions ensure that users of the software are able to use and distribute the software without fear of legal action.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>With this information you're now ready to carefully evaluate the benefits and limitations of each specific collection of open source code you might use. And you can similarly understand how you might want to license your own code when it's ready to be shared with the world.</p>
<p><em>This article comes from my</em> <a target="_blank" href="https://www.udemy.com/course/complete-lpi-open-source-essentials-exam-study-guide/?referralCode=05B999CE18EF4D6E243C"><em>Complete LPI</em></a> Open Source <em>Essentials Study Guide course__.</em> <em>And there's much more technology goodness available at <a target="_blank" href="https://bootstrap-it.com/">bootstrap-it.com</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Software Deployment Models – Explained for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ To effectively plan – or even talk about – application development intelligently, you usually have to understand which of the many program architectures you're referring to. In other words, software code can be deployed in many more ways than just th... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/software-deployment-models/</link>
                <guid isPermaLink="false">66b9963c94b336889c600440</guid>
                
                    <category>
                        <![CDATA[ deployment ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Mon, 08 Jan 2024 22:02:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/pexels-joshua-135018--1-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>To effectively plan – or even talk about – application development intelligently, you usually have to understand which of the many program architectures you're referring to. In other words, software code can be deployed in many more ways than just the "standard" web app.</p>
<p>So let's see what we've got. There's client/server computing, thin and fat clients, microservices, and various flavors of Application Programming Interfaces (APIs). Let's explore these one at a time.</p>
<p>This article comes from my Complete LPI Open Source Essentials Exam Study Guide <a target="_blank" href="https://www.udemy.com/course/complete-lpi-open-source-essentials-exam-study-guide/?referralCode=05B999CE18EF4D6E243C">Udemy course</a> and <a target="_blank" href="https://www.amazon.com/dp/B0CK3Q8DCF">book</a>. You can also <a target="_blank" href="https://www.youtube.com/watch?v=bX_gg9Czook">view the video version of the article on YouTube</a>.</p>
<h2 id="heading-clientserver-architectures">Client/Server Architectures</h2>
<p>Client/server computing architectures are a type of distributed computing architecture in which computing tasks are split between two types of machines: clients and servers. </p>
<p>A <em>client</em> is a device or program that requests services or resources from a server. Clients can be desktop computers, laptops, mobile devices, or any other device capable of making requests over a network. </p>
<p>A <em>server</em> is a device or program that provides services or resources to clients. Servers can be dedicated machines or programs that run on shared machines. Servers are responsible for processing requests from clients and returning the requested data or service.</p>
<p>The interaction between clients and servers is typically based on a request-response model. A client sends a request to a server over a network, and the server processes the request and sends a response back to the client.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/slide-35.png" alt="Image" width="600" height="400" loading="lazy">
<em>A typical client/server setup</em></p>
<p>The client/server architecture provides several advantages, including:</p>
<ul>
<li>Scalability, meaning that servers can be added or removed from the network as demand changes. This allows the system to scale up or down as needed without having to make changes on the clients.</li>
<li>Centralization, which means that by centralizing resources on servers, it is easier to manage and control access to those resources, and to enforce security policies.</li>
</ul>
<p>Examples of client/server applications include email servers, web servers, file servers, and database servers. In each case, the server provides a service or resource that clients can access over a network.</p>
<h2 id="heading-thin-client-and-fat-client-architectures">Thin Client and Fat Client Architectures</h2>
<p>Thin client and fat client architectures are different approaches to designing client/server computing systems. </p>
<p>In a <em>thin</em> client architecture, the client machine is responsible for only the presentation layer, while the application logic and data processing are handled on the server side. Thin clients typically have limited processing power and memory, and rely heavily on network connectivity to function.</p>
<p>When a user interacts with a thin client, the input is sent over the network to the server, which processes the request and sends back the necessary data to the client for display. </p>
<p>This approach can be more efficient in terms of hardware resources and easier to manage, as the server is responsible for most of the processing and storage. But it can also be more dependent on network connectivity and can suffer from latency issues if the network is slow or unreliable.</p>
<p>Fun fact (or, at least, a <em>relatively</em> fun fact): my very first serious administration project – and my introduction to Linux and network administration – involved deploying thin client infrastructure to save significant costs and efforts. It went well, and launched my admin career.</p>
<p>On the other hand, in a <em>fat</em> client architecture, the client machine is responsible for both the presentation layer and the application logic. The client machine typically has more processing power and memory, and can execute code and process data locally. </p>
<p>This approach can provide better performance and responsiveness, and can be more resilient to network connectivity issues.</p>
<p>When a user interacts with a fat client, the client machine processes the input and executes the necessary code and data processing locally, without relying on the server for every request. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/slide-38.png" alt="Image" width="600" height="400" loading="lazy">
<em>Thin clients outsource compute operations, while fat clients process operations locally</em></p>
<p>This approach can be more resource-intensive, as the client machine must have sufficient processing power and memory to handle the workload. It can also be more complex to manage, as updates and maintenance must be performed on both the client and server sides.</p>
<h2 id="heading-microservices-vs-monolith-architectures">Microservices vs. Monolith Architectures</h2>
<p>Now, should you design your software as a microservices or monolith architecture? In a <em>monolith</em> architecture, the entire application is built as a single, self-contained unit. All functionality, from data access to user interface, is bundled together in one codebase and deployed as a single unit. </p>
<p>Monoliths are typically easier to develop and deploy, but can become unwieldy and difficult to maintain as the codebase grows in size and complexity.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/slide-39.png" alt="Image" width="600" height="400" loading="lazy">
<em>A single, multi-purpose server workload</em></p>
<p>But in a <em>microservices</em> architecture, the application is divided into smaller, independent services that communicate with each other over a network. Each service is designed to perform a specific task or set of tasks, and can be developed and deployed independently of the other services. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/slide-40-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Specialized servers</em></p>
<p>Microservices can be more complex to develop and deploy, but offer greater flexibility and scalability, as each service can be scaled independently to handle changing workloads.</p>
<p>In a monolith architecture, all components of the application are tightly coupled, meaning that changes to one component can have a ripple effect throughout the entire system. This can make it difficult to scale or modify specific components of the application without affecting the entire system. </p>
<p>Microservices architectures, on the other hand, make use of loosely coupled features, meaning that changes to one service have minimal impact on other services. This makes it easier to modify or scale specific components of the application without affecting the entire system.</p>
<h2 id="heading-web-apps">Web Apps</h2>
<p>Web applications are software applications that are accessed through a web browser over a network such as the Internet. The purpose of web applications is to provide users with a convenient and accessible way to perform various tasks and access services over the web. </p>
<p>Web applications can be used for a wide range of purposes, such as e-commerce, online banking, social networking, email, file sharing, and online productivity tools. They can be designed to be accessible from any device with a web browser, including desktop computers, laptops, tablets, and smartphones.</p>
<p>Web applications are typically built using web development technologies such as HTML, CSS, and JavaScript, and can be hosted on a web server that communicates with client-side browsers using various web protocols such as HTTP and HTTPS.</p>
<h2 id="heading-single-page-applications-spas">Single Page Applications (SPAs)</h2>
<p>An SPA is a web application that loads a single HTML page and dynamically updates the content on that page as the user interacts with it. This is in contrast to traditional web applications, which require a full page refresh every time the user interacts with the application.</p>
<p>In an SPA, the initial HTML, CSS, and JavaScript are downloaded to the client-side browser, and subsequent interactions with the application are handled through asynchronous requests to the server-side API. The server returns data in a lightweight format, such as JSON, which the client-side JavaScript then uses to update the page content without refreshing the entire page.</p>
<p>SPAs are often built using modern JavaScript frameworks and libraries, such as React, Angular, and Vue.js. They offer several benefits over traditional web applications, such as faster load times, improved user experience, and reduced server load. But SPAs can also present some challenges, such as search engine optimization, accessibility, and managing the application state on the client-side.</p>
<h2 id="heading-application-programming-interfaces-apis">Application Programming Interfaces (APIs)</h2>
<p>An API is a set of rules, protocols, and tools that developers use to build software applications. The purpose of an API is to enable communication and integration between different software applications, allowing them to exchange data and functionality. </p>
<p>Or, in other words, APIs are a tool for securely and efficiently exposing compute functionality and data to public networks. Which is just a different way to bring about a software deployment.</p>
<p>APIs can be classified into several categories, based on their function and level of access:</p>
<ul>
<li>Open APIs, also known as public APIs, are accessible to developers outside the organization that owns the API, and often require no authentication or authorization to access.</li>
<li>Internal APIs, also known as private APIs, are intended for use within an organization and are not accessible to external developers.</li>
<li>Composite APIs are APIs that combine functionality from multiple APIs into a single interface, simplifying the development process for developers.</li>
<li>REST APIs are APIs that use the HTTP protocol to access and manipulate data, and are widely used for building web and mobile applications. They make it easy for developers to programmatically expose local resources to remote users in a controlled way. <strong>REST</strong> stands for Representational State Transfer Application Programming Interface.</li>
<li>SOAP APIs, where SOAP stands for Simple Object Access Protocol, are APIs that use the SOAP protocol to exchange data between different systems, and are commonly used for enterprise-level applications. These days, SOAP is a much less popular protocol than REST.</li>
</ul>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>We've worked through some of the most popular software deployment platform alternatives. Now, with a better sense of what's available, it's your turn to go out and create!</p>
<p><em>This article comes from my</em> <a target="_blank" href="https://www.udemy.com/course/complete-lpi-open-source-essentials-exam-study-guide/?referralCode=05B999CE18EF4D6E243C"><em>Complete LPI</em></a> Open Source <em>Essentials Study Guide course__.</em> <em>And there's much more technology goodness available at <a target="_blank" href="https://bootstrap-it.com/">bootstrap-it.com</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn to Control GPT in the OpenAI Playground ]]>
                </title>
                <description>
                    <![CDATA[ ChatGPT is the interface most people use to work with OpenAI's large language model. But for someone who needs the versatility and power of programmatic access, there's no replacement for OpenAI's API.  The API is the interface you can use to connect... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-to-control-gpt-in-openai-playground/</link>
                <guid isPermaLink="false">66b9960277e922646120d72f</guid>
                
                    <category>
                        <![CDATA[ Artificial Intelligence ]]>
                    </category>
                
                    <category>
                        <![CDATA[ chatgpt ]]>
                    </category>
                
                    <category>
                        <![CDATA[ LLM&#39;s  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ openai ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Fri, 08 Dec 2023 17:15:34 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/12/pexels-levi-damasceno-571249.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>ChatGPT is the interface most people use to work with OpenAI's large language model. But for someone who needs the versatility and power of programmatic access, there's no replacement for OpenAI's API. </p>
<p>The API is the interface you can use to connect programming code running on your own PC with OpenAI's GPT servers. </p>
<p>Of course, when using the API you can include plain language prompts where you ask GPT for answers and generated content. But you can also apply all the built-in power of that programming code to create sophisticated and automated operations that involve GPT. </p>
<p>You could, for instance, ask ChatGPT to write an article on a specific topic. But using the API, you can ask it to write 100 articles on the topics listed in a text document and then sit back while your code does all the work for you. </p>
<p>Anything that takes advantage of code rather than performing manual operations is a thousand times more effective when you add GPT to the equation.</p>
<p>The problem is that, like all APIs, figuring out the syntax and other fine details can take time. To help you over that hill, OpenAI created the visual tools within their <a target="_blank" href="https://platform.openai.com/playground">Playground</a>. Let's see how that'll help. </p>
<p>This article is excerpted from <a target="_blank" href="https://www.manning.com/books/the-complete-obsolete-guide-to-generative-ai?a_aid=bootstrap-it&amp;a_bid=8c39744&amp;a_bid=8c397448&amp;chan=fcc_ai">my Manning book, The Complete Obsolete Guide to Generative AI</a>. </p>
<h2 id="heading-what-is-the-playground">What is the Playground?</h2>
<p>Playground, shown in the figure below, existed even before ChatGPT, and it was where I had my first interactions with GPT. Although do keep in mind that, along with everything else in the AI world, the interface will probably have changed at least twice by the time you get to it. </p>
<p>We're going to use the playground throughout this tutorial to learn how to interact with GPT.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/gai-2-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>OpenAI's Playground interface</em></p>
<p>You get to <a target="_blank" href="https://platform.openai.com/playground">Playground</a> from your OpenAI login account. Rather than enjoying a sustained conversation where subsequent exchanges are informed by earlier prompts and completions, when the Chat option is selected from the pull-down at the top-left of the screen, the text field in Playground offers only one exchange at a time. The models it's based on might also be a bit older and less refined than the ChatGPT version.</p>
<p>But there are two things that set Playground apart from ChatGPT. One is the configuration controls displayed down the right side of the screen in the image above. The second is the <em>View code</em> feature at the top-right. It's those features that make Playground primarily an educational tool rather than just another GPT interface.</p>
<h2 id="heading-how-to-access-python-code-samples">How to Access Python Code Samples</h2>
<p>The image below shows a typical Playground session where I've typed in a prompt and then hit the "View code" button with the "Python" option selected. I'm shown working code that, assuming you'll add a valid OpenAI API key on line 4, can be copied and run from any internet-connected computer.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/gai-2-3-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Playground's View code tool with Python code</em></p>
<p>Don't worry about the details right now, but take a moment to look through the arguments that are included in the <code>openai.Completion.create()</code> method. </p>
<p>The model that's currently selected in the Model field on the right side of the Playground is there (<code>text-davinci-003</code>), as is my actual prompt (<code>Explain the purpose of...</code>). In fact, each configuration option I've selected is there. </p>
<p>In other words, I can experiment with any combination of configurations here in the Playground, and then copy the code and run it – or variations of it – anywhere.</p>
<p>This, in fact, is where you learn how to use the API. In other words, here is where you're shown code samples that can form the basis of a lot of what you'll eventually want to run in your own environment.</p>
<h2 id="heading-how-to-access-curl-code-samples">How to Access CURL Code Samples</h2>
<p>The next image shows us how that exact same prompt would work if I decided to use the command line tool, curl, instead of Python. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/gai-2-4.png" alt="Image" width="600" height="400" loading="lazy">
<em>Playground's View code tool with curl code</em></p>
<p><code>curl</code> is a venerable open source command line tool that's often available by default. You'll generally use <code>curl</code> when you want to access a remote server directly from your command line. Those will usually be for relatively simpler requests. </p>
<p>Python, on the other hand, will be the tool of choice for more complicated applications that involve programming logic.</p>
<p>To confirm it's available on your system, simply type <code>curl</code> at any command line prompt. You should see some kind of help message with suggestions for proper usage.</p>
<p>Besides Python and curl, you can also display code in Node.js (for when you're building server-based applications) and JSON (to enable programmatic integrations). </p>
<p>With that, you're all set to dive deeper than simple chat sessions: you're now able to finely control and programmatically automate your interactions with GPT from the comfort of your own command line (or IDE).</p>
<p>This article is excerpted from <a target="_blank" href="https://www.manning.com/books/the-complete-obsolete-guide-to-generative-ai?a_aid=bootstrap-it&amp;a_bid=8c39744&amp;a_bid=8c397448&amp;chan=fcc_ai">my Manning book, The Complete Obsolete Guide to Generative AI</a>. There's plenty more technology goodness available through <a target="_blank" href="https://bootstrap-it.com">my website</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Why You Might Want to Move Your Workloads Out of the Cloud ]]>
                </title>
                <description>
                    <![CDATA[ Is a public cloud like AWS or Microsoft's Azure the right place to host every deployment workload at every stage of its life? To be honest, I once thought that that was true – at least 95% of the time. But things have changed. Even though new service... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/why-you-might-want-to-move-your-workloads-out-of-the-cloud/</link>
                <guid isPermaLink="false">66b99675a3099de4654e61bb</guid>
                
                    <category>
                        <![CDATA[ Cloud Computing ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Wed, 29 Nov 2023 21:24:11 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/11/pexels-pixabay-52531.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Is a public cloud like AWS or Microsoft's Azure the right place to host <em>every</em> deployment workload at <em>every</em> stage of its life? To be honest, I once thought that that was true – at least 95% of the time.</p>
<p>But things have changed. Even though new services are being added to AWS, for example, nearly every week, we've had loads of time to figure out how things generally work. So it makes sense to listen when admins and industry leaders share their experiences.</p>
<p>In this article, I plan to share some important rationales for assessing and, perhaps, rethinking your deployment strategies. There's certainly no single approach that'll work for everyone, but everyone needs to at least consider the big picture.</p>
<p><em>This article is excerpted from my Pluralsight course: <a target="_blank" href="https://pluralsight.pxf.io/PyqkVQ">The IT Ops Sessions: Why Some Companies Are Moving OUT of the Cloud</a>.</em></p>
<h2 id="heading-whats-the-problem-with-the-cloud">What's the "Problem" with the Cloud?</h2>
<p>So what are the experts telling us? Number one seems to be that once your company hits a certain scale, cloud operating costs start to matter a lot. And that whole abstracted "reduced complexity" thing everyone talks about? Not so much.</p>
<p>Let's dive a bit deeper.</p>
<p>When all you've got running is a website on a single Linux instance and some data stored in a couple of S3 buckets, you'll barely notice the monthly bills.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/slide-10-3.png" alt="Image" width="600" height="400" loading="lazy">
<em>An AWS availability zone with a single EC2 instance and two S3 buckets</em></p>
<p>But once your user demand begins to rise and the possibility of losing some of your data or even a one hour outage keeps you up at night, then you'll need to give the numbers another look.</p>
<p>You see, once your application requires high availability, that single instance won't cut it any more. You'll need <em>at least</em> a second instance hosted in a different availability zone.</p>
<p>But now that your front-end is distributed, you'll need a dedicated high availability database running somewhere that each of your instances can access in real time. On AWS, that'll mean an RDS instance. And they're not free.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/slide-11.png" alt="Image" width="600" height="400" loading="lazy">
<em>Two AWS availability zones with replicated EC2 instances</em></p>
<p>Planning significant data transfers between your servers and users? Count on extra network costs <em>and</em> on more expensive network-optimized instance types. Sharing your instances with other AWS clients not good enough for your security requirements? Then you can add the ongoing costs of Dedicated Hosts.</p>
<p>You can try it out for yourself on the handy <a target="_blank" href="https://calculator.aws/#/">AWS Pricing Calculator</a>: it won't take long before your costs hit tens or even hundreds of thousands of dollars each month.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/aws_calculator-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>The output of a typical AWS Pricing Calculator estimate</em></p>
<p>Now I'm certainly not suggesting that those costs are unfair or that they're not justified. AWS and other big cloud providers work very hard to give you as much information as you'll need to understand what you'll be spending and even how you can spend less. But there's no hiding the fact that renting a lot of compute resources can get very expensive.</p>
<h2 id="heading-what-does-cloud-repatriation-look-like">What Does Cloud Repatriation Look Like?</h2>
<p>Now think what it might mean to apply all of those requirements to meet the needs of a company of the scale of Dropbox or even X – by which, of course, I mean Twitter – both of which have repatriated at least some of their cloud infrastructure.</p>
<p>Say what you like about Twitter (and everyone's got something to say), but they <a target="_blank" href="https://twitter.com/XEng/status/1717754398410240018">very recently announced</a> that their cloud reorganization led to a drop of 60% in their cloud-based media storage and that their cloud data processing costs dropped by 75%. Overall, estimates suggest that they're now spending around 60 million dollars less each year on AWS services.</p>
<p>But that's not even the impressive part. Because they made those changes at the same time they were <em>reducing</em> their employee count by 75%. And, while there's been plenty of entertaining chaos and mayhem on the platform, there were few if any notable service outages.</p>
<p>So not only did they cut their cloud usage, but they seem to have done it without incurring any "complexity" penalty – which of course would have required them to <em>increase</em> their hiring and other expenses. As an example, they claim to be saving another 13.9 million dollars a year through reconfiguring their network backbone.</p>
<p>Naturally, I couldn't throw such ideas at you without the earnest warning that you should never try this yourself at home. Or possibly even at work. What seems to have worked for X might not be a good fit for your organization.</p>
<p>But I can definitely tell you that it's not <em>just</em> X that we're talking about here. 37 Signals – the creators of Basecamp and Hey – expect to save around 7 million dollars over the five years following their 2022 pull-back from AWS. </p>
<p>The market intelligence firm IDC has noted that, in its experience, cloud repatriation has been visible since all the way back in the cloud's early days. They claim to have seen repatriation on some level within around 70 or 80 percent of companies each year.</p>
<p>But we're not necessarily talking about completely abandoning the cloud. Rather, it's a matter of understanding which workloads belong in the cloud and which on-premises or in colocation facilities. </p>
<p>As a rule, the cloud is a great place to test new workloads and smooth out the kinds of unpredictable demand you see in early deployments. But as you grow, cloud costs could increase to the point where, for at least some services, you can do it cheaper "at home".</p>
<p>And keep in mind that cloud migrations that weren't sufficiently planned and executed or went all-in rather than some form of a hybrid deployment are likely to fail over time. Proper preparation and planning are crucial.</p>
<p>As an Andreessen Horowitz report put it: "You're crazy if you don’t start in the cloud; you're crazy if you stay on it."</p>
<p>From here, your job will be to assess your current deployment profile and, if there are elements that need improving, begin mapping out your repatriation plan.</p>
<p>_T_here's much more technology goodness available__ for you through the books and courses available <em>at</em> <a target="_blank" href="https://bootstrap-it.com/"><em>bootstrap-it.com</em></a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Perform CRUD Operations – JavaScript and SQL Example ]]>
                </title>
                <description>
                    <![CDATA[ For the most part, interactive website architectures will involve generating or dispensing data of one sort or another. You can certainly use HTML forms to collect user input. But the kind of web form that's described here will only take you so far. ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-perform-crud-operations-js-and-sql/</link>
                <guid isPermaLink="false">66b995f17bb37b73c3f3c4e5</guid>
                
                    <category>
                        <![CDATA[ crud ]]>
                    </category>
                
                    <category>
                        <![CDATA[ database ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SQL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Thu, 03 Aug 2023 20:41:40 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/08/5f9ca0b7740569d1a4ca4a58.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>For the most part, interactive website architectures will involve generating or dispensing data of one sort or another. You can certainly use HTML forms to collect user input. But the kind of web form <a target="_blank" href="https://www.freecodecamp.org/news/creating-html-forms/">that's described here</a> will only take you so far. </p>
<p>What we really need is a way to reliably store and manipulate our data within the application environment. </p>
<p>In this article, I'm going to show you how to connect a back end database to your data collection process. The plan involves tossing some HTML, JavaScript, and the tiny database engine SQLite into a bowl, mixing vigorously, and seeing what comes out. </p>
<p>This article comes from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-web-development-essentials-exam-study-guide/?referralCode=C92570BCBB38302A9257">my Complete LPI Web Development Essentials Study Guide course</a>. If you'd like, you can follow the video version here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/yf2RJmpMEiI" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>As you may already know, the SQL in SQLite stands for <em>structured query language</em>. This means that the syntax you'll use for interacting with a SQLite database will closely parallel how you'd do it with databases like MariaDB, Amazon Aurora, Oracle, or Microsoft's SQL Server. If you've got experience with any of those, you'll be right at home here.</p>
<p>Why are we going to use SQLite here? Because it's a very popular choice for the kind of work you're likely to undertake in a web environment. </p>
<p>You'll need to create a new directory on your machine along with some files with JavaScript code. We'll learn how to create, modify, and delete records in a SQLite database. </p>
<p>I could incorporate all those actions into a single file, of course, but I think breaking them out into multiple files will make it easier to understand what's going on.</p>
<h2 id="heading-connecting-to-a-database-and-creating-a-table">Connecting to a Database and Creating a Table</h2>
<p>Here's what the first file will look like:</p>
<pre><code><span class="hljs-keyword">const</span> sqlite3 = <span class="hljs-built_in">require</span>(<span class="hljs-string">'sqlite3'</span>).verbose();

<span class="hljs-comment">// Create/connect to the database</span>
<span class="hljs-keyword">const</span> db = <span class="hljs-keyword">new</span> sqlite3.Database(<span class="hljs-string">'mydatabase.db'</span>);

<span class="hljs-comment">// Create a table</span>
db.run(<span class="hljs-string">`CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY,
    name TEXT,
    age INTEGER
)`</span>);

<span class="hljs-comment">// Insert data</span>
<span class="hljs-keyword">const</span> insertQuery = <span class="hljs-string">`INSERT INTO users (name, age) VALUES (?, ?)`</span>;
<span class="hljs-keyword">const</span> name = <span class="hljs-string">'Trevor'</span>;
<span class="hljs-keyword">const</span> age = <span class="hljs-number">5</span>;
db.run(insertQuery, [name, age], <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">err</span>) </span>{
    <span class="hljs-keyword">if</span> (err) {
        <span class="hljs-built_in">console</span>.error(err.message);
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Inserted data with id <span class="hljs-subst">${<span class="hljs-built_in">this</span>.lastID}</span>`</span>);
    }
});

<span class="hljs-comment">// Close the database connection</span>
db.close();
</code></pre><p>We begin by loading the sqlite3 module as <code>sqlite3</code> and then creating the <code>db</code> variable to represent our new database instance. The database will be called <code>mydatabase.db</code>. </p>
<pre><code><span class="hljs-keyword">const</span> sqlite3 = <span class="hljs-built_in">require</span>(<span class="hljs-string">'sqlite3'</span>).verbose();
<span class="hljs-keyword">const</span> db = <span class="hljs-keyword">new</span> sqlite3.Database(<span class="hljs-string">'mydatabase.db'</span>);
</code></pre><p>If there isn't a database using that name in our local directory, the code will create one, otherwise it'll just connect to the one that's there already.</p>
<p>Since this is our first run, I'll create a new table within the <code>mydatabase.db</code> database. There will be three keys in our table: <code>id</code>, <code>name</code>, and <code>age</code>. </p>
<pre><code>db.run(<span class="hljs-string">`CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY,
    name TEXT,
    age INTEGER
)`</span>);
</code></pre><p>As you can see, <code>id</code> will be the primary key that we'll use to reference individual records. </p>
<p>We defined the data type of each key: integer, text and, again, integer. This definition is something we only need to do once. But we do want to get it right, because changing it later, after we've already added data, can be tricky.</p>
<h2 id="heading-inserting-new-data-into-a-table">Inserting New Data into a Table</h2>
<p>In this section, we'll will add a new record to the table using the SQL <code>INSERT</code> command.</p>
<pre><code><span class="hljs-keyword">const</span> insertQuery = <span class="hljs-string">`INSERT INTO users (name, age) VALUES (?, ?)`</span>;
<span class="hljs-keyword">const</span> name = <span class="hljs-string">'Trevor'</span>;
<span class="hljs-keyword">const</span> age = <span class="hljs-number">5</span>;
db.run(insertQuery, [name, age], <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">err</span>) </span>{
    <span class="hljs-keyword">if</span> (err) {
        <span class="hljs-built_in">console</span>.error(err.message);
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Inserted data with id <span class="hljs-subst">${<span class="hljs-built_in">this</span>.lastID}</span>`</span>);
    }
});
</code></pre><p>You'll probably discover that official SQL documentation always capitalizes key syntax terms like <code>INSERT</code> and <code>SELECT</code>. That's a useful best practice, but it's not actually necessary. As a rule, I'm way too lazy to bother.</p>
<p>The query itself is templated as <code>insertQuery</code>, with the <code>name</code> and <code>age</code> details added as constants in the lines that follow. </p>
<p>The <code>db.run</code> method, using the <code>insertQuery</code> constant and those two values (<code>name</code> and <code>age</code>) as attributes, is then executed. Based on the success or failure of the operation, log messages will be generated.</p>
<p>But hang on for a moment. What's with those question marks after declaring <code>insertQuery</code>? And why did we need to break this process into two parts? </p>
<p>This is actually an important security practice known as an escape variable. With this in place, when the <code>db.run()</code> method executes the prepared statement, it'll automatically handle the escaping of the variable value, preventing SQL injection.</p>
<p>Lastly, we close down the connection:</p>
<pre><code>db.close();
</code></pre><h2 id="heading-modifying-data">Modifying Data</h2>
<p>Now let's see how the "modify" code works. Like before, we create a SQLite3 constant and then connect to our database. </p>
<p>This time, however, our table already exists, so we can go straight to the "modify" section.</p>
<pre><code><span class="hljs-keyword">const</span> sqlite3 = <span class="hljs-built_in">require</span>(<span class="hljs-string">'sqlite3'</span>).verbose();

<span class="hljs-comment">// Create/connect to the database</span>
<span class="hljs-keyword">const</span> db = <span class="hljs-keyword">new</span> sqlite3.Database(<span class="hljs-string">'mydatabase.db'</span>);

<span class="hljs-comment">// Modify data</span>
<span class="hljs-keyword">const</span> updateQuery = <span class="hljs-string">`UPDATE users SET age = ? WHERE name = ?`</span>;
<span class="hljs-keyword">const</span> updatedAge = <span class="hljs-number">30</span>;
<span class="hljs-keyword">const</span> updatedName = <span class="hljs-string">'name2'</span>;
db.run(updateQuery, [updatedAge, updatedName], <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">err</span>) </span>{
    <span class="hljs-keyword">if</span> (err) {
        <span class="hljs-built_in">console</span>.error(err.message);
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Modified <span class="hljs-subst">${<span class="hljs-built_in">this</span>.changes}</span> row(s)`</span>);
    }
});

<span class="hljs-comment">// Close the database connection</span>
db.close();
</code></pre><p>The pattern is similar. We define an <code>updateQuery</code> method to <code>UPDATE</code> a record that we'll define. This operation will change the <code>age</code> value for an entry whose name equals <code>Trevor</code>. </p>
<p>You may recall that Trevor's age was earlier listed as 25. We're going to update that to 30. Everything else will work the same as before, including closing the connection when we're done.</p>
<p>This section of code from the third file will delete a record:</p>
<pre><code><span class="hljs-keyword">const</span> deleteQuery = <span class="hljs-string">`DELETE FROM users WHERE name = ?`</span>;
<span class="hljs-keyword">const</span> deletedName = <span class="hljs-string">'name1'</span>;
db.run(deleteQuery, [deletedName], <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">err</span>) </span>{
    <span class="hljs-keyword">if</span> (err) {
        <span class="hljs-built_in">console</span>.error(err.message);
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Deleted <span class="hljs-subst">${<span class="hljs-built_in">this</span>.changes}</span> row(s)`</span>);
    }
});
</code></pre><p>The code above will delete the record where the name equals <code>Trevor</code>.</p>
<p>You can run any of those files using the <code>node</code>  command. But you should first make sure that you've installed the <code>sqlite3</code> module:</p>
<pre><code>$ npm install sqlite3
</code></pre><p>Next I'll use <code>node</code> to run the first file (that you could choose to call <code>db.js</code>). </p>
<pre><code>$ node db.js
Inserted data <span class="hljs-keyword">with</span> id <span class="hljs-number">1</span>
</code></pre><p>We'll see that a new record has been successfully inserted. If you list the directory contents, you'll also see that a new <code>mydatabase.db</code> file has been created.</p>
<p>You can always manually log into sqlite3 to see how things might have changed. I'll reference the <code>mydatabase.db</code> file so we can open it up right away. </p>
<pre><code>$ sqlite3 mydatabase.db
</code></pre><p>Typing <code>.tables</code> within the SQLite interface will list all the existing tables in this database. In our case, it'll be the <code>users</code> table we created. </p>
<pre><code>sqlite&gt; .tables
users
sqlite&gt;
</code></pre><p>Now I'll use the SQL <code>select</code> command to display a record. Here I'll use the asterisk to represent all records and specify the <code>users</code> table. </p>
<pre><code>sqlite&gt; SELECT * FROM users;
<span class="hljs-number">1</span>|Trevor|<span class="hljs-number">25</span>
sqlite&gt;
</code></pre><p>We can see that record <code>1</code> containing <code>Trevor</code> who is 25 years old has been created. Great!</p>
<p>Finally, we can run the <code>delete</code> code which should remove Trevor altogether:</p>
<pre><code><span class="hljs-keyword">const</span> deleteQuery = <span class="hljs-string">`DELETE FROM users WHERE name = ?`</span>;
<span class="hljs-keyword">const</span> deletedName = <span class="hljs-string">'Trevor'</span>;
db.run(deleteQuery, [deletedName], <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">err</span>) </span>{
    <span class="hljs-keyword">if</span> (err) {
        <span class="hljs-built_in">console</span>.error(err.message);
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Deleted <span class="hljs-subst">${<span class="hljs-built_in">this</span>.changes}</span> row(s)`</span>);
    }
});
</code></pre><p>I should note that the <code>db.run</code> and <code>db.close</code> format I used for those methods can also be referred to as <code>Database.run()</code>, and <code>database.close()</code>. It's just a matter of preference - or, in my case, laziness. I'm a Linux admin, after all, and the very best admins are, in principle, lazy.</p>
<h2 id="heading-summary">Summary</h2>
<p>We've seen how use JavaScript to connect to a back end database, create a new table, and then add, modify, and delete records in that table. And we seem to have gotten away with it, too! </p>
<p>Now try this on your own computer. But play around with the values. Even better: build something practical.</p>
<p><em>This article comes from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-web-development-essentials-exam-study-guide/?referralCode=C92570BCBB38302A9257">my Complete LPI Web Development Essentials Study Guide course</a>.</em> <em>And there's much more technology goodness available at <a target="_blank" href="https://bootstrap-it.com/">bootstrap-it.com</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Node.js? Server-Side JavaScript Development Basics ]]>
                </title>
                <description>
                    <![CDATA[ Node.js is a powerful runtime environment for executing JavaScript code outside of a web browser. It brings the JavaScript language to the server-side, enabling developers to build scalable, high-performance, and event-driven applications. Let's disc... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/node-js-basics/</link>
                <guid isPermaLink="false">66b9961894b336889c60043c</guid>
                
                    <category>
                        <![CDATA[ beginners guide ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ node js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Tue, 25 Jul 2023 18:24:42 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/pexels-tomasz-filipek-1630035.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Node.js is a powerful runtime environment for executing JavaScript code <em>outside</em> of a web browser. It brings the JavaScript language to the server-side, enabling developers to build scalable, high-performance, and event-driven applications.</p>
<p>Let's discover how Node.js code works, and how that code can be integrated within your JavaScript and then executed.</p>
<p>This article comes from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-web-development-essentials-exam-study-guide/?referralCode=C92570BCBB38302A9257">my Complete LPI Web Development Essentials Study Guide course</a>. If you'd like, you can follow the video version here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/pSvvqaXCL30" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>Node.js allows developers to use JavaScript both on the client-side and the server-side, providing a unified language and ecosystem. This eliminates the need for context switching and enables code reuse between the front-end and back-end. This results in improved productivity and reduced development time.</p>
<p>Node.js has a vast and active ecosystem of modules and libraries available through the Node Package Manager (npm). This rich ecosystem offers ready-to-use tools and packages for various functionalities, such as web frameworks, database connectors, authentication, and testing frameworks. </p>
<p>Developers can leverage these modules to accelerate development and enhance application functionality.</p>
<p>Given all that, Node.js is particularly well-suited for building:</p>
<ul>
<li>Web applications</li>
<li>Scalable APIs</li>
<li>Real-time applications requiring instant data updates and bidirectional communication like chat applications and multiplayer games</li>
<li>Streaming applications like audio or video processing or real-time analytics</li>
<li>Single-page applications</li>
<li>Internet of Things deployments</li>
</ul>
<p>All that sound like a good match for some useful web applications? I thought it would. So let's see how it all works. </p>
<h2 id="heading-how-to-build-a-nodejs-server-environment">How to Build a Node.js Server Environment</h2>
<p>First off, you won't need to set up and run a third-party web server like Apache HTTPD or NGINX or place your content within the <code>/var/www/html</code> directory hierarchy. That's because Node.js is, among other things, a web server framework. </p>
<p>Let me show you what that means. You'll need to make sure you've got Node.js installed along with the necessary dependencies. By and large, you'll use the NPM package manager to get that done. There's excellent documentation for installing Node on your OS <a target="_blank" href="https://nodejs.org/en/download">from the official website</a>. </p>
<p>You can confirm that both Node and NPM are live and waiting for action by running these commands:</p>
<pre><code>$ node -v
v18<span class="hljs-number">.16</span><span class="hljs-number">.0</span>
$ npm -v
<span class="hljs-number">9.5</span><span class="hljs-number">.1</span>
</code></pre><p>Just to have some HTML to work with, you should find or create a simple <code>index.html</code> file and save it to a local directory on your machine. This command will download the <code>html</code> of an LPI page from my own website if you need something quick and small:</p>
<pre><code>wget https:<span class="hljs-comment">//bootstrap-it.com/lpi/</span>
</code></pre><p>Let's take a look at the <code>server.js</code> code we used for our Node server. </p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);

<span class="hljs-keyword">const</span> server = http.createServer(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-comment">// Read the HTML file</span>
  fs.readFile(<span class="hljs-string">'index.html'</span>, <span class="hljs-string">'utf8'</span>, <span class="hljs-function">(<span class="hljs-params">err, data</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (err) {
      res.writeHead(<span class="hljs-number">500</span>, { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'text/plain'</span> });
      res.end(<span class="hljs-string">'Error loading HTML file'</span>);
      <span class="hljs-keyword">return</span>;
    }

    res.writeHead(<span class="hljs-number">200</span>, { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'text/html'</span> });
    res.end(data);
  });
});

<span class="hljs-keyword">const</span> port = <span class="hljs-number">3000</span>;
server.listen(port, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server is running on http://localhost:<span class="hljs-subst">${port}</span>`</span>);
});
</code></pre>
<p>Now let's work through that code, one section at a time. We begin by loading two necessary modules: <code>http</code> to manage the website hosting, and <code>fs</code> to read the HTML files. </p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
</code></pre>
<p>We then create a server function – called <code>server</code>. When called, it will either read and serve our <code>index.html</code> file (generating a 200 success code) or, if there's a problem reading the file, it'll generate a 500 error message.</p>
<pre><code class="lang-javascript">  fs.readFile(<span class="hljs-string">'index.html'</span>, <span class="hljs-string">'utf8'</span>, <span class="hljs-function">(<span class="hljs-params">err, data</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (err) {
      res.writeHead(<span class="hljs-number">500</span>, { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'text/plain'</span> });
      res.end(<span class="hljs-string">'Error loading HTML file'</span>);
      <span class="hljs-keyword">return</span>;
    }
</code></pre>
<p>The code continues by setting 3000 as the listening port for our application – although, technically, you could change that to any value you like between 1 and 65535. </p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> port = <span class="hljs-number">3000</span>;
</code></pre>
<p>Finally, we call the <code>server</code> function using the <code>listen</code> method and specifying the port number, and then writing an entry to <code>console.log</code>.</p>
<pre><code class="lang-javascript">server.listen(port, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server is running on http://localhost:<span class="hljs-subst">${port}</span>`</span>);
</code></pre>
<h2 id="heading-how-to-execute-your-nodejs-server">How to Execute Your Node.js Server</h2>
<p>Running the <code>npm init</code> command in the same directory were your program files will live is used to initialize a new Node.js project and create a <code>package.json</code> file. </p>
<p>The <code>package.json</code> file serves as the manifest for the project, containing metadata and configuration information about the project, its dependencies, scripts, and other details.</p>
<p>You can manually add dependencies to the file or use:</p>
<pre><code class="lang-js">npm install &lt;package-name&gt;
</code></pre>
<p>...to add packages and their versions to the dependencies section of the <code>package.json</code>.</p>
<p>When you actually run <code>npm init</code> to initialize a directory for a new project, a script will ask you some questions. The default values npm suggests for you will include <code>1.0.0</code> as a version number and an entry point of <code>index.js</code>. </p>
<p>You'll also have the option of setting a git repo, keywords, and a choice of user license models. All the defaults should work just fine.</p>
<p>When that's done, the script will show you the proposed JSON-formatted version of your settings and ask for your approval. The <code>package.json</code> file that was created will reflect those settings.</p>
<p>For our project, install the MySQL database connector module along with express.js:</p>
<pre><code class="lang-javascript">$ npm install mysql
$ npm install express.js
</code></pre>
<p>Neither takes more than a few seconds. When that's all done, I'll see that there's now a new file in town: <code>package-lock.json</code>. </p>
<p>Peeking inside that file will show you an awful lot of JSON goodness. What's that all about? The package-lock.json file is automatically generated by npm when you install dependencies for your project. It serves as a lockfile that ensures deterministic and reproducible builds of your project across different environments. </p>
<p>It's important to include the package-lock.json file in version control systems like Git so that other developers or deployment environments can reproduce the exact dependency tree and versions used in the project. This ensures consistency and avoids potential conflicts or surprises when working with dependencies.</p>
<p>There will also be a new <code>node_modules</code> directory that was automatically created and populated by that init operation. This directory is a storage location for all the packages and modules our project relies on. When you install packages using <code>npm install</code>, the downloaded packages are placed here. </p>
<p>npm automatically resolves and installs the required dependencies of each package. It creates a hierarchical structure in the node_modules directory that reflects the dependency tree of your project.</p>
<p>Launching your server is straightforward:</p>
<pre><code class="lang-javascript">$ node server.js
</code></pre>
<p>To view the service, open your browser and direct it to the application URL, using port <code>3000</code>. When your browser is on the same machine as the Node server, this is how that'll look:</p>
<pre><code class="lang-javascript">localhost:<span class="hljs-number">3000</span>
</code></pre>
<p>Of course, you don't really need Node.js just for that. The value of Node.js comes from building user interactivity by integrating it with a backend database. That can happen using Express.js, but it'll have to wait for another time.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>What we <em>have</em> seen here is how the magic behind building a Node.js environment can provide all the infrastructure and backend functionality you need to launch and maintain an interactive and dynamic server.</p>
<p><em>This article comes from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-web-development-essentials-exam-study-guide/?referralCode=C92570BCBB38302A9257">my Complete LPI Web Development Essentials Study Guide course</a>.</em> <em>And there's much more technology goodness available at <a target="_blank" href="https://bootstrap-it.com/">bootstrap-it.com</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Manipulate HTML and CSS Using JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ In JavaScript, the HTML DOM (Document Object Model) represents the structure and content of an HTML document as a tree-like structure. In it, each element, attribute, and text node in the HTML document is represented as a node in the DOM tree.  In th... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/manipulate-html-and-css-using-javascript/</link>
                <guid isPermaLink="false">66b9961017d9592471979c28</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Wed, 19 Jul 2023 18:00:02 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/pexels-pixabay-276205.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In JavaScript, the HTML DOM (Document Object Model) represents the structure and content of an HTML document as a tree-like structure. In it, each element, attribute, and text node in the HTML document is represented as a node in the DOM tree. </p>
<p>In this article you're going to learn how you can use that structure to more effectively control the way your HTML elements behave. You'll also learn how to use it to add dynamic interactivity to your users' experience. </p>
<p>This article comes from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-web-development-essentials-exam-study-guide/?referralCode=C92570BCBB38302A9257">my Complete LPI Web Development Essentials Study Guide course</a>. If you'd like, you can follow the video version here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/DIg-GoyKUqA" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-understanding-dom-elements">Understanding DOM elements</h2>
<p>The HTML DOM provides a way to interact with and manipulate the elements of an HTML document using JavaScript. It allows you to access, modify, and add elements dynamically, change styles and classes, handle events, and perform other operations on the document.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/642px-DOM-model.svg.png" alt="commons.wikimedia.org/wiki/File:DOM-model.svg using the CC Attribution-Share Alike 3.0 Unported license.\label{fig:dom_model}" width="600" height="400" loading="lazy">
<em>commons.wikimedia.org/wiki/File:DOM-model.svg using the CC Attribution-Share Alike 3.0 Unported license</em></p>
<p>As you can see from that illustration, <code>Document</code> is the top-level object representing an HTML document. It serves as the entry point for accessing the DOM tree and provides methods for navigating and manipulating the document. </p>
<p><code>Element</code> represents an HTML element in the DOM tree. Elements have properties that allow you to access and modify attributes, styles, and content. You can select elements using various methods like:</p>
<ul>
<li><code>getElementById</code></li>
<li><code>getElementsByTagName</code></li>
<li><code>getElementsByClassName</code></li>
<li><code>querySelector</code> </li>
<li><code>querySelectorAll</code></li>
</ul>
<p><code>Node</code> is the base class for all types of nodes in the DOM tree. Nodes can be elements, text nodes, comment nodes, and so on. They have properties and methods for common operations, such as accessing parent and child nodes, manipulating node content, and more.</p>
<p>The DOM provides an event system to handle user interactions and other events. You can attach event listeners to elements to respond to events like clicks, keypresses, and mouse movements.</p>
<h2 id="heading-how-to-interact-with-the-dom-using-javascript">How to Interact with the DOM using JavaScript</h2>
<p>Using JavaScript, you can interact with the HTML DOM to dynamically modify the content and behavior of an HTML page. This allows you to create interactive web applications, implement dynamic user interfaces, and perform various operations on the document based on user actions or programmatic logic.</p>
<p>Here's a simple example that actually does something surprising:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>DOM Manipulation Example<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myHeading"</span>&gt;</span>Hello, World!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myParagraph"</span>&gt;</span>This is a paragraph.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-comment">// Changing the contents and properties of HTML elements</span>
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myHeading"</span>).innerHTML = <span class="hljs-string">"New Heading"</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myParagraph"</span>).style.color = <span class="hljs-string">"red"</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myParagraph"</span>).textContent = <span class="hljs-string">"This is updated."</span>;
  </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>We have an HTML document that contains a heading <code>&lt;h1&gt;</code> element with an id of <code>myHeading</code> and a paragraph <code>&lt;p&gt;</code> element with an id of <code>myParagraph</code>. </p>
<pre><code>  &lt;h1 id=<span class="hljs-string">"myHeading"</span>&gt;Hello, World!&lt;/h1&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myParagraph"</span>&gt;</span>This is a paragraph.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
</code></pre><p>The JavaScript code within the <code>&lt;script&gt;</code> tags manipulates these elements through the DOM.</p>
<pre><code> &lt;script&gt;
    <span class="hljs-comment">// Changing the contents and properties of HTML elements</span>
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myHeading"</span>).innerHTML = <span class="hljs-string">"New Heading"</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myParagraph"</span>).style.color = <span class="hljs-string">"red"</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myParagraph"</span>).textContent = <span class="hljs-string">"This is updated."</span>;
 &lt;/script&gt;
</code></pre><p>The code uses the <code>getElementById</code> method to select elements by their id attribute. It then modifies the elements' contents and properties using the following DOM manipulation techniques:</p>
<ul>
<li><code>innerHTML</code> sets the HTML content inside the selected element. In this case, we change the heading's text to "New Heading".</li>
<li><code>style</code> accesses the CSS styles of the selected element. We set the paragraph's text color to red.</li>
<li><code>textContent</code> sets the text content of the selected element. We update the paragraph's text to "This is an updated paragraph."</li>
</ul>
<p>When we load the HTML document in a web browser, the JavaScript code executes immediately. You'll never see the original HTML styling, but just the "updates" ordered by the JavaScript. The heading text will be "New Heading", the paragraph text color will be red, and the paragraph content will be "This is updated."</p>
<p>This demonstrates how JavaScript can interact with the DOM to dynamically modify the contents and properties of HTML elements based on programmatic logic or user interactions.</p>
<h2 id="heading-how-to-make-your-websites-more-interactive">How to Make Your Websites More Interactive</h2>
<p>You can also trigger changes to an HTML page in response to user activities. In this example, we define two JavaScript functions: <code>showMessage</code> and <code>changeColor</code>. These functions are triggered from HTML elements using the <code>onclick</code> attribute.</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Triggering JavaScript Functions<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">showMessage</span>(<span class="hljs-params"></span>) </span>{
      alert(<span class="hljs-string">"Button clicked!"</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeColor</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myDiv"</span>).style.backgroundColor = <span class="hljs-string">"red"</span>;
    }
  </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Triggering JavaScript Functions Example<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"showMessage()"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myDiv"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"width: 200px; height: 200px; background-color: blue;"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"changeColor()"</span>&gt;</span>Change color<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The <code>showMessage</code> function displays an alert box with the message "Button clicked!" when the button is clicked. </p>
<pre><code>    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">showMessage</span>(<span class="hljs-params"></span>) </span>{
      alert(<span class="hljs-string">"Button clicked!"</span>);
    }
</code></pre><p>The <code>changeColor</code> function changes the background color of the <code>&lt;div&gt;</code> element with the id of <code>myDiv</code> to red when the button is clicked. </p>
<pre><code>    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeColor</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myDiv"</span>).style.backgroundColor = <span class="hljs-string">"red"</span>;
    }
</code></pre><p>The HTML code includes a button with the <code>onclick</code> attribute set to <code>showMessage()</code>, which triggers the <code>showMessage</code> function when the button is clicked. </p>
<p>Similarly, there's another button with the <code>onclick</code> attribute set to <code>changeColor()</code>, which triggers the <code>changeColor</code> function when the button is clicked.</p>
<pre><code>  &lt;button onclick=<span class="hljs-string">"showMessage()"</span>&gt;Click me&lt;/button&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myDiv"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"width: 200px; height: 200px; background-color: blue;"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"changeColor()"</span>&gt;</span>Change color<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
</code></pre><p>When you load the HTML document in a web browser, you'll see the heading, two buttons, and a colored <code>&lt;div&gt;</code> element. Clicking the "Click me" button will trigger the showMessage function and display an alert.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/js1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Clicking the "Change color" button will trigger the <code>changeColor</code> function and change the background color of the <code>&lt;div&gt;</code> element to red.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/js2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>As I'm sure you can guess, this barely scratches the surface on what you can do with DOM. Here's a longer list of DOM-friendly elements and methods and HTML attributes that you can also play with:</p>
<ul>
<li>document.getElementById()</li>
<li>document.getElementsByClassName()</li>
<li>document.getElementsByTagName()</li>
<li>document.querySelector()</li>
<li>document.querySelectorAll()</li>
<li>innerHTML, setAttribute()</li>
<li>removeAttribute()</li>
<li>classList</li>
<li>classList.add()</li>
<li>classList.remove()</li>
<li>classList.toggle()</li>
<li>onClick</li>
<li>onMouseOver</li>
<li>onMouseOut</li>
</ul>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>This was a brief introduction to DOM elements, where you caught a quick glimpse of the how and whys of <em>controlling</em> HTML elements. You also learned how you can add dynamic interactivity and fine-tuned programmatic versatility to your website.</p>
<p><em>This article comes from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-web-development-essentials-exam-study-guide/?referralCode=C92570BCBB38302A9257">my Complete LPI Web Development Essentials Study Guide course</a>.</em> <em>And there's much more technology goodness available at <a target="_blank" href="https://bootstrap-it.com/">bootstrap-it.com</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Start Learning JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Just in case you haven't yet been properly introduced, JavaScript is a powerful programming language that provides significant value in web development. Its benefits include: Server-side development through Node.js Client-side interactivity where sc... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/getting-started-with-javascript/</link>
                <guid isPermaLink="false">66b995ddc39234149cf010fd</guid>
                
                    <category>
                        <![CDATA[ beginner ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Thu, 13 Jul 2023 20:22:41 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/pexels-mikhail-nilov-6968122.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Just in case you haven't yet been properly introduced, JavaScript is a powerful programming language that provides significant value in web development.</p>
<p>Its benefits include:</p>
<ul>
<li>Server-side development through Node.js</li>
<li>Client-side interactivity where scripts run directly within your users' browsers</li>
<li>Responsive and interactive user interfaces</li>
<li>Broad API and third-party service integration that permit multi-tier applications</li>
<li>Cross-platform mobile app development through frameworks like React Native and Ionic</li>
<li>Near-universal browser support, and vast ecosystem of libraries, frameworks, and tools</li>
</ul>
<p>If you're planning to add interactivity into any of your websites, then you'll need to pick up some JavaScript skills. But the basics are actually pretty straightforward. </p>
<p>In this article I'm going to show you how you can incorporate JavaScript into your HTML code, what simple operations might look like using JavaScript, how to create and execute functions in JavaScript, and how you can take advantage of your browser's console to test JavaScript in a live – but safe – environment.</p>
<p>By the way, there isn't any technical connection between JavaScript and the Java programming language. </p>
<p>Some time after Brendan Eich created his LiveScript language at Netscape in just 10 days back in 1995, legend has it, he renamed his project JavaScript to leverage the popularity of Java at the time. </p>
<p>But that was more of a marketing strategy than an indication of any technical relationship.</p>
<p>This article comes from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-web-development-essentials-exam-study-guide/?referralCode=C92570BCBB38302A9257">my Complete LPI Web Development Essentials Study Guide course</a>. If you'd like, you can follow the video version here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/TrARdpmfD7c" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-how-to-incorporate-javascript-into-your-html-code">How to Incorporate JavaScript into Your HTML Code</h2>
<p>You can include JavaScript code in your HTML web pages in a couple ways. First, you can do it by referencing an external <code>.js</code> file as an attribute of a <code>&lt;script&gt;</code> tag – the way you see here:</p>
<pre><code>&lt;script src=<span class="hljs-string">"script.js"</span>&gt;&lt;/script&gt;
</code></pre><p>Or you can drop your code between <code>&lt;script&gt;</code> tags in the head section of your HTML like this:</p>
<pre><code>&lt;head&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>JavaScript App Example<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greet</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">var</span> name = prompt(<span class="hljs-string">"What's your name?"</span>);
      alert(<span class="hljs-string">"Hello, "</span> + name + <span class="hljs-string">"!"</span>);
    }
  </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
&lt;/head&gt;
</code></pre><p>Both work fine. Since the adoption of HTML5, however, you no longer need to add <code>text/javascript</code> as an attribute of the <code>&lt;script&gt;</code> tag. At this point, JavaScript is the <em>default</em> scripting language for HTML.</p>
<h2 id="heading-how-to-execute-some-simple-javascript">How to Execute Some Simple JavaScript</h2>
<p>Here's a simple hello-world kind of script that'll work to get us up and running: </p>
<pre><code>&lt;!DOCTYPE html&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>JavaScript App Example<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-comment">// JavaScript code</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greet</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">var</span> name = prompt(<span class="hljs-string">"What's your name?"</span>);
      alert(<span class="hljs-string">"Hello, "</span> + name + <span class="hljs-string">"!"</span>);
    }
  </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>JavaScript App Example<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"greet()"</span>&gt;</span>Say Hello<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span></span>
</code></pre><p>Let's work through that code one section at a time. </p>
<p>You can see that the JavaScript is all in between those two <code>&lt;script&gt;</code> tags and contains its own comment line. </p>
<pre><code>  &lt;script&gt;
    <span class="hljs-comment">// JavaScript code</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greet</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">var</span> name = prompt(<span class="hljs-string">"What's your name?"</span>);
      alert(<span class="hljs-string">"Hello, "</span> + name + <span class="hljs-string">"!"</span>);
    }
  &lt;/script&gt;
</code></pre><p>I really don't know why it has to be this way, but the comment escape codes for one language never seem to work for another. In the JavaScript world, you'll need two forward slashes: <code>//</code>.</p>
<p>The first line of real code introduces a new function that's named <code>greet</code>. </p>
<pre><code>    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greet</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">var</span> name = prompt(<span class="hljs-string">"What's your name?"</span>);
      alert(<span class="hljs-string">"Hello, "</span> + name + <span class="hljs-string">"!"</span>);
    }
</code></pre><p>The parentheses are necessary and, I assure you, you'll make good use of them later. The function's code must all lie between two curly braces the way you see here.</p>
<p>This function has just two lines. The first uses <code>var</code> to declare a variable that'll be called <code>name</code>. <code>name</code> will take the value entered by users when they're prompted with the "What's your name?" question. </p>
<p>NOTE: while declaring a variable as <code>var</code> still has its use cases, for most modern JavaScript development, <a target="_blank" href="https://www.freecodecamp.org/news/differences-between-var-let-const-javascript/">using <code>let</code> and <code>const</code> is considered a best practice</a> due to their improved scoping rules and stricter variable assignment behavior. I went with <code>var</code> here for simplicity</p>
<p>Once a value has been entered, <code>alert</code> will generate a pop-up window with the text <code>Hello</code> , a comma and space, the current value of the <code>name</code> variable, and an exclamation mark. The <code>+</code> character serves to concatenate all these values into a sentence.</p>
<p>But hang on: you can't see any name entry field on this page, can you? And how exactly is the function executed?</p>
<p>Excellent questions. That'll happen down in the HTML section. This is basically a <code>&lt;button&gt;</code> tag that has a text label of <code>Say Hello</code>. But it's the tag's attribute that really interests us.</p>
<p><code>onclick</code> calls our <code>greet</code> function. In other words, <code>onclick</code> tells the browser to execute the <code>greet</code> function whenever the button is clicked.</p>
<pre><code>&lt;body&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>JavaScript App Example<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"greet()"</span>&gt;</span>Say Hello<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
&lt;/body&gt;
&lt;/html&gt;
</code></pre><p>Paste the code into an <code>.html</code> file and load it in a browser. When you click the button a new dialog box opens with a data entry field looking for your name. When you type your name and then click <code>OK</code>, you'll see nicely concatenated sentence, all perfectly arranged.</p>
<h2 id="heading-how-to-work-with-javascript-in-a-browser-console">How to Work with JavaScript in a Browser Console</h2>
<p>But before moving on, I should remind you that JavaScript was built for browsers. So we can expect some useful integrations. Well, perhaps the most useful of them all is the console. </p>
<p>You can open the console by right-clicking on any empty spot on a browser page and selecting <code>Inspect</code>. This should work no matter what browser you're using. Hitting <code>F12</code> is another way to get to the same place. </p>
<p>In my Brave browser, the console appears on the right side:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/console1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Opening the console</em></p>
<p>This is known as the developer's console, because there are all kinds of helpful debugging and code analysis features packed in. </p>
<p>In the <code>Elements</code> tab, you'll see a representation of the page code. You can expand the <code>&lt;head&gt;</code> and the <code>&lt;script&gt;</code> sections so you can see what you're working with. Moving over to the <code>Console</code> tab, you find a live JavaScript environment.</p>
<p>In this example, I pasted three JavaScript operations into the console which we can actually test. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/webdev-s4-01-f011630.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here's that world-changing code in a cut-and-paste format:</p>
<pre><code><span class="hljs-built_in">console</span>.log(<span class="hljs-number">2</span> + <span class="hljs-number">2</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hello"</span> + <span class="hljs-string">" "</span> + <span class="hljs-string">"World"</span>);
<span class="hljs-keyword">var</span> fruits = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Orange"</span>];
<span class="hljs-built_in">console</span>.log(fruits.length);
</code></pre><p>Try it yourself.</p>
<p>Now, you should be aware that <code>console.log()</code> is a built-in JavaScript function that allows you to output messages or values to the console. It is commonly used for debugging and displaying information during the development process. So, as a rule, you'll only want to use the <code>console.log</code> function here.</p>
<p>This would be a great opportunity to introduce you to some JavaScript syntax. The function accepts one or more arguments within parentheses and prints them to the console. </p>
<p>The first execution is the sum of 2 + 2. </p>
<pre><code><span class="hljs-built_in">console</span>.log(<span class="hljs-number">2</span>+<span class="hljs-number">2</span>);
</code></pre><p>From here we can see that you can use any of the arithmetic operators (like plus, minus, the asterisk for multiplication, the forward slash for division, the right angle for greater than, the left angle for less then, and the equal sign) as-is within your JavaScript code. </p>
<p>The only other thing about this that might catch your attention is the semicolon that follows. In JavaScript, semicolons are statement terminators that help you avoid ambiguity and, sometimes, unexpected behavior. Use 'em early, use 'em often.</p>
<p>The second line contains another example of concatenation. </p>
<pre><code><span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hello"</span> + <span class="hljs-string">" "</span> + <span class="hljs-string">"World"</span>);
</code></pre><p>This one will print the word "Hello" followed by a space, and then the word "World".</p>
<p>Before running the next command, we'll declare a variable called <code>fruits</code>, which will contain an array of three words: "Apple", "Banana", and "Orange". </p>
<pre><code><span class="hljs-keyword">var</span> fruits = [<span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Banana"</span>, <span class="hljs-string">"Orange"</span>];
<span class="hljs-built_in">console</span>.log(fruits.length);
</code></pre><p>The code that follows will take the variable <code>fruits</code> and output its length.</p>
<p>When I hit <code>Enter</code> , all three commands will execute in one go. There are three lines of output: "4", "Hello World", and "3" – which is exactly what we would have expected. </p>
<p>That was nice and everything, but it hardly makes use of your browser's full resources. So now try running a command that'll generate an error. You could, say, add a couple of illegal characters to an operation like these asterisks:</p>
<pre><code><span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hello"</span> + <span class="hljs-string">" "</span> + <span class="hljs-string">"World"</span>)**;
</code></pre><p>Here's what happens:</p>
<pre><code>VM30:<span class="hljs-number">1</span> Uncaught <span class="hljs-built_in">SyntaxError</span>: Unexpected token <span class="hljs-string">';'</span>
</code></pre><p>You should see an uncaught syntax error. The <code>VM30:1</code> test even shows us which line of our code contained the problem - <code>1</code> in this case. If this were real code, we'd be a step closer to solving a bug.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>You're now properly introduced to the basics of JavaScript and, in particular, how to integrate JavaScript with your HTML and how to use your browser's console environment. Now go see what you can build!</p>
<p><em>This article comes from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-web-development-essentials-exam-study-guide/?referralCode=C92570BCBB38302A9257">my Complete LPI Web Development Essentials Study Guide course</a>.</em> <em>And there's much more technology goodness available at <a target="_blank" href="https://bootstrap-it.com/">bootstrap-it.com</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use CSS Selectors ]]>
                </title>
                <description>
                    <![CDATA[ You can apply CSS to elements like paragraphs and ordered lists, which you can learn more about by reading this article. But you're not just restricted to those two approaches.  As we'll see in this tutorial, you can also control content behavior usi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-css-selectors/</link>
                <guid isPermaLink="false">66b995f4c39234149cf010ff</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Thu, 06 Jul 2023 19:42:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/pexels-karolina-grabowska-4016510.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>You can apply CSS to elements like paragraphs and ordered lists, which you can learn more about by <a target="_blank" href="https://www.freecodecamp.org/news/css-style-sheets-basics/">reading this article</a>. But you're not just restricted to those two approaches. </p>
<p>As we'll see in this tutorial, you can also control content behavior using custom or <code>ID</code> styles, pseudo classes, and inheritance. This happens through the use of selectors.</p>
<p>CSS selectors target HTML elements based on their tag names, attributes, classes, IDs, or their position in the document structure. When a selector matches an element, the styles defined in the corresponding CSS rule are applied to that element.</p>
<p>Here's some code that'll illustrate how selectors can work to control various kinds of elements. Read through it and try to understand what everything does, then we'll work through it one section at a time.</p>
<pre><code>&lt;!DOCTYPE html&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
    <span class="hljs-comment">/* Target elements with a class */</span>
    <span class="hljs-selector-class">.highlight</span> {
      <span class="hljs-attribute">background-color</span>: yellow;
      <span class="hljs-attribute">font-weight</span>: bold;
    }

    <span class="hljs-comment">/* Target elements with an ID */</span>
    <span class="hljs-selector-id">#special</span> {
      <span class="hljs-attribute">color</span>: red;
      <span class="hljs-attribute">text-decoration</span>: underline;
    }

    <span class="hljs-comment">/* Target elements based on their tag name */</span>
    <span class="hljs-selector-tag">p</span> {
      <span class="hljs-attribute">font-size</span>: <span class="hljs-number">16px</span>;
    }

    <span class="hljs-comment">/* Target elements based on their relationship */</span>
    <span class="hljs-selector-tag">ul</span> <span class="hljs-selector-tag">li</span> {
      <span class="hljs-attribute">list-style-type</span>: square;
    }

    <span class="hljs-comment">/* Target elements based on attribute values */</span>
    <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=<span class="hljs-string">"text"</span>]</span> {
      <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid gray;
    }
  </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"special"</span>&gt;</span>Welcome to my Website<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This paragraph will have a font size of 16 pixels.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>List item 1<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>List item 2<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"highlight"</span>&gt;</span>List item 3<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter your name"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span></span>
</code></pre><p>This article comes from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-web-development-essentials-exam-study-guide/?referralCode=C92570BCBB38302A9257">my Complete LPI Web Development Essentials Study Guide course</a>. If you'd like, you can follow the video version here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/X_F5vK7XeiI" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-css-custom-and-id-styles">CSS Custom and ID Styles</h2>
<p>This first style is an example of a custom selector called <code>highlight</code>. </p>
<pre><code>    <span class="hljs-comment">/* Target elements with a class */</span>
    .highlight {
      background-color: yellow;
      font-weight: bold;
    }
</code></pre><p>That HTML might look like this:</p>
<pre><code>&lt;li <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"highlight"</span>&gt;List item <span class="hljs-number">3</span>&lt;/li&gt;
</code></pre><p>Next, this ID selector (<code>#special</code>):</p>
<pre><code>    <span class="hljs-comment">/* Target elements with an ID */</span>
    #special {
      <span class="hljs-attr">color</span>: red;
      text-decoration: underline;
    }
</code></pre><p>...will be applied in the HTML through the <code>id=</code> attribute:</p>
<pre><code>&lt;h1 id=<span class="hljs-string">"special"</span>&gt;Welcome to my Website&lt;/h1&gt;
</code></pre><p>We've already seen how associating a style with an HTML element like <code>p</code> works:</p>
<pre><code>    <span class="hljs-comment">/* Target elements based on their tag name */</span>
    p {
      font-size: <span class="hljs-number">16</span>px;
    }
</code></pre><p>...But the <em>shape</em> of the background coloring applied to <code>&lt;ul&gt;</code> tags and the border color of the text input field are controlled by these two styles:</p>
<pre><code>    <span class="hljs-comment">/* Target elements based on their relationship */</span>
    ul li {
      list-style-type: square;
    }

    <span class="hljs-comment">/* Target elements based on attribute values */</span>
    input[type=<span class="hljs-string">"text"</span>] {
      <span class="hljs-attr">border</span>: <span class="hljs-number">1</span>px solid gray;
    }
</code></pre><p>Now, in addition to the HTML snippets we've already examined, we can also see how the third bullet point has the <code>highlight</code> class attribute, so it'll get both a yellow background and that background will be square. Finally, the <code>&lt;input type="text"&gt;</code> field will get a gray border.</p>
<pre><code>&lt;body&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"special"</span>&gt;</span>Welcome to my Website<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>

  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This paragraph will have a font size of 16 pixels.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>

  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>List item 1<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>List item 2<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"highlight"</span>&gt;</span>List item 3<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span>

  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter your name"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span></span>
</code></pre><p>If save all that code to a <code>.html</code> file and load it in your favorite browser, you'll see that it all looks exactly the way we wanted it. Hopefully, at least.</p>
<h2 id="heading-how-to-work-with-the-css-pseudo-class">How to Work with the CSS <code>pseudo class</code></h2>
<p>There's another kind of class in CSS we call a <code>pseudo class</code>. They're called "pseudo" since these aren't exactly traditional classes, but <em>class controls</em>. </p>
<p>You've probably already seen pseudo classes in action on web pages you've visited. Links or page elements will change their appearances when different actions are occurring around them.</p>
<p>For instance, as you can see from this CSS code, there are definitions for <em>normal</em>, <em>hover</em>, <em>focus</em>, and <em>active</em> states.</p>
<pre><code><span class="hljs-comment">/* Normal state */</span>
button {
  background-color: blue;
  color: white;
}

<span class="hljs-comment">/* Hover state */</span>
<span class="hljs-attr">button</span>:hover {
  background-color: lightblue;
}

<span class="hljs-comment">/* Focus state */</span>
<span class="hljs-attr">button</span>:focus {
  <span class="hljs-attr">outline</span>: <span class="hljs-number">2</span>px solid red;
}

<span class="hljs-comment">/* Active state */</span>
<span class="hljs-attr">button</span>:active {
  background-color: darkgreen;
}
</code></pre><p>You should take those CSS styles and apply them to some simple HTML code. This example shows how they could all be applied to the <code>Click me</code> button text in the HTML.</p>
<pre><code>&lt;button&gt;Click me&lt;/button&gt;
</code></pre><p>Let's see how that'll work.</p>
<p>The normal, at-rest appearance of a button might have a blue background color and white text. But when you hover your mouse over top of the button, the background turns light blue. </p>
<pre><code><span class="hljs-comment">/* Hover state */</span>
<span class="hljs-attr">button</span>:hover {
  background-color: lightblue;
}
</code></pre><p>If you would use the <code>Tab</code> key on your keyboard to cycle through all the page elements, once you reach the button, the state will become <code>Focus</code> and the outline will turn red. </p>
<pre><code><span class="hljs-comment">/* Focus state */</span>
<span class="hljs-attr">button</span>:focus {
  <span class="hljs-attr">outline</span>: <span class="hljs-number">2</span>px solid red;
}
</code></pre><p>When I would actually click and hold the button, the background will change to dark green.</p>
<pre><code><span class="hljs-comment">/* Active state */</span>
<span class="hljs-attr">button</span>:active {
  background-color: darkgreen;
}
</code></pre><h2 id="heading-css-inheritance">CSS Inheritance</h2>
<p>CSS inheritance is a mechanism that allows properties defined on parent elements to be inherited by their child elements. When a property is set on a parent element, its value is automatically inherited by its descendants unless overridden.</p>
<p>Inheritance applies to various CSS properties, such as font styles, text colors, and some layout properties. For example, if you set the font family or font size on a parent element, the child elements within it will inherit those values unless explicitly specified otherwise.</p>
<p>In some cases, certain properties are <em>not</em> inherited by default. For instance, properties like background color, border properties, and box-model properties are typically not inherited. In these cases, child elements will not inherit the values from their parent elements unless explicitly set.</p>
<p>CSS inheritance simplifies the styling process by allowing you to set properties once on parent elements, reducing the need for repetitive styling on child elements. However, it's essential to be aware of which properties are inherited and which ones are not to ensure the desired styling outcome.</p>
<p>This code creates a <code>#parent</code> style that sets the font and font color. It also creates a second style that'll apply to paragraphs within the HTML. But this second style is also a <code>child</code> of the <code>parent</code>.</p>
<pre><code>&lt;style type=<span class="hljs-string">"text/css"</span>&gt;
#parent {
  font-family: Arial, sans-serif;
  color: blue;
}
p {
  font-size: <span class="hljs-number">24</span>px;
}
&lt;/style&gt;
</code></pre><p>The HTML exists within a <code>&lt;div&gt;</code> that uses the <code>id=</code> attribute to adopt the <code>parent</code> style. There are two lines of text, one inside the <code>&lt;p&gt;</code> tag and one outside.</p>
<pre><code>&lt;div id=<span class="hljs-string">"parent"</span>&gt;
  Here is some regular text.
  &lt;p&gt;This is a paragraph inside the parent element.&lt;/p&gt;
&lt;/div&gt;
</code></pre><p>When we load our code in a browser we'll see that both those lines of text will be printed in blue - which means that the <code>child</code> element has, indeed, adopted the parents values. But it'll also get its own larger font formatting. This kind of formatting can be powerful when you want to very precisely control overall, global behavior, while maintaining the ability to further define individual elements.</p>
<p>To <em>prevent</em> inheritance and establish a completely new value, the <code>inherit</code> keyword can be used to override the inherited value. Additionally, the initial keyword can be used to reset a property to its default value.</p>
<p>One more important point that's particularly relevant when you're working with multiple CSS styles. What happens when, between your inline CSS, multiple stand alone CSS files, and layers of parents and children, there's a conflict between styles? Well there's a set of rules that determine how everything will be handled.</p>
<p>Inline code within an HTML file's <code>&lt;style&gt;</code> tags always comes first. The more specific a selector is, the greater its priority. The further down in the code a style appears the greater priority it's given. And the <code>!important</code> attribute will always win.</p>
<h3 id="heading-rule-precedence-in-css">Rule Precedence in CSS</h3>
<p>Here's a quick summary of rule precedence in CSS:</p>
<ul>
<li>Inline CSS overrides CSS rules in style tag and CSS file</li>
<li>A more specific selector takes precedence over a less specific one</li>
<li>Rules that appear later in the code override earlier rules if both have the same specificity</li>
<li>A CSS rule with <code>!important</code> always takes precedence.</li>
</ul>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>You've seen how customizing your CSS styles through attributes like <code>id</code> and applying structures like pseudo classes can go a long way to liven up your HTML pages. And you've seen how all of that works through CSS selectors. </p>
<p>You also saw how CSS inheritance can help you closely control the way objects on your web pages behave.</p>
<p>So you're all set to start building some pretty sophisticated websites. Why not start today?</p>
<p><em>This article comes from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-web-development-essentials-exam-study-guide/?referralCode=C92570BCBB38302A9257">my Complete LPI Web Development Essentials Study Guide course</a>.</em> <em>And there's much more technology goodness available at <a target="_blank" href="https://bootstrap-it.com/">bootstrap-it.com</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
