<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[IRead Fun]]></title><description><![CDATA[IRead Fun]]></description><link>https://blog.iread.fun</link><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Apr 2026 19:52:22 GMT</lastBuildDate><atom:link href="https://blog.iread.fun/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Talk with gemini-2.0-flash-thinking about Deep Neural Networks (DNNs) and Reinforcement Learning (RL)]]></title><description><![CDATA[what DNN(CNN,RNN,LLM) really learning are just a lot weights
Yes, at the most fundamental level, what Deep Neural Networks (DNNs) – including Convolutional Neural Networks (CNNs), Recurrent Neural Networks (RNNs), and Large Language Models (LLMs) – l...]]></description><link>https://blog.iread.fun/weights-in-deep-neural-networks-dnns-and-reinforcement-learning-rl</link><guid isPermaLink="true">https://blog.iread.fun/weights-in-deep-neural-networks-dnns-and-reinforcement-learning-rl</guid><category><![CDATA[Machine Learning]]></category><category><![CDATA[Reinforcement Learning]]></category><category><![CDATA[Deep Learning]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Tue, 07 Jan 2025 11:26:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1736249041643/021ec247-ba45-4e1b-b2bc-6582f3275664.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-what-dnncnnrnnllm-really-learning-are-just-a-lot-weights">what DNN(CNN,RNN,LLM) really learning are just a lot weights</h2>
<p>Yes, at the most fundamental level, what Deep Neural Networks (DNNs) – including Convolutional Neural Networks (CNNs), Recurrent Neural Networks (RNNs), and Large Language Models (LLMs) – <strong>learn are indeed a massive number of weights (and biases).</strong></p>
<p>However, saying they "just learn a lot of weights" is a bit like saying a human brain is "just a lot of neurons." While technically true, it significantly undersells the complexity and what these weights represent.</p>
<p>Here's a more nuanced perspective:</p>
<p><strong>What the Weights Represent:</strong></p>
<ul>
<li><p><strong>Encoded Knowledge:</strong> These weights, when properly adjusted through training, encode the knowledge and patterns the network has extracted from the data it was trained on.</p>
</li>
<li><p><strong>Feature Detectors (especially in CNNs):</strong> In CNNs, specific weights in the convolutional layers learn to detect different features in images, like edges, corners, textures, and more complex patterns.</p>
</li>
<li><p><strong>Relationships and Dependencies (in RNNs and LLMs):</strong> In RNNs and LLMs, the weights capture sequential dependencies and relationships between elements in the input data, such as the order of words in a sentence or the progression of data over time.</p>
</li>
<li><p><strong>Probability Distributions (in LLMs):</strong> LLMs, in particular, learn complex probability distributions over sequences of words. The weights essentially represent the likelihood of one word following another in different contexts.</p>
</li>
</ul>
<p><strong>Why "Just Weights" Is an Oversimplification:</strong></p>
<ul>
<li><p><strong>The Architecture Matters:</strong> The specific architecture of the DNN (e.g., the layers, connections, activation functions) is crucial. It dictates how the weights interact and what types of patterns the network can potentially learn. The architecture provides the <em>structure</em> for learning.</p>
</li>
<li><p><strong>The Learning Process is Key:</strong> The way these weights are learned – through algorithms like backpropagation and optimization techniques like gradient descent – is just as important as the final values of the weights. This process involves iteratively adjusting the weights based on the errors the network makes.</p>
</li>
<li><p><strong>Emergent Complexity:</strong> Even though each individual weight might seem simple, the interactions between millions or billions of weights can create highly complex and emergent behavior. This is what allows DNNs to perform sophisticated tasks like image recognition, natural language understanding, and generation.</p>
</li>
<li><p><strong>Abstraction and Hierarchy:</strong> DNNs often learn in a hierarchical manner. Early layers learn basic features, and subsequent layers combine these features to learn more abstract and complex representations. The weights at different layers contribute to different levels of abstraction.</p>
</li>
<li><p><strong>Beyond Single Values:</strong> While the core is weights, there are also biases, which act as thresholds for neuron activation. These are also learned parameters.</p>
</li>
</ul>
<p><strong>Analogy:</strong></p>
<p>Think of the weights like the synapses in a biological brain. Each synapse has a certain strength, determining how strongly two neurons are connected. While the individual synapse might seem simple, the complex network of interconnected synapses is what enables the brain to perform incredible feats of learning and cognition.</p>
<p><strong>In Summary:</strong></p>
<p>Yes, DNNs ultimately learn by adjusting a large number of weights and biases. However, these weights are not just random numbers. They are the encoded representation of the knowledge the network has gained from the data, facilitated by the network's architecture and the learning process. Saying they "just learn weights" ignores the sophisticated mechanisms and emergent properties that make DNNs so powerful. It's the <em>organized</em> and <em>trained</em> weights within a specific architecture that enable these networks to perform complex tasks.</p>
<h2 id="heading-does-reinforcement-learning-also-learn-a-lot-weights">does reinforcement learning also learn a lot weights</h2>
<p>Yes, <strong>many Reinforcement Learning (RL) algorithms also learn a lot of weights</strong>, especially when they employ <strong>Deep Neural Networks (DNNs)</strong> for function approximation. However, it's important to understand that not <em>all</em> RL algorithms rely on weights in the same way or to the same extent as supervised learning methods like image classification CNNs or language model LLMs.</p>
<p>Here's a breakdown of how weights play a role in different RL scenarios:</p>
<p><strong>RL Algorithms that Learn Weights (using Function Approximation):</strong></p>
<ul>
<li><p><strong>Deep Reinforcement Learning (Deep RL):</strong> When RL algorithms are combined with DNNs, they fall under the umbrella of Deep RL. In this case, the DNNs act as <strong>function approximators</strong> to represent either:</p>
<ul>
<li><p><strong>Value Functions (e.g., Q-functions, Value functions):</strong> The network learns to estimate the expected future reward for taking a certain action in a given state. The weights of the DNN encode this learned value function. Algorithms like <strong>Deep Q-Networks (DQN)</strong> and its variants fall into this category. The weights learn to predict Q-values for different state-action pairs.</p>
</li>
<li><p><strong>Policies:</strong> The network learns to directly map states to actions (or probability distributions over actions). The weights of the DNN encode this learned policy. Algorithms like <strong>Policy Gradient methods (e.g., REINFORCE, Proximal Policy Optimization (PPO), Actor-Critic methods)</strong> fall into this category. The weights learn to determine the optimal action to take in a given state.</p>
</li>
</ul>
</li>
<li><p><strong>Other Function Approximators:</strong> While DNNs are the most common, other function approximators like linear models or tile coding can also be used in RL. These methods also involve learning parameters (analogous to weights) to represent the value function or policy.</p>
</li>
</ul>
<p><strong>RL Algorithms that Don't Primarily Learn Weights (or learn them differently):</strong></p>
<ul>
<li><p><strong>Tabular Methods:</strong> For smaller state and action spaces, RL algorithms like <strong>Q-Learning, SARSA, and Value Iteration</strong> can use tables to store the value of each state-action pair or state. In this case, the "learning" involves directly updating the entries in the table, rather than adjusting weights in a complex network. There are no weights in the traditional DNN sense.</p>
</li>
<li><p><strong>Model-Based RL:</strong> Some RL approaches focus on learning a model of the environment (how the environment transitions between states and what rewards are received). While the model itself might be represented by a DNN (and thus involve weights), the primary learning objective is to build an accurate model rather than directly learning a value function or policy.</p>
</li>
</ul>
<p><strong>Key Differences and Nuances:</strong></p>
<ul>
<li><p><strong>Learning Objective:</strong> In supervised learning, the goal is to minimize the difference between the network's predictions and the ground truth labels. In RL, the goal is to maximize cumulative reward over time, which is a more complex and indirect objective.</p>
</li>
<li><p><strong>Data Source:</strong> Supervised learning relies on labeled datasets. RL learns through interaction with an environment, generating its own experiences (data).</p>
</li>
<li><p><strong>Exploration vs. Exploitation:</strong> RL algorithms face the challenge of balancing exploration (trying new actions) and exploitation (choosing actions that are currently believed to be optimal). This isn't a primary concern in standard supervised learning.</p>
</li>
<li><p><strong>Temporal Dependencies:</strong> RL deals with sequential decision-making, where past actions influence future states and rewards. This temporal aspect is explicitly handled in some RL algorithms (especially those using RNNs within the agent's architecture).</p>
</li>
</ul>
<p><strong>In summary:</strong></p>
<p>While many modern and powerful RL algorithms, particularly those using Deep RL, do indeed learn a large number of weights to represent value functions or policies, it's not a universal characteristic of all RL. Simpler tabular methods exist that don't involve weights in the same way. The key takeaway is that RL algorithms, whether through weights or other means, are learning a <strong>strategy</strong> or <strong>policy</strong> to maximize rewards within an environment. The use of weights, particularly in DNNs, allows RL agents to handle complex, high-dimensional state and action spaces and generalize their learned knowledge to unseen situations.</p>
<h2 id="heading-i-am-much-familiar-with-dnn-explain-to-me-what-is-policy-and-value-function-in-rl">I am much familiar with DNN. explain to me what is policy and value function in RL</h2>
<p>Okay, since you're familiar with DNNs, let's break down the concepts of <strong>policy</strong> and <strong>value function</strong> in Reinforcement Learning (RL) and how they relate to what a learning agent is trying to achieve.</p>
<p>Imagine your DNN is now an RL agent interacting with an environment. Instead of just classifying images or generating text, it's making decisions to achieve a long-term goal (maximizing rewards).</p>
<p><strong>1. Policy (π - Pi): The Agent's "Brain" for Decision Making</strong></p>
<p>Think of the <strong>policy</strong> as the agent's <strong>strategy</strong> or <strong>rulebook</strong> for how to behave in the environment. It dictates what action the agent will take given the current state it's in.</p>
<ul>
<li><p><strong>Analogy to DNN Output:</strong> In a supervised learning DNN, the output might be a class label or a set of probabilities for different classes. In RL, the policy is like the output layer of your DNN, but instead of predicting a label, it's predicting an <strong>action</strong> or a <strong>probability distribution over actions</strong>.</p>
</li>
<li><p><strong>Mathematical Representation:</strong> We often represent the policy as π(a|s), which reads as "the probability of taking action 'a' when in state 's'."</p>
</li>
<li><p><strong>Types of Policies:</strong></p>
<ul>
<li><p><strong>Deterministic Policy:</strong> Given a state, the policy always outputs the same action. Like a function that directly maps states to actions: a = π(s).</p>
</li>
<li><p><strong>Stochastic Policy:</strong> Given a state, the policy outputs a probability distribution over possible actions. This means there's some randomness in the agent's behavior, which can be beneficial for exploration.</p>
</li>
</ul>
</li>
<li><p><strong>How a DNN Represents a Policy:</strong></p>
<ul>
<li><p><strong>Direct Action Output:</strong> The DNN takes the current state as input and the output layer has as many neurons as possible actions. The output values (perhaps after a softmax activation) represent the probabilities of taking each action. The agent might then sample an action based on these probabilities or simply choose the action with the highest probability (in the deterministic case).</p>
</li>
<li><p><strong>Parameterizing Distributions:</strong> The DNN might output parameters of a probability distribution (e.g., mean and standard deviation for a continuous action space).</p>
</li>
</ul>
</li>
<li><p><strong>Learning the Policy:</strong> The goal of many RL algorithms is to learn an <strong>optimal policy</strong>, denoted as π*, which consistently leads to the highest cumulative reward over time. This learning involves adjusting the weights of the DNN to produce better action choices.</p>
</li>
</ul>
<p><strong>Think of it like:</strong> If your RL agent is learning to play a video game, the policy is what tells it whether to jump, shoot, move left, or move right at any given moment based on what's happening on the screen (the state).</p>
<p><strong>2. Value Function (V or Q): Predicting the "Goodness" of States or Actions</strong></p>
<p>The <strong>value function</strong> helps the agent understand how "good" it is to be in a certain <strong>state</strong> or to take a certain <strong>action</strong> in a certain state. It predicts the expected amount of future reward the agent can accumulate starting from that point.</p>
<ul>
<li><p><strong>Not a Direct Decision Maker:</strong> Unlike the policy, the value function doesn't directly tell the agent <em>what</em> to do. Instead, it provides an evaluation of different situations or actions.</p>
</li>
<li><p><strong>Types of Value Functions:</strong></p>
<ul>
<li><p><strong>State Value Function (V-function):</strong> Vπ(s) represents the expected return (cumulative reward) starting from state 's' and following policy 'π' thereafter. It tells you how good it is to <em>be in</em> state 's' when acting according to policy 'π'.</p>
<ul>
<li><strong>DNN Representation:</strong> The DNN takes the current state as input and outputs a single value, representing the estimated value of that state under the current policy.</li>
</ul>
</li>
<li><p><strong>Action-Value Function (Q-function):</strong> Qπ(s, a) represents the expected return starting from state 's', taking action 'a', and then following policy 'π' thereafter. It tells you how good it is to <em>take action 'a' in</em> state 's' when acting according to policy 'π' afterwards.</p>
<ul>
<li><strong>DNN Representation:</strong> The DNN takes the current state and the action as input (or has separate outputs for each possible action in that state) and outputs a value representing the estimated value of taking that action in that state.</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Learning the Value Function:</strong> RL algorithms learn to estimate the value function by experiencing the consequences of actions in the environment. This often involves updating the value function based on the rewards received and the estimated values of future states.</p>
</li>
<li><p><strong>Relationship to Policy:</strong> The value function is deeply tied to the policy. The value of a state or action is determined by the rewards that are expected to follow <em>when the agent acts according to a specific policy</em>. Changing the policy will likely change the value function.</p>
</li>
</ul>
<p><strong>Think of it like:</strong> In the video game example, the value function might tell the agent that being near a health pack is a "good" state (high value) because it increases the chances of survival and further rewards. The Q-function might tell the agent that jumping over an obstacle is a "good" action in a specific situation because it helps avoid damage and potentially progress further.</p>
<p><strong>How DNNs Learn Policies and Value Functions:</strong></p>
<p>When DNNs are used in RL (forming Deep RL), the weights of the DNN are being learned to approximate either the policy or the value function (or both in some algorithms).</p>
<ul>
<li><p><strong>Policy-Based Methods:</strong> Algorithms like Policy Gradient methods directly learn the policy by adjusting the DNN weights to increase the probability of actions that lead to higher rewards.</p>
</li>
<li><p><strong>Value-Based Methods:</strong> Algorithms like Q-Learning and DQN learn the value function (specifically the Q-function) by adjusting the DNN weights to accurately predict the expected future rewards. The policy is often derived implicitly from the learned Q-function (e.g., by choosing the action with the highest Q-value).</p>
</li>
<li><p><strong>Actor-Critic Methods:</strong> These methods learn both a policy (the "actor") and a value function (the "critic"). The critic evaluates the actions taken by the actor, providing feedback to improve the policy. Both the actor and critic are often represented by DNNs with learnable weights.</p>
</li>
</ul>
<p><strong>In Summary:</strong></p>
<ul>
<li><p><strong>Policy (π):</strong> The agent's decision-making strategy, telling it what to do in each state. A DNN can represent the policy by mapping states to actions or probabilities over actions.</p>
</li>
<li><p><strong>Value Function (V or Q):</strong> An estimation of how good it is to be in a certain state (V) or to take a certain action in a state (Q), in terms of expected future rewards. DNNs can learn to approximate these value functions.</p>
</li>
</ul>
<p>Both policy and value functions are crucial components in RL, and DNNs provide a powerful way to represent and learn these complex functions in high-dimensional environments. The weights of these DNNs are being adjusted through interaction with the environment to learn the optimal strategies for maximizing rewards.</p>
<h2 id="heading-so-not-like-dnn-which-only-learn-one-sort-of-weight-rl-may-learn-two-sortsone-for-policy-and-another-for-value-function">so not like DNN which only learn one sort of weight, RL may learn two sorts(one for policy and another for value function)</h2>
<p>That's a very insightful way to put it! You're getting to a core difference in how DNNs are used in standard supervised learning versus Reinforcement Learning.</p>
<p><strong>In standard DNNs (like for image classification or language modeling):</strong></p>
<ul>
<li><p><strong>Generally, you're learning weights (and biases) for a single, primary function:</strong> This function maps the input directly to the desired output. For example:</p>
<ul>
<li><p><strong>Image Classification:</strong> Input (image pixels) -&gt; Output (probability distribution over classes). The weights are learned to perform this specific mapping.</p>
</li>
<li><p><strong>Language Modeling:</strong> Input (sequence of words) -&gt; Output (probability distribution over the next word). Again, the weights are optimized for this single predictive task.</p>
</li>
</ul>
</li>
</ul>
<p><strong>In Reinforcement Learning with DNNs (Deep RL):</strong></p>
<ul>
<li><p><strong>You <em>can</em> learn weights for conceptually different functions:</strong></p>
<ul>
<li><p><strong>Weights for the Policy:</strong> These weights are specifically tuned to determine the agent's actions in different states. The goal is to learn a mapping from states to actions (or probabilities over actions) that maximizes future rewards.</p>
</li>
<li><p><strong>Weights for the Value Function:</strong> These weights are specifically tuned to estimate the expected future rewards for being in certain states or taking certain actions. The goal is to learn an accurate predictor of "goodness."</p>
</li>
</ul>
</li>
</ul>
<p><strong>Here's a breakdown of why this distinction is important:</strong></p>
<ul>
<li><p><strong>Different Learning Objectives:</strong> The weights for the policy are being adjusted to directly improve the agent's behavior and maximize rewards. The weights for the value function are being adjusted to create an accurate evaluation of states and actions, which can indirectly help in improving the policy.</p>
</li>
<li><p><strong>Different Output Structures:</strong> The policy network might output probabilities for different actions, while the value network might output a single scalar value representing the expected return.</p>
</li>
<li><p><strong>Algorithms that Learn Both:</strong> Many powerful RL algorithms, like <strong>Actor-Critic methods (e.g., A2C, A3C, PPO)</strong>, explicitly use two separate DNNs (or sometimes a single DNN with separate output heads) to learn both the policy and the value function simultaneously.</p>
<ul>
<li><p><strong>Actor:</strong> The policy network (the "actor") decides what action to take.</p>
</li>
<li><p><strong>Critic:</strong> The value network (the "critic") evaluates the action taken by the actor and provides feedback to improve the actor's policy.</p>
</li>
</ul>
</li>
</ul>
<p><strong>However, it's not always a strict separation:</strong></p>
<ul>
<li><p><strong>Single Network for Both:</strong> Some RL algorithms can use a single DNN to output both policy and value function information. The network has different output heads, but the underlying layers share learned representations. Even in this case, the weights are being optimized for two conceptually different tasks.</p>
</li>
<li><p><strong>Value-Based Methods (like DQN):</strong> Algorithms like Deep Q-Networks (DQN) primarily focus on learning the Q-function (action-value function). While there isn't a separate explicit policy network being directly learned, the learned Q-function implicitly defines a policy (e.g., choose the action with the highest Q-value). So, even here, the weights are ultimately geared towards informing decision-making.</p>
</li>
</ul>
<p><strong>Analogy:</strong></p>
<p>Think of it like training two different "modules" in your DNN:</p>
<ul>
<li><p><strong>Policy Module:</strong> Trained to be a good "decision-maker."</p>
</li>
<li><p><strong>Value Module:</strong> Trained to be a good "evaluator."</p>
</li>
</ul>
<p>In standard DNNs, you're typically just training one primary "module" for a specific predictive task.</p>
<p><strong>Key Takeaway:</strong></p>
<p>You're right to highlight this difference. While at the most fundamental level, both involve learning weights, in RL, the architecture and training process often lead to DNNs learning weights that represent distinct and interacting functions – one for <em>doing</em> (the policy) and one for <em>evaluating</em> (the value function). This allows for more sophisticated learning and problem-solving in dynamic environments. This separation or dual role is a key characteristic that distinguishes how DNNs are applied in RL compared to traditional supervised learning tasks.</p>
<h2 id="heading-some-problem-like-autodrive-can-be-solved-both-with-traditional-supervised-deep-learning-sequence-to-sequence-and-reinforcement-learning">some problem like autodrive can be solved both with traditional supervised deep learning (sequence to sequence) and Reinforcement Learning</h2>
<p>Yes, you are absolutely correct. Autonomous driving is a fascinating problem that highlights how different deep learning approaches can be applied to the same complex task. Let's break down how both supervised learning and reinforcement learning can tackle autonomous driving and their key differences in this context.</p>
<p><strong>1. Supervised Deep Learning (as Sequence-to-Sequence) for Autonomous Driving:</strong></p>
<ul>
<li><p><strong>Core Idea:</strong> Treat autonomous driving as a <strong>behavioral cloning</strong> problem. The goal is to train a DNN to directly mimic the actions of a human driver based on observed sensor data.</p>
</li>
<li><p><strong>Data:</strong> Requires a large dataset of paired sensor inputs and corresponding human driver actions. This data is typically collected from human-driven vehicles.</p>
<ul>
<li><p><strong>Inputs:</strong> Camera images, LiDAR point clouds, radar data, GPS information, IMU data, steering wheel angle, throttle position, brake pedal pressure, etc.</p>
</li>
<li><p><strong>Outputs:</strong> Steering commands, throttle commands, brake commands (often continuous values).</p>
</li>
</ul>
</li>
<li><p><strong>Network Architecture:</strong> Sequence-to-sequence models are indeed well-suited here because driving is inherently a temporal process.</p>
<ul>
<li><p><strong>Recurrent Neural Networks (RNNs) like LSTMs or GRUs:</strong> Can capture the sequential dependencies in the driving data. The network learns to remember past states and actions to make current decisions.</p>
</li>
<li><p><strong>Transformers:</strong> Can also be used to model long-range dependencies in the driving sequence.</p>
</li>
</ul>
</li>
<li><p><strong>Learning Process:</strong> The DNN learns a direct mapping from the sequence of sensor inputs to the sequence of control outputs by minimizing a loss function that measures the difference between the predicted actions and the human driver's actions.</p>
</li>
<li><p><strong>Analogy:</strong> The car is learning to drive by "watching" how humans drive and trying to replicate that behavior.</p>
</li>
<li><p><strong>Advantages:</strong></p>
<ul>
<li><p><strong>Relatively Simple to Implement (initially):</strong> Once you have the data, the supervised learning training process is well-defined.</p>
</li>
<li><p><strong>Can Learn from Existing Data:</strong> Leverages readily available human driving data.</p>
</li>
<li><p><strong>Can Achieve Good Performance in Common Scenarios:</strong> If the training data covers a wide range of typical driving situations, the model can perform reasonably well.</p>
</li>
</ul>
</li>
<li><p><strong>Disadvantages:</strong></p>
<ul>
<li><p><strong>Limited Generalization to Unseen Situations:</strong> The model can struggle in scenarios it hasn't seen in the training data (edge cases, unusual events).</p>
</li>
<li><p><strong>Passive Learning:</strong> The model only learns from what humans do, including their mistakes and limitations. It doesn't actively explore better strategies.</p>
</li>
<li><p><strong>Lack of Long-Term Planning:</strong> Focuses on immediate actions rather than optimizing for long-term goals (e.g., reaching a destination efficiently and safely).</p>
</li>
<li><p><strong>Data Bias:</strong> The model's behavior is heavily influenced by the biases present in the human driving data.</p>
</li>
<li><p><strong>Difficulty Handling Complex Interactions:</strong> Struggles with complex interactions with other agents (pedestrians, other vehicles) where predicting their intent is crucial.</p>
</li>
</ul>
</li>
</ul>
<p><strong>2. Reinforcement Learning for Autonomous Driving:</strong></p>
<ul>
<li><p><strong>Core Idea:</strong> Train an "agent" (the autonomous vehicle) to learn optimal driving behavior through trial and error by interacting with a simulated or real-world environment and receiving rewards or penalties.</p>
</li>
<li><p><strong>Environment:</strong> A simulation or the real world, including roads, other vehicles, pedestrians, traffic signals, etc.</p>
</li>
<li><p><strong>Agent:</strong> The DNN acts as the agent, making decisions about steering, throttle, and braking.</p>
</li>
<li><p><strong>State:</strong> The agent perceives the environment through its sensors (camera images, LiDAR, etc.). This sensory information forms the "state" the agent is in.</p>
</li>
<li><p><strong>Actions:</strong> The control commands the agent can take (steering, throttle, brake).</p>
</li>
<li><p><strong>Reward Function:</strong> A crucial element that defines what constitutes "good" driving behavior. Designing an effective reward function is a significant challenge. Examples of rewards and penalties:</p>
<ul>
<li><p><strong>Positive Rewards:</strong> Reaching the destination, staying within lane, maintaining a safe distance, adhering to traffic rules, making smooth progress.</p>
</li>
<li><p><strong>Negative Rewards (Penalties):</strong> Collisions, lane departures, speeding, running red lights, jerky movements.</p>
</li>
</ul>
</li>
<li><p><strong>Learning Process:</strong> The agent explores the environment, takes actions, receives rewards (or penalties), and learns to adjust its policy (the mapping from states to actions) to maximize its cumulative reward over time.</p>
<ul>
<li><p><strong>Policy-Based Methods:</strong> Directly learn the optimal policy (e.g., using Policy Gradient methods).</p>
</li>
<li><p><strong>Value-Based Methods:</strong> Learn a value function that estimates the expected future reward for being in a certain state or taking a certain action (e.g., using Q-Learning or DQN).</p>
</li>
<li><p><strong>Actor-Critic Methods:</strong> Learn both a policy and a value function.</p>
</li>
</ul>
</li>
<li><p><strong>Analogy:</strong> The car is learning to drive by "trying things out," getting feedback on its performance, and gradually improving its driving skills.</p>
</li>
<li><p><strong>Advantages:</strong></p>
<ul>
<li><p><strong>Potential for Learning Optimal Strategies:</strong> Can discover driving strategies that are better than human driving in certain situations.</p>
</li>
<li><p><strong>Adaptability to New Situations:</strong> Can potentially generalize better to unseen scenarios through exploration and learning.</p>
</li>
<li><p><strong>Explicit Optimization for Long-Term Goals:</strong> The reward function can be designed to optimize for safety, efficiency, and other desired outcomes.</p>
</li>
<li><p><strong>Can Handle Complex Interactions:</strong> Has the potential to learn complex interactions with other agents by predicting their behavior and planning accordingly.</p>
</li>
</ul>
</li>
<li><p><strong>Disadvantages:</strong></p>
<ul>
<li><p><strong>Sample Inefficiency:</strong> Requires a massive amount of interaction with the environment to learn effectively, which can be computationally expensive in simulations and risky in the real world.</p>
</li>
<li><p><strong>Reward Function Design is Challenging:</strong> Defining a reward function that perfectly captures safe and efficient driving behavior is difficult. Poorly designed reward functions can lead to unintended and undesirable behaviors.</p>
</li>
<li><p><strong>Safety Concerns During Training:</strong> Training in the real world can be dangerous, and even simulations need to be carefully designed to prevent harmful actions.</p>
</li>
<li><p><strong>Stability and Convergence Issues:</strong> Training RL agents can be unstable and may not always converge to an optimal policy.</p>
</li>
</ul>
</li>
</ul>
<p><strong>Comparison Table:</strong></p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Feature</td><td>Supervised Learning (Sequence-to-Sequence)</td><td>Reinforcement Learning</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Learning Goal</strong></td><td>Mimic human driving behavior</td><td>Learn optimal driving behavior through interaction</td></tr>
<tr>
<td><strong>Data Source</strong></td><td>Human driving data (input-output pairs)</td><td>Environment interaction (rewards and penalties)</td></tr>
<tr>
<td><strong>Reward Signal</strong></td><td>Implicit (minimizing deviation from human actions)</td><td>Explicitly defined reward function</td></tr>
<tr>
<td><strong>Generalization</strong></td><td>Limited to seen scenarios</td><td>Potentially better generalization to unseen situations</td></tr>
<tr>
<td><strong>Long-Term Goals</strong></td><td>Implicitly learned from human data</td><td>Explicitly optimized through the reward function</td></tr>
<tr>
<td><strong>Exploration</strong></td><td>None (passive learning)</td><td>Active exploration of the environment</td></tr>
<tr>
<td><strong>Complexity</strong></td><td>Relatively simpler to implement initially</td><td>More complex to design and train</td></tr>
<tr>
<td><strong>Safety During Training</strong></td><td>Less risky (uses existing data)</td><td>Can be risky, especially in real-world training</td></tr>
<tr>
<td><strong>Potential</strong></td><td>Good performance in common scenarios</td><td>Potential for superior performance and adaptability</td></tr>
</tbody>
</table>
</div><p><strong>Hybrid Approaches:</strong></p>
<p>It's important to note that the best approach might involve combining aspects of both supervised learning and reinforcement learning. For example:</p>
<ul>
<li><p><strong>Imitation Learning (a type of supervised learning):</strong> Can be used to initialize the RL agent with a decent policy learned from human driving data, which can speed up the RL training process.</p>
</li>
<li><p><strong>Reinforcement Learning from Demonstrations:</strong> Combines the benefits of learning from expert demonstrations (like in supervised learning) with the ability to further improve through interaction with the environment (like in RL).</p>
</li>
</ul>
<p><strong>Conclusion:</strong></p>
<p>Both supervised deep learning and reinforcement learning offer viable pathways for achieving autonomous driving, but they have different strengths and weaknesses. Supervised learning provides a relatively straightforward way to learn from existing data and achieve good performance in common scenarios. However, reinforcement learning holds the potential for developing more robust, adaptable, and ultimately safer autonomous driving systems that can go beyond mimicking human limitations. The choice of approach (or a hybrid approach) depends on the specific requirements, constraints, and priorities of the autonomous driving system being developed.</p>
]]></content:encoded></item><item><title><![CDATA[A detailed course plan/roadmap for teaching chemistry at home]]></title><description><![CDATA[Here's a detailed course plan/roadmap for teaching chemistry at home. Chemistry, with its hands-on experiments and real-world applications, can be a fascinating subject for children of all ages. Remember to adapt this plan based on your child's age, ...]]></description><link>https://blog.iread.fun/roadmap-for-teaching-chemistry-at-home</link><guid isPermaLink="true">https://blog.iread.fun/roadmap-for-teaching-chemistry-at-home</guid><category><![CDATA[chemistry]]></category><category><![CDATA[#homeschool]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Fri, 03 Jan 2025 07:19:25 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1735888616695/ba6b6492-a11f-4b45-9488-0f4f4d7bf753.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Here's a detailed course plan/roadmap for teaching chemistry at home. Chemistry, with its hands-on experiments and real-world applications, can be a fascinating subject for children of all ages. Remember to adapt this plan based on your child's age, interests, and learning style.</p>
<h2 id="heading-i-foundational-principles-apply-to-all-ages"><strong>I. Foundational Principles (Apply to all ages):</strong></h2>
<ul>
<li><p><strong>Safety First!</strong> Establish clear safety rules and procedures before any experiment. Always supervise closely, especially with younger children.</p>
</li>
<li><p><strong>Hands-On Experimentation is Crucial:</strong> Chemistry is best learned by doing. Prioritize experiments and demonstrations.</p>
</li>
<li><p><strong>Relate Chemistry to the Real World:</strong> Point out chemistry in everyday life – cooking, cleaning, materials around the house, nature.</p>
</li>
<li><p><strong>Encourage Curiosity and Questioning:</strong> "Why?" is a great question in chemistry. Foster a sense of inquiry.</p>
</li>
<li><p><strong>Use Visual Aids and Models:</strong> Atoms and molecules are abstract. Use diagrams, models, and simulations to make them more tangible.</p>
</li>
<li><p><strong>Build a Strong Vocabulary:</strong> Chemistry has its own language. Introduce and reinforce key terms gradually.</p>
</li>
<li><p><strong>Focus on Understanding, Not Just Memorization:</strong> Help your child understand the underlying principles rather than just memorizing facts.</p>
</li>
<li><p><strong>Keep it Engaging and Fun:</strong> Use colorful reactions, interesting phenomena, and relatable examples.</p>
</li>
<li><p><strong>Progress Gradually:</strong> Build upon previously learned concepts. Don't rush into complex topics before the basics are understood.</p>
</li>
<li><p><strong>Document and Observe:</strong> Encourage your child to keep a lab notebook to record observations, data, and conclusions.</p>
</li>
<li><p><strong>Embrace Mistakes as Learning Opportunities:</strong> Not every experiment will work perfectly. Discuss why things might have gone wrong.</p>
</li>
</ul>
<h2 id="heading-ii-course-roadmap-by-age-group"><strong>II. Course Roadmap by Age Group:</strong></h2>
<h3 id="heading-a-early-elementary-ages-6-8-focus-observation-and-exploring-properties-of-matter"><strong>A. Early Elementary (Ages 6-8): Focus: Observation and Exploring Properties of Matter</strong></h3>
<ul>
<li><p><strong>Key Concepts:</strong></p>
<ul>
<li><p><strong>States of Matter:</strong> Solids, liquids, gases (observable properties, transitions like melting and freezing).</p>
</li>
<li><p><strong>Mixing and Solutions:</strong> What happens when different substances are mixed (dissolving, suspensions).</p>
</li>
<li><p><strong>Physical Changes:</strong> Changes in appearance but not chemical composition (tearing paper, melting ice).</p>
</li>
<li><p><strong>Simple Chemical Reactions (Observable):</strong> Baking soda and vinegar, rusting, burning.</p>
</li>
<li><p><strong>Basic Measurement:</strong> Volume, mass (informal introduction).</p>
</li>
</ul>
</li>
<li><p><strong>Activities &amp; Resources:</strong></p>
<ul>
<li><p><strong>Observing different states of matter:</strong> Ice melting, water boiling, observing different materials.</p>
</li>
<li><p><strong>Mixing experiments:</strong> Making lemonade, dissolving sugar in water, mixing oil and water.</p>
</li>
<li><p><strong>Physical change demonstrations:</strong> Folding paper, cutting vegetables, melting chocolate.</p>
</li>
<li><p><strong>Simple chemical reaction experiments:</strong> Baking soda and vinegar volcano, observing rust formation.</p>
</li>
<li><p><strong>Using measuring cups and spoons:</strong> For simple volume measurements.</p>
</li>
<li><p><strong>Reading age-appropriate science books about matter and simple chemistry.</strong></p>
</li>
<li><p><strong>Watching educational videos on states of matter and simple reactions.</strong></p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-b-upper-elementary-ages-9-11-focus-introducing-atoms-elements-and-simple-reactions"><strong>B. Upper Elementary (Ages 9-11): Focus: Introducing Atoms, Elements, and Simple Reactions</strong></h3>
<ul>
<li><p><strong>Key Concepts:</strong></p>
<ul>
<li><p><strong>Atoms and Molecules (Basic Introduction):</strong> The building blocks of matter.</p>
</li>
<li><p><strong>Elements and the Periodic Table (Introduction):</strong> Common elements (oxygen, hydrogen, carbon, gold).</p>
</li>
<li><p><strong>Compounds:</strong> Two or more elements chemically combined (water, salt).</p>
</li>
<li><p><strong>Chemical Symbols and Formulas (Simple):</strong> H₂O, NaCl.</p>
</li>
<li><p><strong>Chemical Reactions:</strong> Reactants and products, signs of a chemical reaction (color change, gas production, heat).</p>
</li>
<li><p><strong>Acids and Bases (Introduction):</strong> Basic properties and examples (lemon juice, baking soda).</p>
</li>
</ul>
</li>
<li><p><strong>Activities &amp; Resources:</strong></p>
<ul>
<li><p><strong>Building models of atoms and molecules:</strong> Using modeling clay, marshmallows, or building kits.</p>
</li>
<li><p><strong>Exploring the periodic table:</strong> Identifying common elements and their symbols.</p>
</li>
<li><p><strong>More complex chemical reaction experiments:</strong> Making slime, testing for acids and bases with indicators (red cabbage juice).</p>
</li>
<li><p><strong>Investigating density:</strong> Layering liquids, sinking and floating experiments.</p>
</li>
<li><p><strong>Separating mixtures:</strong> Filtration, evaporation, magnetism.</p>
</li>
<li><p><strong>Using basic lab equipment:</strong> Beakers, test tubes, funnels (with supervision).</p>
</li>
<li><p><strong>Reading more detailed science books about atoms, elements, and reactions.</strong></p>
</li>
<li><p><strong>Watching educational videos explaining atoms and chemical reactions.</strong></p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-c-middle-school-ages-12-14-focus-understanding-chemical-bonding-reactions-and-stoichiometry"><strong>C. Middle School (Ages 12-14): Focus: Understanding Chemical Bonding, Reactions, and Stoichiometry</strong></h3>
<ul>
<li><p><strong>Key Concepts:</strong></p>
<ul>
<li><p><strong>Atomic Structure (Protons, Neutrons, Electrons):</strong> Electron shells and valence electrons.</p>
</li>
<li><p><strong>Chemical Bonding:</strong> Ionic and covalent bonds.</p>
</li>
<li><p><strong>The Periodic Table (Organization and Trends):</strong> Groups and periods, properties of metals, nonmetals, and metalloids.</p>
</li>
<li><p><strong>Chemical Formulas and Nomenclature:</strong> Naming simple compounds.</p>
</li>
<li><p><strong>Balancing Chemical Equations:</strong> Conservation of mass.</p>
</li>
<li><p><strong>Types of Chemical Reactions:</strong> Synthesis, decomposition, single and double displacement, combustion.</p>
</li>
<li><p><strong>The Mole Concept:</strong> Avogadro's number (introduction).</p>
</li>
<li><p><strong>Acids, Bases, and pH:</strong> Strong and weak acids/bases, neutralization reactions.</p>
</li>
</ul>
</li>
<li><p><strong>Activities &amp; Resources:</strong></p>
<ul>
<li><p><strong>Building more detailed atomic and molecular models.</strong></p>
</li>
<li><p><strong>Working with the periodic table to predict properties of elements.</strong></p>
</li>
<li><p><strong>Practicing balancing chemical equations.</strong></p>
</li>
<li><p><strong>Conducting different types of chemical reactions:</strong> Precipitation reactions, gas-forming reactions.</p>
</li>
<li><p><strong>Titration experiments (basic).</strong></p>
</li>
<li><p><strong>Investigating reaction rates:</strong> Factors affecting how fast reactions occur.</p>
</li>
<li><p><strong>Using more advanced lab equipment:</strong> Bunsen burners (with strict supervision), graduated cylinders.</p>
</li>
<li><p><strong>Using chemistry workbooks and textbooks designed for middle school.</strong></p>
</li>
<li><p><strong>Exploring online chemistry simulations and interactive periodic tables.</strong></p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-d-high-school-ages-15-18-focus-advanced-concepts-quantitative-analysis-and-organic-chemistry"><strong>D. High School (Ages 15-18): Focus: Advanced Concepts, Quantitative Analysis, and Organic Chemistry</strong></h3>
<ul>
<li><p><strong>This stage often involves more specialized courses. You can adapt based on your child's interests and goals. Common topics include:</strong></p>
<ul>
<li><p><strong>Stoichiometry (Quantitative Relationships):</strong> Limiting reactants, percent yield.</p>
</li>
<li><p><strong>States of Matter (Advanced):</strong> Gas laws, intermolecular forces, phase diagrams.</p>
</li>
<li><p><strong>Solutions:</strong> Concentration, solubility, colligative properties.</p>
</li>
<li><p><strong>Chemical Kinetics:</strong> Reaction rates, rate laws, activation energy, catalysts.</p>
</li>
<li><p><strong>Chemical Equilibrium:</strong> Le Chatelier's principle.</p>
</li>
<li><p><strong>Thermochemistry:</strong> Enthalpy, entropy, Gibbs free energy.</p>
</li>
<li><p><strong>Acids and Bases (Advanced):</strong> Acid-base equilibrium, buffers, titrations.</p>
</li>
<li><p><strong>Oxidation-Reduction Reactions:</strong> Electrochemistry, electrochemical cells.</p>
</li>
<li><p><strong>Organic Chemistry (Introduction):</strong> Nomenclature, functional groups, basic reactions of alkanes, alkenes, and alkynes.</p>
</li>
<li><p><strong>Biochemistry (Introduction):</strong> Basic structure and function of carbohydrates, lipids, and proteins.</p>
</li>
<li><p><strong>Nuclear Chemistry (Optional):</strong> Radioactivity, nuclear reactions.</p>
</li>
</ul>
</li>
<li><p><strong>Activities &amp; Resources:</strong></p>
<ul>
<li><p><strong>More complex and quantitative experiments:</strong> Determining molar mass, enthalpy changes, reaction rates.</p>
</li>
<li><p><strong>Titration experiments with calculations.</strong></p>
</li>
<li><p><strong>Synthesis experiments (following safe procedures).</strong></p>
</li>
<li><p><strong>Using more sophisticated lab equipment:</strong> Spectrophotometer (if accessible), analytical balances.</p>
</li>
<li><p><strong>Solving complex stoichiometry and equilibrium problems.</strong></p>
</li>
<li><p><strong>Drawing organic molecules and reaction mechanisms.</strong></p>
</li>
<li><p><strong>Using high school chemistry textbooks and lab manuals.</strong></p>
</li>
<li><p><strong>Exploring online chemistry resources, including simulations, virtual labs, and university-level lectures (like Khan Academy).</strong></p>
</li>
<li><p><strong>Consider using AP or IB chemistry curriculum materials if preparing for advanced placement exams.</strong></p>
</li>
</ul>
</li>
</ul>
<h2 id="heading-iii-essential-resources-to-have-on-hand"><strong>III. Essential Resources to Have On Hand:</strong></h2>
<ul>
<li><p><strong>Safety Equipment:</strong> Safety goggles, lab coats or aprons, gloves (nitrile or latex).</p>
</li>
<li><p><strong>Basic Labware:</strong> Beakers, Erlenmeyer flasks, test tubes, graduated cylinders, funnels, stirring rods, pipettes (droppers).</p>
</li>
<li><p><strong>Measuring Tools:</strong> Balances (kitchen scale for basic, analytical balance for higher levels), thermometers.</p>
</li>
<li><p><strong>Heating Equipment:</strong> Hot plate, Bunsen burner (with appropriate safety training and supervision).</p>
</li>
<li><p><strong>Chemicals (Start Simple and Gradually Increase Complexity):</strong> Baking soda, vinegar, salt, sugar, food coloring, various household chemicals (cleaners, etc. - use with caution and supervision), and gradually introduce more specific lab chemicals as needed.</p>
</li>
<li><p><strong>pH Testing Supplies:</strong> pH paper, universal indicator, red cabbage juice indicator.</p>
</li>
<li><p><strong>Models:</strong> Atomic and molecular model kits.</p>
</li>
<li><p><strong>Periodic Table:</strong> A good quality, detailed periodic table.</p>
</li>
<li><p><strong>Notebook or Lab Journal:</strong> For recording observations, data, and calculations.</p>
</li>
<li><p><strong>Textbooks and Workbooks (age-appropriate).</strong></p>
</li>
<li><p><strong>Online Resources and Simulations.</strong></p>
</li>
<li><p><strong>First Aid Kit.</strong></p>
</li>
</ul>
<h2 id="heading-iv-tips-for-success"><strong>IV. Tips for Success:</strong></h2>
<ul>
<li><p><strong>Start Simple and Build Gradually:</strong> Don't try to cover too much too soon.</p>
</li>
<li><p><strong>Emphasize Visual Learning:</strong> Use diagrams, charts, and demonstrations.</p>
</li>
<li><p><strong>Make it Hands-On:</strong> Prioritize experiments and activities.</p>
</li>
<li><p><strong>Connect to Real-World Applications:</strong> Show the relevance of chemistry.</p>
</li>
<li><p><strong>Encourage Questions and Discussion:</strong> Create a learning environment where your child feels comfortable asking questions.</p>
</li>
<li><p><strong>Review and Reinforce Concepts Regularly:</strong> Chemistry builds upon itself.</p>
</li>
<li><p><strong>Use a Variety of Resources:</strong> Combine textbooks, experiments, online tools, and videos.</p>
</li>
<li><p><strong>Join Homeschool Science Groups or Online Forums:</strong> Share resources and ideas with other homeschooling families.</p>
</li>
<li><p><strong>Consider Unit Studies:</strong> Focus on a specific area of chemistry for a period of time.</p>
</li>
<li><p><strong>Visit Science Museums and Laboratories (if possible).</strong></p>
</li>
</ul>
<h2 id="heading-v-important-considerations"><strong>V. Important Considerations:</strong></h2>
<ul>
<li><p><strong>Math Prerequisites:</strong> Chemistry heavily relies on math, especially algebra. Ensure your child has a solid foundation in math.</p>
</li>
<li><p><strong>Lab Safety:</strong> This is paramount. Establish and enforce strict safety rules.</p>
</li>
<li><p><strong>Chemical Availability and Storage:</strong> Be mindful of where you purchase chemicals and how you store them safely.</p>
</li>
<li><p><strong>Disposal of Chemicals:</strong> Learn proper disposal methods for any chemicals used in experiments.</p>
</li>
<li><p><strong>Learning Disabilities:</strong> Adapt your teaching methods and provide extra support if your child has learning disabilities.</p>
</li>
<li><p><strong>Time Commitment:</strong> Experiments can take time, so plan accordingly.</p>
</li>
<li><p><strong>Cost:</strong> Lab supplies and chemicals can add up, so budget accordingly. Look for affordable alternatives and consider borrowing equipment if possible.</p>
</li>
</ul>
<p>By following this detailed course plan and prioritizing hands-on learning and safety, you can create a rich and engaging chemistry education for your child at home. Remember to be flexible and adapt the plan to suit your child's individual needs and interests.</p>
]]></content:encoded></item><item><title><![CDATA[A detailed course plan/roadmap for teaching physics at home]]></title><description><![CDATA[Okay, here's a detailed course plan/roadmap for teaching physics at home. Like math, physics can be approached in a hands-on, inquiry-based way, making it engaging for children of all ages. Remember to adapt this plan based on your child's age, inter...]]></description><link>https://blog.iread.fun/roadmap-for-teaching-physics-at-home</link><guid isPermaLink="true">https://blog.iread.fun/roadmap-for-teaching-physics-at-home</guid><category><![CDATA[#homeschool]]></category><category><![CDATA[Physics]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Fri, 03 Jan 2025 03:43:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1735875629184/34c84068-1761-4875-a70b-d2f0a02bf299.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Okay, here's a detailed course plan/roadmap for teaching physics at home. Like math, physics can be approached in a hands-on, inquiry-based way, making it engaging for children of all ages. Remember to adapt this plan based on your child's age, interests, and learning style.</p>
<h2 id="heading-i-foundational-principles-apply-to-all-ages"><strong>I. Foundational Principles (Apply to all ages):</strong></h2>
<ul>
<li><p><strong>Focus on Inquiry and Exploration:</strong> Physics is about understanding how the world works. Encourage curiosity, questioning, and experimentation. "Why?" is a great starting point.</p>
</li>
<li><p><strong>Hands-On Activities and Experiments are Key:</strong> Physics concepts become much clearer when children can see, touch, and manipulate objects. Simple, everyday materials can be used for many experiments.</p>
</li>
<li><p><strong>Real-World Connections:</strong> Point out physics principles at play in everyday life – how things move, why things fall, how machines work, how light and sound behave.</p>
</li>
<li><p><strong>Visualizations and Analogies:</strong> Physics can be abstract. Use visual aids (diagrams, videos, simulations) and relatable analogies to help your child grasp concepts.</p>
</li>
<li><p><strong>Mathematical Foundation (Gradual Introduction):</strong> While math is essential for advanced physics, the initial focus should be on conceptual understanding. Introduce mathematical tools as needed.</p>
</li>
<li><p><strong>Embrace Failure as a Learning Opportunity:</strong> Experiments don't always go as planned. Encourage your child to analyze why something didn't work and how to improve it.</p>
</li>
<li><p><strong>Keep it Engaging and Fun:</strong> Use games, stories, and demonstrations to spark interest. Avoid making it feel like a chore.</p>
</li>
<li><p><strong>Regular Exploration, But Keep it Manageable:</strong> Short, focused sessions are better than long, infrequent ones, especially for younger children.</p>
</li>
<li><p><strong>Patience and Encouragement:</strong> Physics can be challenging. Offer positive reinforcement and celebrate successes.</p>
</li>
<li><p><strong>Connect with Other Learners (If Possible):</strong> Consider online forums, homeschool groups, or science clubs for interaction and shared learning.</p>
</li>
</ul>
<h2 id="heading-ii-course-roadmap-by-age-group"><strong>II. Course Roadmap by Age Group:</strong></h2>
<h3 id="heading-a-early-elementary-ages-6-8-focus-observation-and-basic-physical-phenomena"><strong>A. Early Elementary (Ages 6-8): Focus: Observation and Basic Physical Phenomena</strong></h3>
<ul>
<li><p><strong>Key Concepts:</strong></p>
<ul>
<li><p><strong>Motion:</strong> Describing how things move (fast, slow, straight, curved, back and forth).</p>
</li>
<li><p><strong>Forces (Introduction):</strong> Pushes and pulls, gravity (things fall down), magnetism (attraction and repulsion).</p>
</li>
<li><p><strong>Energy (Introduction):</strong> The ability to do work or cause change (light, heat, movement).</p>
</li>
<li><p><strong>Simple Machines:</strong> Levers, pulleys, wheels and axles, inclined planes (how they make work easier).</p>
</li>
<li><p><strong>States of Matter:</strong> Solid, liquid, gas (basic properties and transitions).</p>
</li>
<li><p><strong>Light:</strong> How light travels, shadows, reflection.</p>
</li>
<li><p><strong>Sound:</strong> How sound travels, vibrations.</p>
</li>
</ul>
</li>
<li><p><strong>Activities &amp; Resources:</strong></p>
<ul>
<li><p><strong>Simple experiments:</strong> Dropping objects (gravity), playing with magnets, building ramps (inclined planes), pushing and pulling toys.</p>
</li>
<li><p><strong>Observation walks:</strong> Identifying examples of motion, forces, and energy in their surroundings.</p>
</li>
<li><p><strong>Building simple machines:</strong> Using LEGOs, K'NEX, or household items.</p>
</li>
<li><p><strong>Exploring light and shadows:</strong> Using flashlights, making shadow puppets.</p>
</li>
<li><p><strong>Making musical instruments:</strong> Exploring how vibrations create sound.</p>
</li>
<li><p><strong>Reading age-appropriate science books and watching educational videos.</strong></p>
</li>
<li><p><strong>Using toys that demonstrate physics principles:</strong> Marbles, toy cars, building blocks.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-b-upper-elementary-ages-9-11-focus-introducing-basic-laws-and-quantitative-observations"><strong>B. Upper Elementary (Ages 9-11): Focus: Introducing Basic Laws and Quantitative Observations</strong></h3>
<ul>
<li><p><strong>Key Concepts:</strong></p>
<ul>
<li><p><strong>Motion (More Detailed):</strong> Speed, distance, time. Introduction to Newton's First Law (inertia).</p>
</li>
<li><p><strong>Forces (More Detailed):</strong> Types of forces (gravity, friction, air resistance), balanced and unbalanced forces.</p>
</li>
<li><p><strong>Energy (More Detailed):</strong> Kinetic energy (energy of motion), potential energy (stored energy). Introduction to conservation of energy.</p>
</li>
<li><p><strong>Heat and Temperature:</strong> Heat transfer (conduction, convection, radiation).</p>
</li>
<li><p><strong>Electricity (Static and Simple Circuits):</strong> Static electricity, conductors and insulators, batteries, light bulbs.</p>
</li>
<li><p><strong>Magnetism (More Detailed):</strong> Magnetic fields, electromagnets.</p>
</li>
<li><p><strong>Waves (Introduction):</strong> Basic properties of waves (wavelength, frequency). Sound waves and light waves.</p>
</li>
</ul>
</li>
<li><p><strong>Activities &amp; Resources:</strong></p>
<ul>
<li><p><strong>Measuring speed and distance:</strong> Using stopwatches and rulers.</p>
</li>
<li><p><strong>Experiments with friction:</strong> Sliding objects on different surfaces.</p>
</li>
<li><p><strong>Building simple circuits:</strong> Using batteries, wires, and bulbs.</p>
</li>
<li><p><strong>Exploring electromagnets:</strong> Making a simple electromagnet.</p>
</li>
<li><p><strong>Observing heat transfer:</strong> Melting ice, feeling heat from a light bulb.</p>
</li>
<li><p><strong>Investigating sound waves:</strong> Using tuning forks, making string telephones.</p>
</li>
<li><p><strong>Simple investigations with lenses and mirrors.</strong></p>
</li>
<li><p><strong>Using online simulations and interactive resources.</strong></p>
</li>
<li><p><strong>More detailed science books and documentaries.</strong></p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-c-middle-school-ages-12-14-focus-formalizing-concepts-and-introducing-mathematical-relationships"><strong>C. Middle School (Ages 12-14): Focus: Formalizing Concepts and Introducing Mathematical Relationships</strong></h3>
<ul>
<li><p><strong>Key Concepts:</strong></p>
<ul>
<li><p><strong>Newton's Laws of Motion:</strong> A deeper understanding of inertia, force, and acceleration.</p>
</li>
<li><p><strong>Work, Power, and Energy:</strong> Calculating work, power, and different forms of energy.</p>
</li>
<li><p><strong>Conservation of Energy and Momentum:</strong> Applying these principles to solve problems.</p>
</li>
<li><p><strong>Simple Harmonic Motion:</strong> Pendulums, springs.</p>
</li>
<li><p><strong>Mechanical Waves:</strong> Transverse and longitudinal waves, superposition, interference.</p>
</li>
<li><p><strong>Sound:</strong> Speed of sound, intensity, Doppler effect.</p>
</li>
<li><p><strong>Light and Optics:</strong> Reflection, refraction, lenses, mirrors, the electromagnetic spectrum.</p>
</li>
<li><p><strong>Electricity and Magnetism (More Quantitative):</strong> Ohm's Law, series and parallel circuits, magnetic fields around wires.</p>
</li>
</ul>
</li>
<li><p><strong>Activities &amp; Resources:</strong></p>
<ul>
<li><p><strong>Experiments involving forces and motion:</strong> Using carts, springs, and weights.</p>
</li>
<li><p><strong>Building more complex circuits:</strong> Measuring voltage and current.</p>
</li>
<li><p><strong>Investigating wave phenomena:</strong> Using slinkies, ripple tanks.</p>
</li>
<li><p><strong>Solving quantitative problems:</strong> Calculating speed, acceleration, force, energy.</p>
</li>
<li><p><strong>Using simulations to explore complex phenomena.</strong></p>
</li>
<li><p><strong>Introduction to basic algebra and its application in physics.</strong></p>
</li>
<li><p><strong>Age-appropriate physics textbooks or curriculum materials.</strong></p>
</li>
<li><p><strong>More in-depth documentaries and scientific articles.</strong></p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-d-high-school-ages-15-18-focus-advanced-concepts-and-mathematical-rigor"><strong>D. High School (Ages 15-18): Focus: Advanced Concepts and Mathematical Rigor</strong></h3>
<ul>
<li><p><strong>This stage becomes more specialized depending on your child's interests and future academic goals. You can cover these topics in separate courses or integrate them:</strong></p>
<ul>
<li><p><strong>Classical Mechanics (Advanced):</strong> Kinematics in 2D and 3D, rotational motion, angular momentum, gravity, oscillations, waves. Calculus is often used extensively here.</p>
</li>
<li><p><strong>Electricity and Magnetism (Advanced):</strong> Electric fields, magnetic fields, electromagnetic induction, Maxwell's equations, AC circuits, electromagnetic waves. Calculus is essential.</p>
</li>
<li><p><strong>Thermodynamics:</strong> Laws of thermodynamics, entropy, heat engines.</p>
</li>
<li><p><strong>Optics (Advanced):</strong> Wave optics, interference, diffraction, polarization.</p>
</li>
<li><p><strong>Modern Physics:</strong></p>
<ul>
<li><p><strong>Relativity (Special and General):</strong> Time dilation, length contraction, mass-energy equivalence, spacetime.</p>
</li>
<li><p><strong>Quantum Mechanics:</strong> Wave-particle duality, atomic structure, quantum phenomena.</p>
</li>
<li><p><strong>Nuclear Physics:</strong> Radioactivity, nuclear reactions, nuclear energy.</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Activities &amp; Resources:</strong></p>
<ul>
<li><p><strong>More sophisticated experiments:</strong> Using advanced lab equipment (if accessible), analyzing data quantitatively.</p>
</li>
<li><p><strong>Solving complex physics problems:</strong> Applying calculus and advanced mathematical techniques.</p>
</li>
<li><p><strong>Building projects that demonstrate physics principles.</strong></p>
</li>
<li><p><strong>Reading college-level physics textbooks.</strong></p>
</li>
<li><p><strong>Participating in science competitions and Olympiads.</strong></p>
</li>
<li><p><strong>Exploring online resources like MIT OpenCourseware, Khan Academy (Advanced Physics).</strong></p>
</li>
<li><p><strong>Consider using a structured high school physics curriculum (textbook and accompanying materials).</strong></p>
</li>
</ul>
</li>
</ul>
<h2 id="heading-iii-essential-resources-to-have-on-hand"><strong>III. Essential Resources to Have On Hand:</strong></h2>
<ul>
<li><p><strong>Basic Measurement Tools:</strong> Rulers, meter sticks, measuring tapes, stopwatches, scales.</p>
</li>
<li><p><strong>Tools for Mechanics Experiments:</strong> Toy cars, ramps, blocks, springs, weights, pulleys, pendulums.</p>
</li>
<li><p><strong>Electricity and Magnetism Supplies:</strong> Batteries, wires, light bulbs, switches, magnets, compasses.</p>
</li>
<li><p><strong>Optics Equipment:</strong> Flashlights, lenses, prisms, mirrors.</p>
</li>
<li><p><strong>Heat and Thermodynamics Tools:</strong> Thermometers, beakers, containers for heating and cooling.</p>
</li>
<li><p><strong>Safety Equipment:</strong> Safety goggles, gloves (when needed).</p>
</li>
<li><p><strong>Notebooks or Lab Journals:</strong> For recording observations, data, and calculations.</p>
</li>
<li><p><strong>Whiteboard or Large Paper:</strong> For diagrams and brainstorming.</p>
</li>
<li><p><strong>Computer with Internet Access:</strong> For research, simulations, and educational videos.</p>
</li>
<li><p><strong>Optional: More Advanced Lab Equipment (depending on the level):</strong> Multimeter, oscilloscope, force sensors.</p>
</li>
</ul>
<h2 id="heading-iv-tips-for-success"><strong>IV. Tips for Success:</strong></h2>
<ul>
<li><p><strong>Start with Observations and Questions:</strong> Encourage your child to notice the physics around them and ask questions.</p>
</li>
<li><p><strong>Keep Experiments Hands-On and Engaging:</strong> Even complex concepts can be introduced through simple demonstrations.</p>
</li>
<li><p><strong>Gradually Introduce Mathematical Formalism:</strong> Don't overwhelm younger children with equations.</p>
</li>
<li><p><strong>Connect Physics to Other Subjects:</strong> Show how physics relates to math, chemistry, biology, and engineering.</p>
</li>
<li><p><strong>Utilize Online Resources Wisely:</strong> Simulations, videos, and interactive websites can be very helpful, but choose reliable sources.</p>
</li>
<li><p><strong>Don't Be Afraid to Say "I Don't Know":</strong> Use it as an opportunity to learn together.</p>
</li>
<li><p><strong>Find a Good Physics Curriculum (Especially for High School):</strong> A structured curriculum can provide a roadmap and ensure comprehensive coverage.</p>
</li>
<li><p><strong>Consider Unit Studies:</strong> Focus on a specific area of physics for a period (e.g., a unit on electricity, a unit on motion).</p>
</li>
<li><p><strong>Visit Science Museums and Planetariums:</strong> These provide real-world examples and inspiration.</p>
</li>
<li><p><strong>Encourage Participation in Science Fairs and Competitions:</strong> This can motivate learning and provide valuable experience.</p>
</li>
</ul>
<h2 id="heading-v-important-considerations"><strong>V. Important Considerations:</strong></h2>
<ul>
<li><p><strong>Math Prerequisites:</strong> Ensure your child has the necessary math skills for the physics concepts being taught (especially algebra and calculus for higher levels).</p>
</li>
<li><p><strong>Learning Styles:</strong> Adapt your teaching methods to your child's preferred learning style (visual, auditory, kinesthetic).</p>
</li>
<li><p><strong>Time Commitment:</strong> Physics requires time for experimentation, problem-solving, and discussion.</p>
</li>
<li><p><strong>Safety:</strong> Always prioritize safety during experiments. Supervise closely and teach safe practices.</p>
</li>
<li><p><strong>Seeking Help:</strong> Don't hesitate to seek help from online forums, other homeschooling parents, or tutors if you encounter difficulties.</p>
</li>
<li><p><strong>Keeping it Relevant:</strong> Connect physics to your child's interests (e.g., if they like cars, focus on mechanics; if they like music, explore sound waves).</p>
</li>
</ul>
<p>By following this roadmap and keeping a focus on inquiry, experimentation, and real-world connections, you can provide your child with a strong foundation in physics at home. Remember to be flexible and enjoy the process of discovery!</p>
]]></content:encoded></item><item><title><![CDATA[A detailed course plan/roadmap for teaching mathematics at home]]></title><description><![CDATA[That's fantastic you're taking the initiative to teach your child math at home! This can be a rewarding experience. Here's a detailed course plan/roadmap, broken down by age groups and key mathematical concepts. Remember that this is a guideline, and...]]></description><link>https://blog.iread.fun/roadmap-for-teaching-mathematics-at-home</link><guid isPermaLink="true">https://blog.iread.fun/roadmap-for-teaching-mathematics-at-home</guid><category><![CDATA[Mathematics]]></category><category><![CDATA[#homeschool]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Fri, 03 Jan 2025 03:21:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1735873644633/51f64966-22bc-4c5e-81b8-87acea61c2c7.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>That's fantastic you're taking the initiative to teach your child math at home! This can be a rewarding experience. Here's a detailed course plan/roadmap, broken down by age groups and key mathematical concepts. Remember that this is a guideline, and you'll need to adapt it based on your child's individual pace, interests, and learning style.</p>
<h2 id="heading-i-foundational-principles-apply-to-all-ages"><strong>I. Foundational Principles (Apply to all ages):</strong></h2>
<ul>
<li><p><strong>Make it Fun and Engaging:</strong> Use games, stories, real-world examples, and hands-on activities to make learning enjoyable. Avoid turning it into a chore.</p>
</li>
<li><p><strong>Focus on Understanding, Not Just Memorization:</strong> Encourage your child to explain their reasoning and not just recite facts.</p>
</li>
<li><p><strong>Build on Previous Knowledge:</strong> Ensure they have a solid grasp of earlier concepts before moving on to more complex ones.</p>
</li>
<li><p><strong>Use Manipulatives and Visual Aids:</strong> Tangible objects (like blocks, counters, and even food!) and visual representations (like drawings and diagrams) can make abstract concepts more concrete.</p>
</li>
<li><p><strong>Regular Practice, But Keep it Short:</strong> Consistent, short sessions are more effective than long, infrequent ones.</p>
</li>
<li><p><strong>Patience and Encouragement:</strong> Learning takes time. Be patient, offer positive reinforcement, and celebrate their progress.</p>
</li>
<li><p><strong>Real-World Connections:</strong> Show how math is used in everyday life (e.g., measuring ingredients while cooking, counting money, telling time).</p>
</li>
<li><p><strong>Embrace Mistakes as Learning Opportunities:</strong> Help your child understand that mistakes are a normal part of learning and a chance to identify areas for improvement.</p>
</li>
<li><p><strong>Stay Flexible and Adapt:</strong> Be prepared to adjust your plan based on your child's progress and interests. Don't be afraid to slow down or revisit concepts as needed.</p>
</li>
</ul>
<h2 id="heading-ii-course-roadmap-by-age-group"><strong>II. Course Roadmap by Age Group:</strong></h2>
<h3 id="heading-a-preschoolearly-kindergarten-ages-3-5-focus-number-sense-and-early-spatial-reasoning"><strong>A. Preschool/Early Kindergarten (Ages 3-5): Focus: Number Sense and Early Spatial Reasoning</strong></h3>
<ul>
<li><p><strong>Key Concepts:</strong></p>
<ul>
<li><p><strong>Number Recognition (1-10 and beyond):</strong> Recognizing and naming numerals.</p>
</li>
<li><p><strong>Counting:</strong> Rote counting (saying numbers in order) and one-to-one correspondence (matching one object to one number).</p>
</li>
<li><p><strong>Subitizing:</strong> Recognizing small quantities (like 2 or 3) instantly without counting.</p>
</li>
<li><p><strong>Comparing Quantities:</strong> Understanding "more than," "less than," and "the same as."</p>
</li>
<li><p><strong>Shapes:</strong> Identifying and naming basic shapes (circle, square, triangle, rectangle).</p>
</li>
<li><p><strong>Spatial Reasoning:</strong> Understanding positional words (above, below, beside, in front of, behind).</p>
</li>
<li><p><strong>Patterns:</strong> Recognizing and creating simple patterns.</p>
</li>
<li><p><strong>Measurement (Informal):</strong> Comparing lengths, weights, and volumes using non-standard units (e.g., "This block is longer than that one").</p>
</li>
</ul>
</li>
<li><p><strong>Activities &amp; Resources:</strong></p>
<ul>
<li><p><strong>Counting games:</strong> Counting fingers, toes, toys, snacks.</p>
</li>
<li><p><strong>Shape sorting and matching:</strong> Using shape sorters, drawing shapes.</p>
</li>
<li><p><strong>Building with blocks:</strong> Encouraging spatial reasoning and understanding of shapes.</p>
</li>
<li><p><strong>Singing counting songs and rhymes:</strong> Reinforces number sequences.</p>
</li>
<li><p><strong>Using manipulatives:</strong> Counting beans, buttons, or small toys.</p>
</li>
<li><p><strong>Reading counting books:</strong> Many engaging picture books introduce numbers.</p>
</li>
<li><p><strong>Simple pattern activities:</strong> Using beads, blocks, or stickers.</p>
</li>
<li><p><strong>Comparing activities:</strong> "Which pile has more?" "Are there enough cups for everyone?"</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-b-kindergartenearly-elementary-ages-5-7-focus-building-number-sense-and-basic-operations"><strong>B. Kindergarten/Early Elementary (Ages 5-7): Focus: Building Number Sense and Basic Operations</strong></h3>
<ul>
<li><p><strong>Key Concepts:</strong></p>
<ul>
<li><p><strong>Number Recognition and Writing (up to 100 and beyond):</strong> Connecting numerals to their quantity.</p>
</li>
<li><p><strong>Counting (beyond 100):</strong> Understanding place value (tens and ones).</p>
</li>
<li><p><strong>Number Order and Sequencing:</strong> Identifying the number that comes before, after, or between.</p>
</li>
<li><p><strong>Addition and Subtraction (within 20):</strong> Understanding the concepts of joining and taking away.</p>
</li>
<li><p><strong>Introduction to Multiplication (as repeated addition):</strong> Using groups of objects.</p>
</li>
<li><p><strong>Measurement (Standard Units):</strong> Introducing units like inches, centimeters, and simple time telling (o'clock).</p>
</li>
<li><p><strong>Fractions (Basic):</strong> Understanding halves and wholes.</p>
</li>
<li><p><strong>Data and Graphing (Simple):</strong> Collecting and representing data using simple charts (e.g., bar graphs with pictures).</p>
</li>
<li><p><strong>Money (Introduction):</strong> Identifying coins and their values.</p>
</li>
</ul>
</li>
<li><p><strong>Activities &amp; Resources:</strong></p>
<ul>
<li><p><strong>Manipulatives:</strong> Using base-ten blocks to understand place value.</p>
</li>
<li><p><strong>Number lines and hundreds charts:</strong> Visual aids for counting and understanding number relationships.</p>
</li>
<li><p><strong>Addition and subtraction games:</strong> Using dice, cards, or online games.</p>
</li>
<li><p><strong>Story problems:</strong> Presenting math problems in a narrative context.</p>
</li>
<li><p><strong>Measuring objects around the house:</strong> Using rulers and measuring tapes.</p>
</li>
<li><p><strong>Cutting objects into halves:</strong> Visualizing fractions.</p>
</li>
<li><p><strong>Creating simple graphs:</strong> Tracking favorite colors or pets.</p>
</li>
<li><p><strong>Playing store:</strong> Using play money to practice counting and basic transactions.</p>
</li>
<li><p><strong>Online math games and resources:</strong> (e.g., Khan Academy Kids, ABCmouse, Math Playground).</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-c-upper-elementary-ages-8-10-focus-developing-fluency-with-operations-and-introducing-more-complex-concepts"><strong>C. Upper Elementary (Ages 8-10): Focus: Developing Fluency with Operations and Introducing More Complex Concepts</strong></h3>
<ul>
<li><p><strong>Key Concepts:</strong></p>
<ul>
<li><p><strong>Multiplication and Division (Multi-digit):</strong> Developing fluency with multiplication facts and algorithms.</p>
</li>
<li><p><strong>Fractions (Operations):</strong> Adding, subtracting, multiplying, and dividing fractions.</p>
</li>
<li><p><strong>Decimals:</strong> Understanding decimal place value and performing basic operations.</p>
</li>
<li><p><strong>Measurement (Conversions):</strong> Converting between different units of measurement.</p>
</li>
<li><p><strong>Geometry (More Advanced Shapes and Angles):</strong> Identifying different types of triangles, quadrilaterals, and understanding angles.</p>
</li>
<li><p><strong>Area and Perimeter:</strong> Calculating the area and perimeter of simple shapes.</p>
</li>
<li><p><strong>Data Analysis and Probability (Introduction):</strong> Interpreting different types of graphs and understanding basic probability concepts.</p>
</li>
<li><p><strong>Algebraic Thinking (Introduction):</strong> Using variables to represent unknown quantities and solving simple equations.</p>
</li>
</ul>
</li>
<li><p><strong>Activities &amp; Resources:</strong></p>
<ul>
<li><p><strong>Multiplication and division fact practice:</strong> Using flashcards, games, and online resources.</p>
</li>
<li><p><strong>Fraction manipulatives:</strong> Using fraction bars or circles.</p>
</li>
<li><p><strong>Real-world problems involving fractions and decimals:</strong> Cooking, measuring, and finances.</p>
</li>
<li><p><strong>Geometric construction activities:</strong> Using rulers, protractors, and compasses.</p>
</li>
<li><p><strong>Collecting and analyzing data:</strong> Conducting surveys and creating graphs.</p>
</li>
<li><p><strong>Solving simple algebraic puzzles:</strong> Using missing numbers or letter variables.</p>
</li>
<li><p><strong>Math workbooks and textbooks (appropriate for the grade level).</strong></p>
</li>
<li><p><strong>Online resources:</strong> Khan Academy, IXL, Prodigy.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-d-middle-school-ages-11-13-focus-abstract-thinking-and-formal-mathematical-reasoning"><strong>D. Middle School (Ages 11-13): Focus: Abstract Thinking and Formal Mathematical Reasoning</strong></h3>
<ul>
<li><p><strong>Key Concepts:</strong></p>
<ul>
<li><p><strong>Number Systems:</strong> Working with integers, rational numbers, and understanding the real number system.</p>
</li>
<li><p><strong>Algebra (Formal):</strong> Solving equations and inequalities, working with variables and expressions, graphing linear equations.</p>
</li>
<li><p><strong>Geometry (Congruence, Similarity, Transformations):</strong> Understanding geometric proofs and relationships.</p>
</li>
<li><p><strong>Ratios and Proportional Relationships:</strong> Solving problems involving proportions, scale factors, and percentages.</p>
</li>
<li><p><strong>Statistics and Probability (More Advanced):</strong> Calculating measures of central tendency, understanding probability distributions.</p>
</li>
<li><p><strong>Functions (Introduction):</strong> Understanding the concept of a function and its representation.</p>
</li>
</ul>
</li>
<li><p><strong>Activities &amp; Resources:</strong></p>
<ul>
<li><p><strong>Algebra puzzles and word problems:</strong> Applying algebraic concepts to real-world situations.</p>
</li>
<li><p><strong>Geometric constructions and proofs:</strong> Developing logical reasoning skills.</p>
</li>
<li><p><strong>Working with scale drawings and maps:</strong> Applying proportional reasoning.</p>
</li>
<li><p><strong>Conducting statistical investigations:</strong> Collecting, analyzing, and interpreting data.</p>
</li>
<li><p><strong>Graphing calculators (optional, but helpful).</strong></p>
</li>
<li><p><strong>Pre-algebra and algebra textbooks.</strong></p>
</li>
<li><p><strong>Online resources:</strong> Khan Academy, Mathway, Wolfram Alpha.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-e-high-school-ages-14-18-focus-advanced-mathematical-concepts-and-preparation-for-higher-education"><strong>E. High School (Ages 14-18): Focus: Advanced Mathematical Concepts and Preparation for Higher Education</strong></h3>
<ul>
<li><p><strong>This stage becomes more personalized based on the child's interests and future goals. Common subjects include:</strong></p>
<ul>
<li><p><strong>Algebra I &amp; II:</strong> Advanced algebraic concepts, quadratic equations, polynomials, functions.</p>
</li>
<li><p><strong>Geometry (Advanced):</strong> Proofs, trigonometry, analytical geometry.</p>
</li>
<li><p><strong>Trigonometry:</strong> Study of triangles and trigonometric functions.</p>
</li>
<li><p><strong>Precalculus:</strong> Preparation for calculus, including advanced functions, logarithms, and sequences.</p>
</li>
<li><p><strong>Calculus:</strong> Differential and integral calculus.</p>
</li>
<li><p><strong>Statistics and Probability (Advanced):</strong> Inferential statistics, hypothesis testing.</p>
</li>
<li><p><strong>Discrete Mathematics:</strong> Logic, sets, combinatorics, graph theory.</p>
</li>
</ul>
</li>
<li><p><strong>Resources:</strong></p>
<ul>
<li><p><strong>High school math textbooks.</strong></p>
</li>
<li><p><strong>Online courses:</strong> Khan Academy, Coursera, edX.</p>
</li>
<li><p><strong>Tutoring (if needed).</strong></p>
</li>
<li><p><strong>Practice problems and standardized test preparation materials.</strong></p>
</li>
</ul>
</li>
</ul>
<h2 id="heading-iii-essential-resources-to-have-on-hand"><strong>III. Essential Resources to Have On Hand:</strong></h2>
<ul>
<li><p><strong>Manipulatives:</strong> Base-ten blocks, counting bears, fraction circles/bars, pattern blocks, dice, playing cards.</p>
</li>
<li><p><strong>Measuring Tools:</strong> Rulers, measuring tapes, scales, measuring cups and spoons.</p>
</li>
<li><p><strong>Geometry Tools:</strong> Protractor, compass.</p>
</li>
<li><p><strong>Writing Materials:</strong> Pencils, erasers, paper, notebooks, whiteboard/markers.</p>
</li>
<li><p><strong>Visual Aids:</strong> Number lines, hundreds charts, geometric shape cutouts.</p>
</li>
<li><p><strong>Workbooks and Textbooks (age-appropriate).</strong></p>
</li>
<li><p><strong>Online Resources and Apps (carefully selected and monitored).</strong></p>
</li>
<li><p><strong>Real-World Objects:</strong> Coins, food items, toys.</p>
</li>
</ul>
<h2 id="heading-iv-tips-for-success"><strong>IV. Tips for Success:</strong></h2>
<ul>
<li><p><strong>Establish a Routine:</strong> Set aside dedicated time for math learning.</p>
</li>
<li><p><strong>Create a Dedicated Learning Space:</strong> Minimize distractions.</p>
</li>
<li><p><strong>Connect with Other Homeschooling Families:</strong> Share resources and support.</p>
</li>
<li><p><strong>Stay Informed About Math Curriculum Standards:</strong> While you're not bound by public school standards, understanding them can be helpful.</p>
</li>
<li><p><strong>Don't Be Afraid to Seek Help:</strong> Utilize online resources, tutors, or other homeschooling parents when you encounter challenges.</p>
</li>
<li><p><strong>Celebrate Milestones:</strong> Acknowledge and celebrate your child's progress.</p>
</li>
<li><p><strong>Continuously Assess Understanding:</strong> Don't just move on if your child struggles with a concept. Revisit and reinforce.</p>
</li>
</ul>
<h2 id="heading-v-important-considerations"><strong>V. Important Considerations:</strong></h2>
<ul>
<li><p><strong>Learning Disabilities:</strong> If your child struggles significantly, consider exploring resources and strategies for learning disabilities in math (dyscalculia).</p>
</li>
<li><p><strong>Keeping Up with Peers (if that's a concern):</strong> Compare your curriculum to established standards for your child's age group.</p>
</li>
<li><p><strong>Socialization:</strong> Ensure your child has opportunities for social interaction outside of homeschooling.</p>
</li>
<li><p><strong>Burnout (for both you and your child):</strong> Be flexible, take breaks, and keep learning enjoyable.</p>
</li>
</ul>
<p>This is a comprehensive roadmap, and you can adjust it to fit your child's specific needs and your teaching style. Remember to enjoy the journey of learning together! Good luck!</p>
]]></content:encoded></item><item><title><![CDATA[Colors in Makie.jl]]></title><description><![CDATA[# https://github.com/JuliaPlots/PlotUtils.jl/blob/master/src/colorschemes.jl
abstract type AbstractColorList end

abstract type ColorGradient <: AbstractColorList end

struct ContinuousColorGradient <: ColorGradient
    colors::ColorScheme
    values...]]></description><link>https://blog.iread.fun/colors-in-makiejl</link><guid isPermaLink="true">https://blog.iread.fun/colors-in-makiejl</guid><category><![CDATA[makie.jl]]></category><category><![CDATA[Julia]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Thu, 09 May 2024 06:52:30 GMT</pubDate><content:encoded><![CDATA[<pre><code class="lang-julia"><span class="hljs-comment"># https://github.com/JuliaPlots/PlotUtils.jl/blob/master/src/colorschemes.jl</span>
<span class="hljs-keyword">abstract type</span> AbstractColorList <span class="hljs-keyword">end</span>

<span class="hljs-keyword">abstract type</span> ColorGradient &lt;: AbstractColorList <span class="hljs-keyword">end</span>

<span class="hljs-keyword">struct</span> ContinuousColorGradient &lt;: ColorGradient
    colors::ColorScheme
    values::<span class="hljs-built_in">Vector</span>{<span class="hljs-built_in">Float64</span>}

    <span class="hljs-keyword">function</span> ContinuousColorGradient(colors, values = get_range(colors))
        c, v = prepare_continuous_cgrad_colors(colors, values)
        new(c, v)
    <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>

<span class="hljs-keyword">struct</span> CategoricalColorGradient &lt;: ColorGradient
    colors::ColorScheme
    values::<span class="hljs-built_in">Vector</span>{<span class="hljs-built_in">Float64</span>}

    <span class="hljs-keyword">function</span> CategoricalColorGradient(colors, values = get_range(colors))
        c, v = prepare_categorical_cgrad_colors(colors, values)
        new(c, v)
    <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>

<span class="hljs-keyword">struct</span> ColorPalette &lt;: AbstractColorList
    colors::ColorScheme
<span class="hljs-keyword">end</span>

<span class="hljs-string">"""
cgrad(colors, [values]; 
  categorical = nothing, scale = nothing, rev = false, alpha = nothing)

Construct a Colorgradient from `colors` and `values`.

`colors` can be a symbol for ColorSchemes.jl `ColorScheme`s, a `ColorScheme`, a vector of colors, a `ColorGradient` or a `ColorPalette`.
If `values` is an integer, it specifies the numbers of colors chosen equidistantly from the colorscheme specified by colors.
Otherwise vectors are accepted.
For continuous color gradients `values` indicate where between 0 and 1 the colors are positioned.
For categorical color gradients `values` indicate where a color ends and where a new one begins between 0 and 1.
0 and 1 are added to `values` if not already present.

If `rev` is `true` colors are reversed.
`scale` accepts the symbols `:log`, `:log10`, `:log2`, `:ln`, `:exp`, `:exp10` or functions.
If `alpha` is set, it is applied to all colors.
"""</span>


<span class="hljs-string">"""
palette(colors, [n]; rev = false, alpha = nothing)

Construct a `ColorPalette`.
Accepts symbols for Colorschemes.jl `ColorScheme`s, `ColorScheme`s, vectors of colors, `ColorGradient`s and `ColorPalettes`.
If 'n' is provided, `n` colors are chosen equidistantly from the colorscheme.
If `rev` is `true` colors are reversed.
"""</span>
</code></pre>
<pre><code class="lang-julia"><span class="hljs-comment"># https://juliagraphics.github.io/ColorSchemes.jl/stable/</span>
] add ColorSchemes

<span class="hljs-keyword">using</span> ColorSchemes

ColorSchemes.Purples_5 
<span class="hljs-comment"># =&gt; a ColorScheme </span>

colorschemes[:Purples_5]
<span class="hljs-comment"># =&gt; a ColorScheme </span>

ColorSchemes.Purples_5.colors
<span class="hljs-comment"># =&gt; array of five RGB colors</span>

ColorSchemes.Purples_5.colors[<span class="hljs-number">3</span>]
<span class="hljs-comment"># =&gt; the third color in the colorscheme</span>

get(ColorSchemes.Purples_5, <span class="hljs-number">0.5</span>)
<span class="hljs-comment"># =&gt; the midway point of the colorscheme</span>

colorschemes
<span class="hljs-comment"># =&gt; Dict{Symbol, ColorScheme} with 983 entries</span>

findcolorscheme(<span class="hljs-string">"purple"</span>)
<span class="hljs-comment"># =&gt; display list of matching schemes</span>
</code></pre>
<pre><code class="lang-julia"><span class="hljs-comment"># https://juliagraphics.github.io/ColorSchemeTools.jl/stable/makingschemes/</span>
roygbiv = [
    <span class="hljs-string">colorant"red"</span>,
    <span class="hljs-string">colorant"orange"</span>,
    <span class="hljs-string">colorant"yellow"</span>,
    <span class="hljs-string">colorant"green"</span>,
    <span class="hljs-string">colorant"blue"</span>,
    <span class="hljs-string">colorant"indigo"</span>,
    <span class="hljs-string">colorant"violet"</span>
]
scheme = make_colorscheme(roygbiv, <span class="hljs-number">10</span>)

<span class="hljs-comment"># You can supply the colors in any format, as long as it's a Colorant:</span>
cols = <span class="hljs-built_in">Any</span>[
    RGB(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>),
    Gray(<span class="hljs-number">0.5</span>),
    HSV(<span class="hljs-number">50.</span>, <span class="hljs-number">0.7</span>, <span class="hljs-number">1.</span>),
    Gray(<span class="hljs-number">0.4</span>),
    LCHab(<span class="hljs-number">54</span>, <span class="hljs-number">105</span>, <span class="hljs-number">40</span>),
    HSV(<span class="hljs-number">285.</span>, <span class="hljs-number">0.9</span>, <span class="hljs-number">0.8</span>),
    <span class="hljs-string">colorant"#FFEEFF"</span>,
    <span class="hljs-string">colorant"hotpink"</span>,
]
scheme = make_colorscheme(cols, <span class="hljs-number">8</span>)
</code></pre>
<p>Color attributes</p>
<p>color=theme(scene, :linecolor) sets the color of the line. If no color is set, multiple calls to line! will cycle through the axis color palette. Otherwise, one can set one color per line point by passing a Vector{&lt;:Colorant}, or one colorant for the whole line. If color is a vector of numbers, the colormap args are used to map the numbers to colors.</p>
<p>cycle::Vector{Symbol} = [:color] sets which attributes to cycle when creating multiple plots.</p>
<p>colormap::Union{Symbol, Vector{&lt;:Colorant}} = :viridis sets the colormap that is sampled for numeric colors. PlotUtils.cgrad(...), Makie.Reverse(any_colormap) can be used as well, or any symbol from ColorBrewer or PlotUtils. To see all available color gradients, you can call Makie.available_gradients().</p>
<p>colorscale::Function = identity color transform function. Can be any function, but only works well together with Colorbar for identity, log, log2, log10, sqrt, logit, Makie.pseudolog10 and Makie.Symlog10.</p>
<p>colorrange::Tuple{&lt;:Real, &lt;:Real} sets the values representing the start and end points of colormap.</p>
<p>nan_color::Union{Symbol, &lt;:Colorant} = RGBAf(0,0,0,0) sets a replacement color for color = NaN.</p>
<p>lowclip::Union{Nothing, Symbol, &lt;:Colorant} = nothing sets a color for any value below the colorrange.</p>
<p>highclip::Union{Nothing, Symbol, &lt;:Colorant} = nothing sets a color for any value above the colorrange.</p>
<p>alpha = 1.0 sets the alpha value of the colormap or color attribute. Multiple alphas like in plot(alpha=0.2, color=(:red, 0.5), will get multiplied.</p>
]]></content:encoded></item><item><title><![CDATA[How to use the CDS API with curl]]></title><description><![CDATA[The Climate Data Store (CDS) Application Program Interface (API) is a service providing programmatic access to CDS data like ERA5.
ERA5 is the fifth generation ECMWF reanalysis for the global climate and weather for the past 8 decades. Data is availa...]]></description><link>https://blog.iread.fun/how-to-use-the-cds-api-with-curl</link><guid isPermaLink="true">https://blog.iread.fun/how-to-use-the-cds-api-with-curl</guid><category><![CDATA[ERA5]]></category><category><![CDATA[CDSAPI]]></category><category><![CDATA[GRIB2]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Tue, 16 Apr 2024 15:21:52 GMT</pubDate><content:encoded><![CDATA[<p>The <strong>Climate Data Store (CDS) Application Program Interface (</strong><a target="_blank" href="https://cds.climate.copernicus.eu/api-how-to"><strong>API</strong></a><strong>)</strong> is a service providing programmatic access to CDS data like <strong>ERA5</strong>.</p>
<p><a target="_blank" href="https://cds.climate.copernicus.eu/cdsapp#!/dataset/reanalysis-era5-single-levels?tab=overview"><strong>ERA5</strong></a> is the fifth generation ECMWF reanalysis for the global climate and weather for the past 8 decades. Data is available from 1940 onwards. ERA5 replaces the ERA-Interim reanalysis.</p>
<p>The CDS has provided a python based <a target="_blank" href="https://github.com/ecmwf/cdsapi">API client library</a> <code>cdsapi</code>. It provides support for both Python 2.7.x and Python 3.</p>
<h2 id="heading-python-cdsapi-single-levels-example">Python cdsapi single levels example</h2>
<blockquote>
<p>code from <a target="_blank" href="https://cds.climate.copernicus.eu/cdsapp#!/dataset/reanalysis-era5-single-levels?tab=form">https://cds.climate.copernicus.eu/cdsapp#!/dataset/reanalysis-era5-single-levels?tab=form</a></p>
</blockquote>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> cdsapi

c = cdsapi.Client()

c.retrieve(
    <span class="hljs-string">'reanalysis-era5-single-levels'</span>,
    {
        <span class="hljs-string">'product_type'</span>: <span class="hljs-string">'reanalysis'</span>,
        <span class="hljs-string">'format'</span>: <span class="hljs-string">'grib'</span>,
        <span class="hljs-string">'variable'</span>: [
            <span class="hljs-string">'2m_dewpoint_temperature'</span>, <span class="hljs-string">'2m_temperature'</span>, <span class="hljs-string">'convective_available_potential_energy'</span>,
            <span class="hljs-string">'convective_precipitation'</span>, <span class="hljs-string">'large_scale_precipitation'</span>, <span class="hljs-string">'mean_sea_level_pressure'</span>,
            <span class="hljs-string">'total_precipitation'</span>,
        ],
        <span class="hljs-string">'year'</span>: <span class="hljs-string">'2024'</span>,
        <span class="hljs-string">'month'</span>: [
            <span class="hljs-string">'03'</span>, <span class="hljs-string">'04'</span>,
        ],
        <span class="hljs-string">'day'</span>: [
            <span class="hljs-string">'01'</span>, <span class="hljs-string">'02'</span>, <span class="hljs-string">'30'</span>,
            <span class="hljs-string">'31'</span>,
        ],
        <span class="hljs-string">'time'</span>: [
            <span class="hljs-string">'00:00'</span>, <span class="hljs-string">'01:00'</span>, <span class="hljs-string">'02:00'</span>,
            <span class="hljs-string">'03:00'</span>, <span class="hljs-string">'04:00'</span>, <span class="hljs-string">'05:00'</span>,
            <span class="hljs-string">'06:00'</span>, <span class="hljs-string">'07:00'</span>, <span class="hljs-string">'08:00'</span>,
            <span class="hljs-string">'09:00'</span>, <span class="hljs-string">'10:00'</span>, <span class="hljs-string">'11:00'</span>,
            <span class="hljs-string">'12:00'</span>, <span class="hljs-string">'13:00'</span>, <span class="hljs-string">'14:00'</span>,
            <span class="hljs-string">'15:00'</span>, <span class="hljs-string">'16:00'</span>, <span class="hljs-string">'17:00'</span>,
            <span class="hljs-string">'18:00'</span>, <span class="hljs-string">'19:00'</span>, <span class="hljs-string">'20:00'</span>,
            <span class="hljs-string">'21:00'</span>, <span class="hljs-string">'22:00'</span>, <span class="hljs-string">'23:00'</span>,
        ],
        <span class="hljs-string">'area'</span>: [
            <span class="hljs-number">50</span>, <span class="hljs-number">90</span>, <span class="hljs-number">20</span>,
            <span class="hljs-number">120</span>,
        ],
    },
    <span class="hljs-string">'download.grib'</span>)
</code></pre>
<h2 id="heading-python-cdsapi-pressure-levels-example">Python cdsapi pressure levels example</h2>
<blockquote>
<p>code from <a target="_blank" href="https://cds.climate.copernicus.eu/cdsapp#!/dataset/reanalysis-era5-pressure-levels?tab=form">https://cds.climate.copernicus.eu/cdsapp#!/dataset/reanalysis-era5-pressure-levels?tab=form</a></p>
</blockquote>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> cdsapi

c = cdsapi.Client()

c.retrieve(
    <span class="hljs-string">'reanalysis-era5-pressure-levels'</span>,
    {
        <span class="hljs-string">'product_type'</span>: <span class="hljs-string">'reanalysis'</span>,
        <span class="hljs-string">'format'</span>: <span class="hljs-string">'grib'</span>,
        <span class="hljs-string">'pressure_level'</span>: [
            <span class="hljs-string">'500'</span>, <span class="hljs-string">'700'</span>,
        ],
        <span class="hljs-string">'year'</span>: <span class="hljs-string">'2024'</span>,
        <span class="hljs-string">'month'</span>: [
            <span class="hljs-string">'03'</span>, <span class="hljs-string">'04'</span>,
        ],
        <span class="hljs-string">'day'</span>: [
            <span class="hljs-string">'01'</span>, <span class="hljs-string">'02'</span>, <span class="hljs-string">'30'</span>,
            <span class="hljs-string">'31'</span>,
        ],
        <span class="hljs-string">'time'</span>: [
            <span class="hljs-string">'00:00'</span>, <span class="hljs-string">'01:00'</span>, <span class="hljs-string">'02:00'</span>,
            <span class="hljs-string">'03:00'</span>, <span class="hljs-string">'04:00'</span>, <span class="hljs-string">'05:00'</span>,
            <span class="hljs-string">'06:00'</span>, <span class="hljs-string">'07:00'</span>, <span class="hljs-string">'08:00'</span>,
            <span class="hljs-string">'09:00'</span>, <span class="hljs-string">'10:00'</span>, <span class="hljs-string">'11:00'</span>,
            <span class="hljs-string">'12:00'</span>, <span class="hljs-string">'13:00'</span>, <span class="hljs-string">'14:00'</span>,
            <span class="hljs-string">'15:00'</span>, <span class="hljs-string">'16:00'</span>, <span class="hljs-string">'17:00'</span>,
            <span class="hljs-string">'18:00'</span>, <span class="hljs-string">'19:00'</span>, <span class="hljs-string">'20:00'</span>,
            <span class="hljs-string">'21:00'</span>, <span class="hljs-string">'22:00'</span>, <span class="hljs-string">'23:00'</span>,
        ],
        <span class="hljs-string">'area'</span>: [
            <span class="hljs-number">50</span>, <span class="hljs-number">90</span>, <span class="hljs-number">20</span>,
            <span class="hljs-number">120</span>,
        ],
        <span class="hljs-string">'variable'</span>: [
            <span class="hljs-string">'divergence'</span>, <span class="hljs-string">'geopotential'</span>,
        ],
    },
    <span class="hljs-string">'download.grib'</span>)
</code></pre>
<p>We can also use the CDS API without Python. Here I will show you how to use the CDS API with curl to download ERA5 data.</p>
<h2 id="heading-check-api-status">Check API status</h2>
<pre><code class="lang-bash">curl https://cds.climate.copernicus.eu/api/v2/status.json

{
    <span class="hljs-string">"info"</span>: [<span class="hljs-string">"Welcome to the CDS"</span>],
    <span class="hljs-string">"warning"</span>: []
}
</code></pre>
<h2 id="heading-authorization-required">Authorization Required</h2>
<pre><code class="lang-bash">curl -X POST -H <span class="hljs-string">"Content-Type: application/json"</span> 
    https://cds.climate.copernicus.eu/api/v2/resources/reanalysis-era5-pressure-levels

&lt;html&gt;
&lt;head&gt;&lt;title&gt;401 Authorization Required&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
&lt;center&gt;&lt;h1&gt;401 Authorization Required&lt;/h1&gt;&lt;/center&gt;
&lt;hr&gt;&lt;center&gt;nginx/1.20.2&lt;/center&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<blockquote>
<ol>
<li><p>If you don't have an account, please self register at the <a target="_blank" href="https://cds.climate.copernicus.eu/user/register?destination=%2F%23!%2Fhome">CDS registration</a> <a target="_blank" href="https://cds.climate.copernicus.eu/user/register?destination=%2F%23!%2Fhome">page and go to t</a>he steps below.</p>
</li>
<li><p>If you are not logged, please <a target="_blank" href="https://cds.climate.copernicus.eu/user/login?destination=%2F%23!%2Fhome">login</a> <a target="_blank" href="https://cds.climate.copernicus.eu/user/login?destination=%2F%23!%2Fhome">and g</a>o to the step below.</p>
</li>
<li><p>Copy the key displayed at <a target="_blank" href="https://cds.climate.copernicus.eu/api-how-to">https://cds.climate.copernicus.eu/api-how-to</a></p>
</li>
</ol>
</blockquote>
<h2 id="heading-agreed-to-the-required-terms-and-conditions">Agreed to the required terms and conditions</h2>
<pre><code class="lang-bash">curl -X POST -H <span class="hljs-string">"Content-Type: application/json"</span> 
    -u 123456:2d0b6cac-e6cb-4d1b-85df-1234560f4dd6 
    -d <span class="hljs-string">'{ "variable": "temperature", "pressure_level": "1000", "product_type": "reanalysis", "date": "2017-12-01/2017-12-02", "time": "12:00", "format": "grib" }'</span> 
    https://cds.climate.copernicus.eu/api/v2/resources/reanalysis-era5-pressure-levels

{
  <span class="hljs-string">"message"</span>: <span class="hljs-string">"Client has not agreed to the required terms and conditions."</span>,
  <span class="hljs-string">"url"</span>: <span class="hljs-string">"http://copernicus-climate.eu/exc/missing-terms"</span>,
  <span class="hljs-string">"reason"</span>: <span class="hljs-string">"Client has not agreed to the required terms and conditions."</span>,
  <span class="hljs-string">"context"</span>: {
    <span class="hljs-string">"required_terms"</span>: [{
      <span class="hljs-string">"title"</span>: <span class="hljs-string">"Licence to use Copernicus Products"</span>,
      <span class="hljs-string">"url"</span>: <span class="hljs-string">"https://cds.climate.copernicus.eu/cdsapp/#!/terms/licence-to-use-copernicus-products"</span>,
      <span class="hljs-string">"reason"</span>: <span class="hljs-string">"missing"</span>
    }]
  },
  <span class="hljs-string">"permanent"</span>: <span class="hljs-literal">false</span>,
  <span class="hljs-string">"who"</span>: <span class="hljs-string">"client"</span>
}
</code></pre>
<p>To access this resource, you first need to accept the terms of "Licence to use Copernicus Products" at <a target="_blank" href="https://cds.climate.copernicus.eu/cdsapp/#!/terms/licence-to-use-copernicus-products">https://cds.climate.copernicus.eu/cdsapp/#!/terms/licence-to-use-copernicus-products</a></p>
<h2 id="heading-request-will-queued">Request will queued</h2>
<pre><code class="lang-bash">curl -X POST -H <span class="hljs-string">"Content-Type: application/json"</span> 
    -u 123456:2d0b6cac-e6cb-4d1b-85df-1234560f4dd6 
    -d <span class="hljs-string">'{ "variable": "temperature", "pressure_level": "1000", "product_type": "reanalysis", "date": "2017-12-01/2017-12-02", "time": "12:00", "format": "grib" }'</span> 
    https://cds.climate.copernicus.eu/api/v2/resources/reanalysis-era5-pressure-levels

{
  <span class="hljs-string">"state"</span>: <span class="hljs-string">"queued"</span>,
  <span class="hljs-string">"request_id"</span>: <span class="hljs-string">"baa0698c-b035-4ace-a463-a3ba4639df69"</span>,
  <span class="hljs-string">"specific_metadata_json"</span>: {
    <span class="hljs-string">"top_request_origin"</span>: <span class="hljs-string">"api"</span>
  }
}
</code></pre>
<h2 id="heading-check-requestid-state">Check request_id state</h2>
<pre><code class="lang-bash">curl -u 123456:2d0b6cac-e6cb-4d1b-85df-1234560f4dd6 
    https://cds.climate.copernicus.eu/api/v2/tasks/baa0698c-b035-4ace-a463-a3ba4639df69

{
  <span class="hljs-string">"state"</span>: <span class="hljs-string">"completed"</span>,
  <span class="hljs-string">"request_id"</span>: <span class="hljs-string">"baa0698c-b035-4ace-a463-a3ba4639df69"</span>,
  <span class="hljs-string">"location"</span>: <span class="hljs-string">"https://download-0001-clone.copernicus-climate.eu/cache-compute-0001/cache/data6/adaptor.mars.internal-1713276220.7536583-952-1-baa0698c-b035-4ace-a463-a3ba4639df69.grib"</span>,
  <span class="hljs-string">"content_length"</span>: 4153200,
  <span class="hljs-string">"content_type"</span>: <span class="hljs-string">"application/x-grib"</span>,
  <span class="hljs-string">"sent_to_rmq_at"</span>: <span class="hljs-string">"2024-04-16T14:03:40.448Z"</span>,
  <span class="hljs-string">"specific_metadata_json"</span>: {
    <span class="hljs-string">"top_request_origin"</span>: <span class="hljs-string">"api"</span>
  }
}
</code></pre>
<h2 id="heading-download-the-file-at-location">Download the file at location</h2>
<pre><code class="lang-bash">curl -o era5-test.grib https://download-0001-clone.copernicus-climate.eu/cache-compute-0001/cache/data6/adaptor.mars.inter
nal-1713276220.7536583-952-1-baa0698c-b035-4ace-a463-a3ba4639df69.grib
</code></pre>
<p>That's all!</p>
]]></content:encoded></item><item><title><![CDATA[Julia Notes Day5 -- REPL help/pkg/search mode and Depot]]></title><description><![CDATA[Install Julia
All official Julia binaries produce portable installations. Once installed, the directory in which Julia was installed can be moved to a different location on the same computer, or even to a different computer.
wget https://julialang-s3...]]></description><link>https://blog.iread.fun/julia-notes-day5-repl-helppkgsearch-mode-and-depot</link><guid isPermaLink="true">https://blog.iread.fun/julia-notes-day5-repl-helppkgsearch-mode-and-depot</guid><category><![CDATA[Julia]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Sat, 23 Mar 2024 10:17:58 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-install-julia">Install Julia</h2>
<p>All official Julia binaries produce portable installations. Once installed, the directory in which Julia was installed can be moved to a different location on the same computer, or even to a different computer.</p>
<pre><code class="lang-bash">wget https://julialang-s3.julialang.org/bin/linux/x64/1.10/julia-1.10.2-linux-x86_64.tar.gz
tar zxvf julia-1.10.2-linux-x86_64.tar.gz
</code></pre>
<p>The generic Linux and FreeBSD binaries do not require any special installation steps, but you will need to ensure that your system can find the <code>julia</code> executable. The directory where Julia is installed is referred to as <code>&lt;Julia directory&gt;</code>.</p>
<p>To run Julia, you can do any of the following:</p>
<ul>
<li><p>Invoke the <code>julia</code> executable by using its full path: <code>&lt;Julia directory&gt;/bin/julia</code></p>
</li>
<li><p>Create a symbolic link to <code>julia</code> inside a folder which is on your system <code>PATH</code></p>
</li>
<li><p>Add Julia's <code>bin</code> folder (with full path) to your system <code>PATH</code> environment variable</p>
</li>
</ul>
<p>To add Julia's <code>bin</code> folder (with full path) to <code>PATH</code> environment variable, you can edit the <code>~/.bashrc</code> (or <code>~/.bash_profile</code>) file. Open the file in your favourite editor and add a new line as follows:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">export</span> PATH=<span class="hljs-string">"<span class="hljs-variable">$PATH</span>:/workspace/empty/julia-1.10.2/bin"</span>
</code></pre>
<h2 id="heading-repl">REPL</h2>
<p>The easiest way to learn and experiment with Julia is by starting an interactive session (also known as a read-eval-print loop or "REPL") by double-clicking the Julia executable or running <code>julia</code> from the command line:</p>
<pre><code class="lang-julia">$ julia

               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  <span class="hljs-built_in">Type</span> <span class="hljs-string">"?"</span> <span class="hljs-keyword">for</span> help, <span class="hljs-string">"]?"</span> <span class="hljs-keyword">for</span> Pkg help.
  | | | | | | |/ _<span class="hljs-string">` |  |
  | | |_| | | | (_| |  |  Version 1.10.2 (2024-03-01)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |


julia&gt; 1 + 2
3

julia&gt; ans
3</span>
</code></pre>
<h3 id="heading-julian-mode">julian mode</h3>
<p>The REPL has five main modes of operation. The first and most common is the Julian prompt. It is the default mode of operation; each new line initially starts with <code>julia&gt;</code>. It is here that you can enter Julia expressions. Hitting return or enter after a complete expression has been entered will evaluate the entry and show the result of the last expression.</p>
<h3 id="heading-help-mode">help mode</h3>
<p>You can use the REPL as a learning resource by switching into the help mode. Switch to help mode by pressing <code>?</code> at an empty <code>julia&gt;</code> prompt, before typing anything else. Typing a keyword in help mode will fetch the documentation for it, along with examples.</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">using</span> UnicodePlots

help?&gt; lineplot
search: lineplot lineplot!

  lineplot(; kw...)
  lineplot(y; kw...)
  lineplot(x, y; kw...)
  lineplot!(p, args...; kw...)

  Description
  ≡≡≡≡≡≡≡≡≡≡≡

  Draws a path through the given points on a new canvas.

  The first (optional) vector x should contain the horizontal positions <span class="hljs-keyword">for</span> all the points along the path. The second
  vector y should then contain the corresponding vertical positions respectively. This means that the two vectors must be
  of the same length and ordering.

  Usage
  ≡≡≡≡≡

  lineplot([x], y; head_tail = <span class="hljs-literal">nothing</span>, ..., name = <span class="hljs-string">""</span>)
  lineplot([start], [stop], fun; kw...)

  Arguments
  ≡≡≡≡≡≡≡≡≡

    •  fun : a unary <span class="hljs-keyword">function</span> f: R -&gt; R that should be evaluated, and drawn as a path from start to stop (numbers <span class="hljs-keyword">in</span>
       the domain).

    •  head_tail : color the line head and/or tail with the complement of the chosen color (:head, :tail, :both).

    •  head_tail_frac : fraction of the arrow head or tail (<span class="hljs-literal">e</span>.g. provide <span class="hljs-number">0.1</span> <span class="hljs-keyword">for</span> <span class="hljs-number">10</span>%).

    •  x : horizontal position <span class="hljs-keyword">for</span> each point (can be a real number or of <span class="hljs-keyword">type</span> TimeType), <span class="hljs-keyword">if</span> omitted, the axes of y
       will be used as x.

    •  format : specify the ticks date format (TimeType only).

    •  color::<span class="hljs-built_in">Symbol</span> = :auto : <span class="hljs-built_in">Vector</span> of colors, or scalar - choose from (:green, :blue, :red, :yellow, :cyan,
       :magenta, :white, :normal, :auto), use an integer <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>-<span class="hljs-number">255</span>], or provide <span class="hljs-number">3</span> integers as RGB components.

    •  y : vertical position <span class="hljs-keyword">for</span> each point.

    •  title::<span class="hljs-built_in">String</span> = <span class="hljs-string">""</span> : text displayed on top of the plot.

    •  name::<span class="hljs-built_in">String</span> = <span class="hljs-string">""</span> : current drawing annotation displayed on the right.

    •  xlabel::<span class="hljs-built_in">String</span> = <span class="hljs-string">""</span> : text displayed on the x axis of the plot.

    •  ylabel::<span class="hljs-built_in">String</span> = <span class="hljs-string">""</span> : text displayed on the y axis of the plot.

    •  xscale::<span class="hljs-built_in">Symbol</span> = :identity : x-axis scale (:identity, :ln, :log2, :log10), or scale <span class="hljs-keyword">function</span> <span class="hljs-literal">e</span>.g. x -&gt;
       log10(x).

    •  yscale::<span class="hljs-built_in">Symbol</span> = :identity : y-axis scale.

    •  labels::<span class="hljs-built_in">Bool</span> = <span class="hljs-literal">true</span> : show plot labels.

    •  border::<span class="hljs-built_in">Symbol</span> = :solid : plot bounding box style (:corners, :solid, :bold, :dashed, :dotted, :ascii, :none).

    •  margin::<span class="hljs-built_in">Int</span> = <span class="hljs-number">3</span> : number of empty characters to the left of the whole plot.

    •  padding::<span class="hljs-built_in">Int</span> = <span class="hljs-number">1</span> : left and right space between the labels and the canvas.

    •  height::<span class="hljs-built_in">Int</span> = <span class="hljs-number">15</span> : number of canvas rows, or :auto.

    •  width::<span class="hljs-built_in">Int</span> = <span class="hljs-number">40</span> : number of characters per canvas row, or :auto.

    •  xlim::<span class="hljs-built_in">Tuple</span> = (<span class="hljs-number">0</span>, <span class="hljs-number">0</span>) : plotting range <span class="hljs-keyword">for</span> the x axis ((<span class="hljs-number">0</span>, <span class="hljs-number">0</span>) stands <span class="hljs-keyword">for</span> automatic).

    •  ylim::<span class="hljs-built_in">Tuple</span> = (<span class="hljs-number">0</span>, <span class="hljs-number">0</span>) : plotting range <span class="hljs-keyword">for</span> the y axis.

    •  xflip::<span class="hljs-built_in">Bool</span> = <span class="hljs-literal">false</span> : set <span class="hljs-literal">true</span> to flip the x axis.

    •  yflip::<span class="hljs-built_in">Bool</span> = <span class="hljs-literal">false</span> : set <span class="hljs-literal">true</span> to flip the y axis.

    •  canvas::<span class="hljs-built_in">UnionAll</span> = UnicodePlots.BrailleCanvas : <span class="hljs-keyword">type</span> of canvas used <span class="hljs-keyword">for</span> drawing.

    •  grid::<span class="hljs-built_in">Bool</span> = <span class="hljs-literal">true</span> : draws grid-lines at the origin.

    •  compact::<span class="hljs-built_in">Bool</span> = <span class="hljs-literal">false</span> : compact plot labels.

    •  unicode_exponent::<span class="hljs-built_in">Bool</span> = <span class="hljs-literal">true</span> : use Unicode symbols <span class="hljs-keyword">for</span> exponents: <span class="hljs-literal">e</span>.g. <span class="hljs-number">10</span>²⸱¹ instead of <span class="hljs-number">10</span>^<span class="hljs-number">2.1</span>.

    •  blend::<span class="hljs-built_in">Bool</span> = <span class="hljs-literal">true</span> : blend colors on the underlying canvas.

  Author(s)
  ≡≡≡≡≡≡≡≡≡

    •  Christof Stocker (github.com/Evizero)

    •  Milktrader (github.com/milktrader)

  Examples
  ≡≡≡≡≡≡≡≡

  julia&gt; lineplot([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">7</span>], [<span class="hljs-number">9</span>, -<span class="hljs-number">6</span>, <span class="hljs-number">8</span>]; title = <span class="hljs-string">"My Lineplot"</span>)
         ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀My Lineplot⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
         ┌────────────────────────────────────────────────┐ 
      <span class="hljs-number">10</span> │⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀ ⠀⠀⠀│ 
         │⢇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠│ 
         │⠘⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠤⠊⠁⠀│ 
         │⠀⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠔⠊⠁⠀⠀⠀⠀│ 
         │⠀⠈⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠔⠊⠀⠀⠀⠀⠀⠀⠀⠀│ 
         │⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠔⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ 
         │⠀⠀⠀⢇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠒⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ 
         │⠤⠤⠤⠼⡤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⢤⠤⠶⠥⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤│ 
         │⠀⠀⠀⠀⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠤⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ 
         │⠀⠀⠀⠀⠈⡆⠀⠀⠀⠀⠀⠀⠀⣀⠔⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ 
         │⠀⠀⠀⠀⠀⢱⠀⠀⠀⠀⡠⠔⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ 
         │⠀⠀⠀⠀⠀⠀⢇⡠⠔⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ 
         │⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀│ 
         │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀│ 
     -<span class="hljs-number">10</span> │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀│ 
         └────────────────────────────────────────────────┘ 
         ⠀<span class="hljs-number">1</span>⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀<span class="hljs-number">7</span>⠀ 

  See also
  ≡≡≡≡≡≡≡≡

  Plot, scatterplot, stairs, BrailleCanvas, BlockCanvas, AsciiCanvas, DotCanvas
</code></pre>
<h3 id="heading-pkg-mode">pkg mode</h3>
<p>The Package manager mode accepts specialized commands for loading and updating packages. It is entered by pressing the <code>]</code> key at the Julian REPL prompt and exited by pressing CTRL-C or pressing the backspace key at the beginning of the line. The prompt for this mode is <code>pkg&gt;</code>. It supports its own help-mode, which is entered by pressing <code>?</code> at the beginning of the line of the <code>pkg&gt;</code> prompt. The Package manager mode is documented in the Pkg manual, available at <a target="_blank" href="https://julialang.github.io/Pkg.jl/v1/">https://julialang.github.io/Pkg.jl/v1/</a>.</p>
<h3 id="heading-shell-mode">shell mode</h3>
<p>Just as help mode is useful for quick access to documentation, another common task is to use the system shell to execute system commands. Just as <code>?</code> entered help mode when at the beginning of the line, a semicolon (<code>;</code>) will enter the shell mode. And it can be exited by pressing backspace at the beginning of the line.</p>
<h3 id="heading-search-mode">search mode</h3>
<p>In all of the above modes, the executed lines get saved to a history file, which can be searched. To initiate an incremental search through the previous history, type <code>^R</code> – the control key together with the <code>r</code> key. The prompt will change to <code>(reverse-i-search)`':</code>, and as you type the search query will appear in the quotes. The most recent result that matches the query will dynamically update to the right of the colon as more is typed. To find an older result using the same query, simply type <code>^R</code> again.</p>
<p>Just as <code>^R</code> is a reverse search, <code>^S</code> is a forward search, with the prompt <code>(i-search)`':</code>. The two may be used in conjunction with each other to move through the previous or next matching results, respectively.</p>
<h2 id="heading-depot-directory">Depot Directory</h2>
<p>The <code>JULIA_DEPOT_PATH</code> environment variable is used to populate the global Julia <code>DEPOT_PATH</code> variable, which controls where the package manager, as well as Julia's code loading mechanisms, look for package registries, installed packages, named environments, repo clones, cached compiled package images, configuration files, and the default location of the REPL's history file.</p>
<p>Here is an overview of some of the subdirectories that may exist in a depot:</p>
<ul>
<li><p><code>compiled</code>: Contains precompiled <code>*.ji</code> files for packages. Maintained by Julia.</p>
</li>
<li><p><code>environments</code>: Default package environments. For instance the global environment for a specific julia version. Maintained by <code>Pkg.jl</code>.</p>
</li>
<li><p><code>logs</code>: Contains logs of <code>Pkg</code> and <code>REPL</code> operations. Maintained by <code>Pkg.jl</code> and <code>Julia</code>.</p>
</li>
<li><p><code>packages</code>: Contains packages, some of which were explicitly installed and some which are implicit dependencies. Maintained by <code>Pkg.jl</code>.</p>
</li>
<li><p><code>registries</code>: Contains package registries. By default only <code>General</code>. Maintained by <code>Pkg.jl</code>.</p>
</li>
<li><p><code>scratchspaces</code>: Contains content that a package itself installs via the <code>Scratch.jl</code> package. <code>Pkg.gc()</code> will delete content that is known to be unused.</p>
</li>
</ul>
<pre><code class="lang-bash"><span class="hljs-built_in">export</span> JULIA_DEPOT_PATH=<span class="hljs-string">"/workspace/empty/depot"</span>
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Julia Notes Day4 -- Module,Package and Environment]]></title><description><![CDATA[Module
Modules in Julia help organize code into coherent units. They are delimited syntactically inside module NameOfModule ... end.Typically, in larger Julia packages you will see module code organized into files, eg
module SomeModule

# export, usi...]]></description><link>https://blog.iread.fun/julia-notes-day4-module-package-and-environment</link><guid isPermaLink="true">https://blog.iread.fun/julia-notes-day4-module-package-and-environment</guid><category><![CDATA[Julia]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Tue, 19 Mar 2024 09:55:51 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-module">Module</h2>
<p>Modules in Julia help organize code into coherent units. They are delimited syntactically inside <code>module NameOfModule ... end</code>.Typically, in larger Julia packages you will see module code organized into files, eg</p>
<pre><code class="lang-julia"><span class="hljs-keyword">module</span> SomeModule

<span class="hljs-comment"># export, using, import statements are usually here; we discuss these below</span>

include(<span class="hljs-string">"file1.jl"</span>)
include(<span class="hljs-string">"file2.jl"</span>)

<span class="hljs-keyword">end</span>
</code></pre>
<p>Files and file names are mostly unrelated to modules; modules are associated only with module expressions. One can have multiple files per module, and multiple modules per file. <code>include</code> behaves as if the contents of the source file were evaluated in the global scope of the including module.</p>
<pre><code class="lang-julia"><span class="hljs-comment"># math.jl</span>
<span class="hljs-keyword">module</span> SomeModuleMath
<span class="hljs-keyword">export</span> add

add(x, y=<span class="hljs-number">5</span>) = x + y
<span class="hljs-keyword">end</span>
</code></pre>
<p>To load a module from a package, the statement <code>using ModuleName</code> can be used. To load a module from a locally defined module, a dot needs to be added before the module name like <code>using .ModuleName</code>.</p>
<pre><code class="lang-julia"><span class="hljs-comment"># main1.jl</span>
include(<span class="hljs-string">"math.jl"</span>) <span class="hljs-comment"># first include file for locally defined module</span>
<span class="hljs-keyword">using</span> .SomeModuleMath

println(add(<span class="hljs-number">3</span>,<span class="hljs-number">3</span>))
</code></pre>
<p>In contrast, <code>import</code> brings <em>only</em> the module name into scope.</p>
<p>An identifier brought into scope by <code>import</code> or <code>using</code> can be renamed with the keyword <code>as</code>. This is useful for working around name conflicts as well as for shortening names.</p>
<pre><code class="lang-julia"><span class="hljs-comment"># main2.jl</span>
include(<span class="hljs-string">"math.jl"</span>) <span class="hljs-comment"># first include file for locally defined module</span>
<span class="hljs-keyword">import</span> .SomeModuleMath as MyMath

println(MyMath.add(<span class="hljs-number">5</span>,<span class="hljs-number">3</span>))
</code></pre>
<h2 id="heading-package">Package</h2>
<p>Pkg is Julia's package manager.</p>
<p>Pkg comes with a REPL. Enter the Pkg REPL by pressing <code>]</code> from the Julia REPL. To get back to the Julia REPL, press <code>Ctrl+C</code> or backspace (when the REPL cursor is at the beginning of the input).</p>
<p>To add a package, use <code>add</code>:</p>
<pre><code class="lang-julia">(<span class="hljs-meta">@v1</span><span class="hljs-number">.10</span>) pkg&gt; add UnicodePlots
</code></pre>
<p>After the package is installed, it can be loaded into the Julia session:</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">using</span> UnicodePlots

julia&gt; lineplot(-<span class="hljs-literal">π</span>/<span class="hljs-number">2</span>, <span class="hljs-number">2</span><span class="hljs-literal">π</span>, [cos, sin])
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1710840603832/32964a80-a454-429e-89fc-523de8f80b59.png" alt /></p>
<p>The <code>status</code> command (or the shorter <code>st</code> command) can be used to see installed packages.</p>
<p>To remove packages, use <code>rm</code> (or <code>remove</code>).</p>
<p>Use <code>up</code> (or <code>update</code>) to update the installed packages.</p>
<p>If a package is not in a registry, it can be added by specifying a URL to the Git repository:</p>
<pre><code class="lang-julia">(<span class="hljs-meta">@v1</span><span class="hljs-number">.10</span>) pkg&gt; add https://github.com/fredrikekre/ImportMacros.jl
</code></pre>
<h2 id="heading-environment">Environment</h2>
<p>You may have noticed the <code>(@v1.10)</code> in the REPL prompt. This lets us know that <code>v1.10</code> is the <strong>active environment</strong>. Different environments can have different totally different packages and versions installed from another environment. The active environment is the environment that will be modified by Pkg commands such as <code>add</code>, <code>rm</code> and <code>update</code>.</p>
<p>So far we have added packages to the default environment at <code>~/.julia/environments/v1.10</code>. It is however easy to create other, independent, projects. This approach has the benefit of allowing you to check in a <code>Project.toml</code>, and even a <code>Manifest.toml</code> if you wish, into version control (e.g. git) alongside your code.</p>
<h3 id="heading-active-environment">active environment</h3>
<p>In order to create a new project, create a directory for it and then activate that directory to make it the "active project", which package operations manipulate.</p>
<p>To set the active environment, use <code>activate</code>:</p>
<pre><code class="lang-julia">(<span class="hljs-meta">@v1</span><span class="hljs-number">.10</span>) pkg&gt; activate tutorial
[ Info: activating new environment at <span class="hljs-string">`~/tutorial/Project.toml`</span>.

(tutorial) pkg&gt;
</code></pre>
<p>We can ask for information about the active environment by using <code>status</code>.</p>
<blockquote>
<p>It should be pointed out that when two projects use the same package at the same version, the content of this package is not duplicated.</p>
</blockquote>
<p>If the project contains a manifest, this will install the packages in the same state that is given by that manifest. Otherwise, it will resolve the latest versions of the dependencies compatible with the project.</p>
<h3 id="heading-instantiate">instantiate</h3>
<p>Note that <code>activate</code> by itself does not install missing dependencies. If you only have a <code>Project.toml</code>, a <code>Manifest.toml</code> must be generated by "resolving" the environment, then any missing packages must be installed and precompiled. <code>instantiate</code> does all this for you.</p>
<p>If you already have a resolved <code>Manifest.toml</code>, then you will still need to ensure that the packages are installed and with the correct versions. Again <code>instantiate</code> does this for you.</p>
<p>In short, <code>instantiate</code> is your friend to make sure an environment is ready to use. If there's nothing to do, <code>instantiate</code> does nothing.</p>
<pre><code class="lang-julia">shell&gt; git clone https://github.com/JuliaLang/Example.jl.git
Cloning into 'Example.jl'...
...

(<span class="hljs-meta">@v1</span><span class="hljs-number">.10</span>) pkg&gt; activate Example.jl
Activating project at <span class="hljs-string">`~/Example.jl`</span>

(Example) pkg&gt; instantiate
  No Changes to <span class="hljs-string">`~/Example.jl/Project.toml`</span>
  No Changes to <span class="hljs-string">`~/Example.jl/Manifest.toml`</span>
</code></pre>
<h3 id="heading-shared-environment">shared environment</h3>
<p>A "shared" environment is simply an environment that exists in <code>~/.julia/environments</code>. The default <code>v1.10</code> environment is therefore a shared environment.</p>
<p>Shared environments can be activated with the <code>--shared</code> flag to <code>activate</code>:</p>
<pre><code class="lang-julia">(<span class="hljs-meta">@v1</span><span class="hljs-number">.10</span>) pkg&gt; activate --shared mysharedenv
  Activating project at <span class="hljs-string">`~/.julia/environments/mysharedenv`</span>

(<span class="hljs-meta">@mysharedenv</span>) pkg&gt;
</code></pre>
<h3 id="heading-precompile-package">precompile package</h3>
<p>By default, any package that is added to a project or updated in a Pkg action will be automatically precompiled, along with its dependencies.</p>
]]></content:encoded></item><item><title><![CDATA[How AI weather models like ECMWF-AIFS and GraphCast work]]></title><description><![CDATA[Original article: https://twitter.com/Brady_Wx/status/1769910256354627891


GraphCast: Learning skillful medium-range global weather forecasting

I see a lot of people posting false information about AI weather models like ECMWF-AIFS and GraphCast. T...]]></description><link>https://blog.iread.fun/how-ai-weather-models-like-ecmwf-aifs-and-graphcast-work</link><guid isPermaLink="true">https://blog.iread.fun/how-ai-weather-models-like-ecmwf-aifs-and-graphcast-work</guid><category><![CDATA[weather-model]]></category><category><![CDATA[AI]]></category><category><![CDATA[graph neural network]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Tue, 19 Mar 2024 08:58:55 GMT</pubDate><content:encoded><![CDATA[<p>Original article: <a target="_blank" href="https://twitter.com/Brady_Wx/status/1769910256354627891">https://twitter.com/Brady_Wx/status/1769910256354627891</a></p>
<blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1710839105274/2f803c12-69ba-4596-9ab7-7c3d235649d2.png" alt /></p>
<p><a target="_blank" href="https://arxiv.org/pdf/2212.12794.pdf">GraphCast: Learning skillful medium-range global weather forecasting</a></p>
</blockquote>
<p>I see a lot of people posting false information about AI weather models like ECMWF-AIFS and GraphCast. This is brand new technology, so misunderstandings are to be expected. I'll try to explain how they work in way that is simplified and easy to understand. This is a bit over-simplified, but should be sufficient to help weather enthusiasts, storm chasers, etc understand how these models work to an extent.</p>
<p>These models aren't weather models designed by AI. They aren't ChatGPT wrappers. In fact, they aren't even related to that "kind" of AI (Large Language Models). These models use a somewhat similar underlying 'architecture', but do not use human-like logic in any way. "Machine-Learning" is probably an easier way to understand these models than the term "AI".</p>
<p>So, briefly, I will describe how neural networks work in general.</p>
<h2 id="heading-problem">Problem</h2>
<p>Imagine you are trying to predict whether or not a severe thunderstorm is likely at a precise location (lets say Amarillo Tx), and you want to build an extremely basic neural network for this task. This basic neural network is called a multi-layer perceptrton (MLP).</p>
<h2 id="heading-features">Features</h2>
<p>Some features to consider at this location would be dew-point, srh, wind shear, cape.. we'll leave it at those 4 for this example. So our MLP will be taking the DP, srh, 500mb wind shear, and CAPE at this location and it will be <strong>outputting</strong> the probability of a severe thunderstorm. The model will need to somehow learn what combinations of DP,srh,ws, and cape generally mean severe thunderstorms and what combinations do not.</p>
<p>Let's say we've collected 100 data points for Amarillo Texas (so 100 days of data). In 50 of those, a severe thunderstorm happened, and in the other 50 there weren't any severe thunderstorms. So what we now have is 100 data points where each data point contains the DP, srh, 500mb wind shear, and CAPE in Amarillo on that day, as well as whether or not a severe thunderstorm occurred. So we have our training data and we are ready to feed into MLP.</p>
<h2 id="heading-model-hidden-layers">Model hidden layers</h2>
<p>The MLP will go datapoint-by-datapoint, for each datapoint the data will be input and will enter the first "hidden layer". In this hidden layer, the model applies some random multiplication (weights) and addition (bias) to each input, n number of times (the number of "neurons" in this hidden layer). Each neuron is then connected to the neurons in the next hidden layer. The number of hidden layers is the "depth" of the model and is customizable by the model engineer. More complex models require more neurons and more depth, to compensate for the complexity of the issue at hand.</p>
<p>In each hidden layer, the neurons from the previous layer are fully connected to the neurons of the current layer, weights (multiply) and biases (add) are applied, and then they move to the next layer. A special function is applied between layers to ensure that the model is able to learn non-linearity (not really relevant to a simple discussion here). When the data arrives at the final/output layer, the biases/weights from the final hidden layer are all congealed into a single neuron. A special function is applied here which adjusts all of the data into a single value between 0 and 1, and that is your probability.</p>
<h2 id="heading-training">Training</h2>
<p>The model will begin training with random weights and biases but with each datapoint will propagate backwards to try to "figure out" how to adjust the weights and biases to reduce the error. After many datapoints and epochs (iterations over the same data), the model (if it is well designed with quality, diverse data) will be able to be applied to new data (only inputs) and output realistic probabilities (outputs).</p>
<p>So how exactly do these new AI/ML models work? Both AIFS and GraphCast use an architecture called encoder-processor-decoder Graph Neural Networks. This means that the model takes the input data and puts it through 3 steps (encoder, processor, decoder). I will mostly focus on GraphCast as it is open source.</p>
<h3 id="heading-encoder-gridpoints">Encoder gridpoints</h3>
<p>In the first step, the encoder, the models take initial conditions (various meteorological fields such as temperature, geopotential heights, humidity, and more) across the globe and "encode" these datapoints onto a mesh grid (a grid where gridpoints are equidistant from one another) and connect each gridpoint to other gridpoints that are nearby as well as far away. This mapping is done by a neural network, which just means that the model is trained on how to make these connections most efficiently. Each gridpoint is now considered a "node" in the graph with "edges" connecting them to gridpoints near and far (7 levels of resolution reduction allow for connections near and far (high resolution and low resolution)).</p>
<h3 id="heading-forward-propagating">Forward-propagating</h3>
<p>"Connected" in this context just means that the program is informing the model that the gridpoints are connected and how they are connected. So the gridpoints (and their data) are connected, now what's next? The model enters the "processor" stage. In the processor stage, the model passes data between connected gridpoints 16 times. When a node (or gridpoint) receives information from a connected node, it updates its values and pushes data to the connected gridpoints. This message (or data) exchange occurs 16 times. The changes that each gridpoint applies is dependent on the data it is receiving from neighboring gridpoints, and this is entirely dependent on the training.</p>
<h3 id="heading-back-propagating-and-decoder-gridpoints">Back-propagating and Decoder gridpoints</h3>
<p>The final step is the "decoder" stage. In this stage, the data is plotted from the abstract processing stage, where it is split between various grid resolutions, back to the original 0.25deg lat-lon grid. This mapping is done through a single-layered graph neural network (the model simply learns how to map the data back to the original lat-lon grid). In training, the model compares the output to the expected output (target data based on past analysis data).. if the difference is huge, the model goes backwards through the steps and tries to adjust the values so that the error is reduced. It does this over and over again for each past event... and then goes over all of the events again likely dozens to hundreds of times. This allows the model to learn all of these various "trainable" factors (connections between gridpoints, how to change the data based on neighboring data, how to plot the data back to the original latlon grid, etc)..</p>
<h2 id="heading-chained-forecast">Chained forecast</h2>
<p>This is only for a 6hr forecast. The outputs from the 6hr forecast are then fed back into the model as inputs, producing a fresh 6hr forecast (total of 12hrs).. these forecasts are continuously chained together into the future indefinitely.. usually 240hrs currently. Eventually, the data becomes oversmooth and unrealistic.</p>
<p>So these models are very complex... a lot of that is simplified. If you'd like a deeper dive into this, I suggest reading the full paper on GraphCast published by google deepmind.</p>
<h2 id="heading-test">Test</h2>
<p>Btw: these models have been extensively tested with published verification data. They score better on every tested metric compared to ECMWF, GFS, and every other physics model. This includes with severe weather such as tropical cyclones.</p>
]]></content:encoded></item><item><title><![CDATA[Julia Notes Day3 -- Composite and Parametric Types]]></title><description><![CDATA[Composite types are called records, structs, or objects in various languages.
struct Foo
    bar
    baz::Int
    qux::Float64
end

foo = Foo("Hello, world.", 23, 1.5) # Foo("Hello, world.", 23, 1.5)

foo.bar # "Hello, world."


Composite objects dec...]]></description><link>https://blog.iread.fun/julia-notes-day3-composite-and-parametric-types</link><guid isPermaLink="true">https://blog.iread.fun/julia-notes-day3-composite-and-parametric-types</guid><category><![CDATA[Julia]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Fri, 15 Mar 2024 03:59:46 GMT</pubDate><content:encoded><![CDATA[<p>Composite types are called records, structs, or objects in various languages.</p>
<pre><code class="lang-julia"><span class="hljs-keyword">struct</span> Foo
    bar
    baz::<span class="hljs-built_in">Int</span>
    qux::<span class="hljs-built_in">Float64</span>
<span class="hljs-keyword">end</span>

foo = Foo(<span class="hljs-string">"Hello, world."</span>, <span class="hljs-number">23</span>, <span class="hljs-number">1.5</span>) <span class="hljs-comment"># Foo("Hello, world.", 23, 1.5)</span>

foo.bar <span class="hljs-comment"># "Hello, world."</span>
</code></pre>
<blockquote>
<p>Composite objects declared with <code>struct</code> are <em>immutable</em>; they cannot be modified after construction.</p>
<p>An immutable object might contain mutable objects, such as arrays, as fields. Those contained objects will remain mutable; only the fields of the immutable object itself cannot be changed to point to different objects.</p>
</blockquote>
<p>Where required, mutable composite objects can be declared with the keyword <code>mutable struct</code>.</p>
<p>In cases where one or more fields of an otherwise mutable struct is known to be immutable, one can declare these fields as such using <code>const</code> as shown below.</p>
<pre><code class="lang-julia"><span class="hljs-keyword">mutable struct</span> Baz
    a::<span class="hljs-built_in">Int</span>
    <span class="hljs-keyword">const</span> b::<span class="hljs-built_in">Float64</span>
<span class="hljs-keyword">end</span>

baz = Baz(<span class="hljs-number">1</span>, <span class="hljs-number">1.5</span>) <span class="hljs-comment"># Baz(1, 1.5)</span>
baz.a = <span class="hljs-number">3</span>;
baz <span class="hljs-comment"># Baz(3, 1.5)</span>
</code></pre>
<p>An important and powerful feature of Julia's type system is that it is parametric: types can take parameters, so that type declarations actually introduce a whole family of new types – one for each possible combination of parameter values.</p>
<pre><code class="lang-julia"><span class="hljs-keyword">struct</span> Point{T&lt;:<span class="hljs-built_in">Real</span>}
    x::T
    y::T
<span class="hljs-keyword">end</span>
</code></pre>
<p>Without any explicitly provided inner constructors, the declaration of the composite type <code>Point{T&lt;:Real}</code> automatically provides an inner constructor, <code>Point{T}</code>, for each possible type <code>T&lt;:Real</code>, that behaves just like non-parametric default inner constructors do. It also provides a single general outer <code>Point</code> constructor that takes pairs of real arguments, which must be of the same type. This automatic provision of constructors is equivalent to the following explicit declaration:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">struct</span> Point{T&lt;:<span class="hljs-built_in">Real</span>}
   x::T
   y::T
   Point{T}(x,y) <span class="hljs-keyword">where</span> {T&lt;:<span class="hljs-built_in">Real</span>} = new(x,y)
<span class="hljs-keyword">end</span>

Point(x::T, y::T) <span class="hljs-keyword">where</span> {T&lt;:<span class="hljs-built_in">Real</span>} = Point{T}(x,y);
</code></pre>
<p>By default, instances of parametric composite types can be constructed either with explicitly given type parameters or with type parameters implied by the types of the arguments given to the constructor. Here are some examples:</p>
<pre><code class="lang-julia">p1 = Point(<span class="hljs-number">7</span>,<span class="hljs-number">5</span>) <span class="hljs-comment">## implicit T ## Point{Int64}(7,5)</span>
p2 = Point(<span class="hljs-number">2</span>,<span class="hljs-number">3</span>) <span class="hljs-comment">## implicit T ## Point{Int64}(2,3)</span>

Point{<span class="hljs-built_in">Float64</span>}(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>) <span class="hljs-comment">## explicit T ## Point{Float64}(1.0, 2.0)</span>

p1 = Point(<span class="hljs-number">5</span>,<span class="hljs-number">1.5</span>) 
<span class="hljs-comment"># ERROR: MethodError: no method matching Point(::Int64, ::Float64)</span>
</code></pre>
<p>For a more general way to make all such calls work sensibly, all it takes is the following outer method definition to make all calls to the general <code>Point</code> constructor work as one would expect:</p>
<pre><code class="lang-julia">Point(x::<span class="hljs-built_in">Real</span>, y::<span class="hljs-built_in">Real</span>) = Point(promote(x,y)...);

<span class="hljs-comment"># Point(Float64, Int) -&gt; Point(Float64, Float64)</span>
Point(<span class="hljs-number">1.5</span>,<span class="hljs-number">2</span>) <span class="hljs-comment"># Point{Float64}(1.5, 2.0)</span>
</code></pre>
<p>The <code>promote</code> function converts all its arguments to a common type – in this case <code>Float64</code>. With this method definition, the <code>Point</code> constructor promotes its arguments the same way that numeric operators like <code>+</code> do, and works for all kinds of real numbers.</p>
<p>In mainstream object oriented languages, such as C++, Java, Python and Ruby, composite types also have named functions associated with them, and the combination is called an "object".</p>
<p>In Julia, all values are objects, but functions are always <strong>not</strong> bundled with the objects they operate on.This is necessary since Julia chooses which method of a function to use by multiple dispatch, meaning that the types of <em>all</em> of a function's arguments are considered when selecting a method, rather than just the first one.</p>
<pre><code class="lang-julia">Base.show(io::<span class="hljs-built_in">IO</span>, z::Point) = print(io, <span class="hljs-string">"{\n  x=<span class="hljs-subst">$(z.x)</span>\n  y=<span class="hljs-subst">$(z.y)</span>\n}"</span>)

Point(<span class="hljs-number">2.3</span>, <span class="hljs-number">5</span>)
<span class="hljs-comment">#= 
{
  x=2.3
  y=5.0
}
=#</span>
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Julia Notes Day2 -- string and collections]]></title><description><![CDATA[Char and String
A Char value represents a single character
c = 'x'
d = Int('x') # 120
e = Char(120)  # 'x'
f = '\u2200' # '∀': Unicode U+2200 (category Sm: Symbol, math)
g = 'A' + 1 # 'B'

String literals are delimited by double quotes or triple doub...]]></description><link>https://blog.iread.fun/julia-notes-day2-string-and-collections</link><guid isPermaLink="true">https://blog.iread.fun/julia-notes-day2-string-and-collections</guid><category><![CDATA[Julia]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Wed, 13 Mar 2024 10:53:53 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-char-and-string">Char and String</h2>
<p>A <code>Char</code> value represents a single character</p>
<pre><code class="lang-julia">c = <span class="hljs-string">'x'</span>
d = <span class="hljs-built_in">Int</span>(<span class="hljs-string">'x'</span>) <span class="hljs-comment"># 120</span>
<span class="hljs-literal">e</span> = <span class="hljs-built_in">Char</span>(<span class="hljs-number">120</span>)  <span class="hljs-comment"># 'x'</span>
f = <span class="hljs-string">'\u2200'</span> <span class="hljs-comment"># '∀': Unicode U+2200 (category Sm: Symbol, math)</span>
g = <span class="hljs-string">'A'</span> + <span class="hljs-number">1</span> <span class="hljs-comment"># 'B'</span>
</code></pre>
<p>String literals are delimited by double quotes or triple double quotes (not single quotes).</p>
<pre><code class="lang-julia">s = <span class="hljs-string">"\u2200 x \u2203 y"</span> <span class="hljs-comment"># "∀ x ∃ y"</span>
s *= <span class="hljs-string">"世界"</span> <span class="hljs-comment"># "∀ x ∃ y世界"</span>
length(s) <span class="hljs-comment"># 9</span>
sizeof(s) <span class="hljs-comment"># 17</span>
s[<span class="hljs-keyword">end</span>] <span class="hljs-comment"># '界': Unicode U+754C (category Lo: Letter, other)</span>

findfirst(<span class="hljs-string">'界'</span>,s) <span class="hljs-comment"># 15</span>

<span class="hljs-comment"># Sequential iteration is implemented by the iterate function. </span>
<span class="hljs-comment"># The general for loop:</span>
<span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> s
    print(c*<span class="hljs-string">' '</span>)
<span class="hljs-keyword">end</span>
<span class="hljs-comment"># ∀   x   ∃   y 世 界</span>
</code></pre>
<blockquote>
<p>String literals are encoded using the UTF-8 encoding. UTF-8 is a variable-width encoding, meaning that not all characters are encoded in the same number of bytes ("code units"). In UTF-8, ASCII characters — i.e. those with code points less than 0x80 (128) – are encoded as they are in ASCII, using a single byte, while code points 0x80 and above are encoded using multiple bytes — up to four per character.</p>
<p>String indices in Julia refer to code units (= bytes for UTF-8), the fixed-width building blocks that are used to encode arbitrary characters (code points). This means that not every index into a <code>String</code> is necessarily a valid index for a character. If you index into a string at such an invalid byte index, an error is thrown</p>
</blockquote>
<pre><code class="lang-julia">greet = <span class="hljs-string">"Hello"</span>; whom = <span class="hljs-string">"world"</span>;

<span class="hljs-comment">#Julia provides * for string concatenation</span>
greet * <span class="hljs-string">' '</span> * whom <span class="hljs-comment"># "Hello world"</span>

<span class="hljs-comment">#interpolation into string literals using $</span>
<span class="hljs-string">"<span class="hljs-variable">$greet</span>, <span class="hljs-variable">$whom</span>."</span> <span class="hljs-comment"># "Hello, world."</span>

<span class="hljs-comment"># triple-quoted strings are dedented to the level of the least-indented line.</span>
str = <span class="hljs-string">"""
           Hello,
           world.
         """</span>
<span class="hljs-comment"># "  Hello,\n  world.\n"</span>

<span class="hljs-string">"1 + 2 = 3"</span> == <span class="hljs-string">"1 + 2 = <span class="hljs-subst">$(<span class="hljs-number">1</span> + <span class="hljs-number">2</span>)</span>"</span> <span class="hljs-comment"># true</span>

<span class="hljs-comment"># repeat("A", 10)</span>
<span class="hljs-string">'A'</span>^<span class="hljs-number">10</span> <span class="hljs-comment"># "AAAAAAAAAA"</span>
<span class="hljs-string">"B"</span>^<span class="hljs-number">10</span> <span class="hljs-comment"># "BBBBBBBBBB"</span>
<span class="hljs-string">"BA"</span>^<span class="hljs-number">10</span> <span class="hljs-comment"># "BABABABABABABABABABA"</span>
</code></pre>
<h2 id="heading-range-and-vector">Range and Vector</h2>
<pre><code class="lang-julia">V = [i/<span class="hljs-number">2</span> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-number">1</span>:<span class="hljs-number">10</span>]

<span class="hljs-comment"># Comprehensions can also be written without the enclosing square brackets, </span>
<span class="hljs-comment"># producing an object known as a generator.</span>
sum(<span class="hljs-number">1</span>/n^<span class="hljs-number">2</span> <span class="hljs-keyword">for</span> n=<span class="hljs-number">1</span>:<span class="hljs-number">1000</span>)

<span class="hljs-comment"># convert a range to a vector by using the collect function.</span>
vec = collect(<span class="hljs-number">1</span>:<span class="hljs-number">2</span>:<span class="hljs-number">7</span>)
println(vec)  <span class="hljs-comment"># Output: [1, 3, 5, 7]</span>
</code></pre>
<h2 id="heading-matrix">Matrix</h2>
<pre><code class="lang-julia">A = [<span class="hljs-number">1</span> <span class="hljs-number">2</span>; <span class="hljs-number">3</span> <span class="hljs-number">4</span>] 
<span class="hljs-comment">#= 2×2 Matrix{Int64}:
 1  2
 3  4
=#</span>
B = A*A*A
<span class="hljs-comment">#= 2×2 Matrix{Int64}:
 37   54
 81  118
=#</span>
B == A^<span class="hljs-number">3</span> <span class="hljs-comment"># true</span>

C = A * <span class="hljs-number">3</span>
C == <span class="hljs-number">3</span>A  <span class="hljs-comment"># true</span>

sin.(A)
<span class="hljs-comment">#= 2×2 Matrix{Float64}:
 0.841471   0.909297
 0.14112   -0.756802
=#</span>

sin(A)
<span class="hljs-comment">#= 2×2 Matrix{Float64}:
 -0.465581  -0.148424
 -0.222637  -0.688218
=#</span>

A*[<span class="hljs-number">1</span>,<span class="hljs-number">2</span>]
<span class="hljs-comment">#= 2-element Vector{Int64}:
  5
 11
=#</span>
</code></pre>
<h2 id="heading-dict">Dict</h2>
<pre><code class="lang-julia"><span class="hljs-built_in">Dict</span>(<span class="hljs-string">"A"</span>=&gt;<span class="hljs-number">1</span>, <span class="hljs-string">"B"</span>=&gt;<span class="hljs-number">2</span>)
<span class="hljs-comment">#= Dict{String, Int64} with 2 entries:
  "B" =&gt; 2
  "A" =&gt; 1
=#</span>
</code></pre>
<h2 id="heading-list-of-functions-of-collections">List of functions of Collections</h2>
<blockquote>
<ul>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.iterate">Base.iterate — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.IteratorSize">Base.IteratorSize — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.IteratorEltype">Base.IteratorEltype — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.AbstractRange">Base.AbstractRange — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.OrdinalRange">Base.OrdinalRange — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.AbstractUnitRange">Base.AbstractUnitRange — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.StepRange">Base.StepRange — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.UnitRange">Base.UnitRange — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.LinRange">Base.LinRange — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.isempty">Base.isempty — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.empty!">Base.empty! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.length">Base.length — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.checked_length">Base.checked_length — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.in">Base.in — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.:%E2%88%89">Base.:∉ — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.eltype">Base.eltype — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.indexin">Base.indexin — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.unique">Base.unique — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.unique!">Base.unique! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.allunique">Base.allunique — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.allequal">Base.allequal — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.reduce-Tuple{Any,20%Any}">Base.reduce — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.reduce-Tuple{Any,20%AbstractArray}">Base.reduce — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.foldl-Tuple{Any,20%Any}">Base.foldl — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.foldr-Tuple{Any,20%Any}">Base.foldr — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.maximum">Base.maximum — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.maximum!">Base.maximum! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.minimum">Base.minimum — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.minimum!">Base.minimum! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.extrema">Base.extrema — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.extrema!">Base.extrema! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.argmax">Base.argmax — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.argmin">Base.argmin — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.findmax">Base.findmax — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.findmin">Base.findmin — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.findmax!">Base.findmax! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.findmin!">Base.findmin! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.sum">Base.sum — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.sum!">Base.sum! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.prod">Base.prod — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.prod!">Base.prod! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.any-Tuple%7BAny%7D">Base.any — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.any-Tuple{AbstractArray,20%Any}">Base.any — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.any!">Base.any! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.all-Tuple%7BAny%7D">Base.all — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.all-Tuple{AbstractArray,20%Any}">Base.all — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.all!">Base.all! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.count">Base.count — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.foreach">Base.foreach — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.map">Base.map — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.map!">Base.map! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.mapreduce-Tuple{Any,%20Any,%20Any}">Base.mapreduce — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.mapfoldl-Tuple{Any,%20Any,%20Any}">Base.mapfoldl — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.mapfoldr-Tuple{Any,%20Any,%20Any}">Base.mapfoldr — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.first">Base.first — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.last">Base.last — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.front">Base.front — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.tail">Base.tail — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.step">Base.step — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.collect-Tuple%7BAny%7D">Base.collect — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.collect-Tuple{Type,%20Any}">Base.collect — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.filter">Base.filter — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.filter!">Base.filter! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.replace-Tuple{Any,20%Vararg{Pair}}">Base.replace — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.replace-Tuple{Union{Function,%20Type},%20Any}">Base.replace — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.replace!">Base.replace! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.rest">Base.rest — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.split_rest">Base.split_rest — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.getindex">Base.getindex — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.setindex!">Base.setindex! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.firstindex">Base.firstindex — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.lastindex">Base.lastindex — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.AbstractDict">Base.AbstractDict — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.Dict">Base.Dict — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.IdDict">Base.IdDict — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.WeakKeyDict">Base.WeakKeyDict — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.ImmutableDict">Base.ImmutableDict — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.haskey">Base.haskey — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.get">Base.get — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.get!">Base.get! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.getkey">Base.getkey — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.delete!">Base.delete! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.pop!-Tuple{Any,%20Any,%20Any}">Base.pop! — Method</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.keys">Base.keys — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.values">Base.values — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.pairs">Base.pairs — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.merge">Base.merge — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.mergewith">Base.mergewith — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.merge!">Base.merge! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.mergewith!">Base.mergewith! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.sizehint!">Base.sizehint! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.keytype">Base.keytype — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.valtype">Base.valtype — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.AbstractSet">Base.AbstractSet — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.Set">Base.Set — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.BitSet">Base.BitSet — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.union">Base.union — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.union!">Base.union! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.intersect">Base.intersect — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.setdiff">Base.setdiff — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.setdiff!">Base.setdiff! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.symdiff">Base.symdiff — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.symdiff!">Base.symdiff! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.intersect!">Base.intersect! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.issubset">Base.issubset — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.:%E2%8A%88">Base.:⊈ — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.:%E2%8A%8A">Base.:⊊ — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.issetequal">Base.issetequal — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.isdisjoint">Base.isdisjoint — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.push!">Base.push! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.pop!">Base.pop! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.popat!">Base.popat! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.pushfirst!">Base.pushfirst! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.popfirst!">Base.popfirst! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.insert!">Base.insert! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.deleteat!">Base.deleteat! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.keepat!">Base.keepat! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.splice!">Base.splice! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.resize!">Base.resize! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.append!">Base.append! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.prepend!">Base.prepend! — Function</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Core.Pair">Core.Pair — Type</a></p>
</li>
<li><p><a target="_blank" href="https://docs.julialang.org/en/v1/base/collections/#Base.Pairs">Base.Pairs — Type</a></p>
</li>
</ul>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Julia Notes Day1 -- functions and operators]]></title><description><![CDATA[Functions
∑(n) = sum(1:n)

∑(3) # Output: 6
∑(100) # Output: 5050


Unicode variable and function names ∑ are allowed.
Julia functions can be defined using compact "assignment form" syntax.
The value returned by a function is the value of the last ex...]]></description><link>https://blog.iread.fun/julia-notes-day1-functions-and-operators</link><guid isPermaLink="true">https://blog.iread.fun/julia-notes-day1-functions-and-operators</guid><category><![CDATA[Julia]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Wed, 13 Mar 2024 03:48:52 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-functions">Functions</h2>
<pre><code class="lang-julia">∑(n) = sum(<span class="hljs-number">1</span>:n)

∑(<span class="hljs-number">3</span>) <span class="hljs-comment"># Output: 6</span>
∑(<span class="hljs-number">100</span>) <span class="hljs-comment"># Output: 5050</span>
</code></pre>
<blockquote>
<p><a target="_blank" href="https://www.fileformat.info/info/unicode/category/index.htm">Unicode</a> variable and function names <code>∑</code> are allowed.</p>
<p>Julia functions can be defined using compact "assignment form" syntax.</p>
<p>The value returned by a function is the value of the last expression evaluated, the <code>return</code> keyword can be omited.</p>
</blockquote>
<pre><code class="lang-julia">∏(n) = (p=<span class="hljs-number">1</span>; <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-number">1</span>:n; p*=i; <span class="hljs-keyword">end</span>; p) <span class="hljs-comment"># the ; chain syntax</span>

∏(<span class="hljs-number">4</span>) <span class="hljs-comment"># Output: 24</span>
∏(<span class="hljs-number">10</span>) <span class="hljs-comment"># Output: 3628800</span>
</code></pre>
<blockquote>
<p>Sometimes it is convenient to have a single expression which evaluates several subexpressions in order, returning the value of the last subexpression as its value.</p>
<p>There are two Julia constructs that accomplish this: <code>begin</code> blocks and <code>;</code> chains.</p>
</blockquote>
<pre><code class="lang-julia"><span class="hljs-keyword">function</span> foo(a,b)
    a+b, a*b <span class="hljs-comment">#return multiple values by returning a tuple</span>
<span class="hljs-keyword">end</span>

foo(<span class="hljs-number">2</span>,<span class="hljs-number">3</span>) <span class="hljs-comment"># Output: (5, 6)</span>
</code></pre>
<blockquote>
<p>Julia has a built-in data structure called a <em>tuple</em> that is closely related to function arguments and return values.</p>
</blockquote>
<h2 id="heading-operators">Operators</h2>
<p>In Julia, operators and symbols often have specific meanings or uses that are integral to the language's syntax and functionality. Below is a list of some of these symbols, along with brief explanations and code examples to illustrate their use:</p>
<h3 id="heading-arithmetic-operators">Arithmetic Operators</h3>
<ul>
<li><p><code>+</code> (Addition)</p>
</li>
<li><p><code>-</code> (Subtraction)</p>
</li>
<li><p><code>*</code> (Multiplication)</p>
</li>
<li><p><code>/</code> (Division)</p>
</li>
<li><p><code>÷</code> (integer divide)</p>
</li>
<li><p><code>^</code> (Power)</p>
</li>
<li><p><code>%</code> (Remainder)</p>
</li>
</ul>
<h3 id="heading-comparison-operators">Comparison Operators</h3>
<ul>
<li><p><code>==</code> (Equal to)</p>
</li>
<li><p><code>!=</code> or <code>≠</code> (Not equal to)</p>
</li>
<li><p><code>&lt;</code> (Less than)</p>
</li>
<li><p><code>&gt;</code> (Greater than)</p>
</li>
<li><p><code>&lt;=</code> or <code>≤</code> (Less than or equal to)</p>
</li>
<li><p><code>&gt;=</code> or <code>≥</code> (Greater than or equal to)</p>
</li>
</ul>
<h3 id="heading-logical-operators">Logical Operators</h3>
<ul>
<li><p><code>!</code> (Not)</p>
</li>
<li><p><code>&amp;&amp;</code> (And)</p>
</li>
<li><p><code>||</code> (Or)</p>
</li>
</ul>
<h3 id="heading-bitwise-operators">Bitwise Operators</h3>
<ul>
<li><p><code>&amp;</code> (And)</p>
</li>
<li><p><code>|</code> (Or)</p>
</li>
<li><p><code>~</code> (Not)</p>
</li>
<li><p><code>&lt;&lt;</code> (logical/arithmetic shift left)</p>
</li>
<li><p><code>&gt;&gt;</code> (arithmetic shift right)</p>
</li>
<li><p><code>&gt;&gt;&gt;</code> (logical shift right)</p>
</li>
<li><p><code>⊻</code> bitwise xor (exclusive or)</p>
</li>
<li><p><code>⊼</code> bitwise nand (not and)</p>
</li>
<li><p><code>⊽</code> bitwise nor (not or)</p>
</li>
</ul>
<h3 id="heading-spehttpsenwikipediaorgwikilogicalshiftciahttpsenwikipediaorgwikiarithmeticshiftl-symbols"><a target="_blank" href="https://en.wikipedia.org/wiki/Logical_shift">Spe</a><a target="_blank" href="https://en.wikipedia.org/wiki/Arithmetic_shift">cia</a>l Symbols</h3>
<ul>
<li><p><code>:</code> (Colon, used for ranges)</p>
</li>
<li><p><code>;</code> (Semicolon, used to separate expressions)</p>
</li>
<li><p><code>=&gt;</code> (Pair, used in dictionaries)</p>
</li>
<li><p><code>[]</code> (Brackets, used for indexing or array literals)</p>
</li>
<li><p><code>{}</code> (Curly braces, used for comprehension or generator expressions)</p>
</li>
<li><p><code>()</code> (Parentheses, used for grouping or function calls)</p>
</li>
<li><p><code>|&gt;</code> (Pipe, used for function chaining)</p>
</li>
<li><p><code>.</code> (Dot, used for broadcasting)</p>
</li>
</ul>
<pre><code class="lang-julia"><span class="hljs-comment"># Range</span>
<span class="hljs-number">1</span>:<span class="hljs-number">5</span>  <span class="hljs-comment"># 1:5</span>

<span class="hljs-comment"># Pair and Dictionary</span>
dict = <span class="hljs-built_in">Dict</span>(<span class="hljs-string">"a"</span> =&gt; <span class="hljs-number">1</span>, <span class="hljs-string">"b"</span> =&gt; <span class="hljs-number">2</span>)

<span class="hljs-comment"># Pipe</span>
sqrt(<span class="hljs-number">25</span>) |&gt; println  <span class="hljs-comment"># 5.0</span>

<span class="hljs-comment"># Broadcasting</span>
[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>] .+ <span class="hljs-number">1</span>  <span class="hljs-comment"># [2, 3, 4]</span>
<span class="hljs-number">1</span>:<span class="hljs-number">3</span> .|&gt; (x -&gt; x^<span class="hljs-number">2</span>)  <span class="hljs-comment"># [1, 4, 9]</span>
</code></pre>
<h3 id="heading-division-and-related-operations">Division and Related Operations</h3>
<ul>
<li><p><code>\</code> (Backslash, used for solving linear equations, <code>A \ b</code> solves <code>Ax = b</code>)</p>
</li>
<li><p><code>//</code> (Rational, creates a rational number)</p>
</li>
</ul>
<pre><code class="lang-julia"><span class="hljs-comment"># Solving linear equations</span>
A = [<span class="hljs-number">1</span> <span class="hljs-number">2</span>; <span class="hljs-number">3</span> <span class="hljs-number">4</span>]
b = [<span class="hljs-number">5</span>, <span class="hljs-number">11</span>]
A \ b  <span class="hljs-comment"># [1.0, 2.0]</span>

<span class="hljs-comment"># Rational number</span>
<span class="hljs-number">3</span> // <span class="hljs-number">4</span>  <span class="hljs-comment"># 3//4</span>
</code></pre>
]]></content:encoded></item><item><title><![CDATA[在 Python 中模拟 switch 语句的 fall-through 行为]]></title><description><![CDATA[什么是 fall-through
在 JavaScript 中，switch 语句允许 fall-through 行为。当在 switch 语句中发现匹配条件时，相应的代码块将被执行，直到遇到 break 语句，此时 switch 语句将退出。如果没有提供 break 语句，程序将继续执行下一个 case，而不管它是否与条件匹配。这就是所谓的 fall-through 行为。
switch (Animal) {
    case "Dog":
    case "Cow":
        co...]]></description><link>https://blog.iread.fun/mimic-the-fall-through-behavior-of-switch-in-python-cn</link><guid isPermaLink="true">https://blog.iread.fun/mimic-the-fall-through-behavior-of-switch-in-python-cn</guid><category><![CDATA[fall-through]]></category><category><![CDATA[Switch case]]></category><category><![CDATA[match-case]]></category><category><![CDATA[Python 3]]></category><category><![CDATA[javascript control flow]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Mon, 05 Feb 2024 06:44:26 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-fall-through">什么是 fall-through</h2>
<p>在 JavaScript 中，<code>switch</code> 语句允许 fall-through 行为。当在 <code>switch</code> 语句中发现匹配条件时，相应的代码块将被执行，直到遇到 <code>break</code> 语句，此时 <code>switch</code> 语句将退出。如果没有提供 <code>break</code> 语句，程序将继续执行下一个 <code>case</code>，而不管它是否与条件匹配。这就是所谓的 fall-through 行为。</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">switch</span> (Animal) {
    <span class="hljs-keyword">case</span> <span class="hljs-string">"Dog"</span>:
    <span class="hljs-keyword">case</span> <span class="hljs-string">"Cow"</span>:
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"This animal is friend of people."</span>);
    <span class="hljs-keyword">case</span> <span class="hljs-string">"Giraffe"</span>:
    <span class="hljs-keyword">case</span> <span class="hljs-string">"Pig"</span>:
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"This animal is not extinct."</span>);
        <span class="hljs-keyword">break</span>;
    <span class="hljs-keyword">case</span> <span class="hljs-string">"Dinosaur"</span>:
    <span class="hljs-keyword">default</span>:
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"This animal is extinct."</span>);
}
</code></pre>
<h2 id="heading-fall-through-1">fall-through 何时有用</h2>
<p>在多个 cases 共享同一代码块或需要跨多个 cases 执行一连串操作时，<code>switch</code> 语句中的 fall-through 会非常有用。以下是一些例子：</p>
<ol>
<li><p>将多个 cases 组合在一起： 当多个 cases 需要执行相同的代码块时，fall-through 可让您一个接一个地列出这些 cases，而无需重复每个 case 的代码块。这可以使代码更简洁，更易于维护。</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">switch</span> (dayOfWeek) {
      <span class="hljs-keyword">case</span> <span class="hljs-string">"Saturday"</span>:
      <span class="hljs-keyword">case</span> <span class="hljs-string">"Sunday"</span>:
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"It's the weekend!"</span>);
          <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">default</span>:
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Looking forward to the Weekend"</span>);
  }
</code></pre>
</li>
<li><p>不同 cases 下的顺序操作： 在需要执行一系列操作的情况下，如果这些操作是建立在彼此基础之上的，但只是针对不同的情况从序列中的不同点开始执行，那么 fall-through 可以让您在不重复代码的情况下对这些操作进行结构化处理。</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">switch</span> (userLevel) {
      <span class="hljs-keyword">case</span> <span class="hljs-string">"beginner"</span>:
          beginnerTasks();
          <span class="hljs-comment">// Fall through to execute intermediate tasks as well.</span>
      <span class="hljs-keyword">case</span> <span class="hljs-string">"intermediate"</span>:
          intermediateTasks();
          <span class="hljs-comment">// Fall through to execute advanced tasks as well.</span>
      <span class="hljs-keyword">case</span> <span class="hljs-string">"advanced"</span>:
          advancedTasks();
          <span class="hljs-keyword">break</span>;
  }
</code></pre>
</li>
<li><p>设置特定条件下默认值： 您可以使用 fall-through 功能为某些情况设置默认值，然后在后面的特定情况中覆盖这些默认值。</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">switch</span> (productType) {
      <span class="hljs-keyword">case</span> <span class="hljs-string">"book"</span>:
          basePrice = <span class="hljs-number">5</span>;
          <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">"video"</span>:
      <span class="hljs-keyword">case</span> <span class="hljs-string">"software"</span>:
          <span class="hljs-comment">// These types have a base price and additional licensing fee.</span>
          basePrice = <span class="hljs-number">20</span>;
          <span class="hljs-comment">// Fall through to add licensing fee.</span>
      <span class="hljs-keyword">default</span>:
          licensingFee = <span class="hljs-number">10</span>;
  }
</code></pre>
</li>
<li><p>复杂的条件逻辑：当触发一个案例的逻辑比较复杂，涉及多个步骤或条件，并且这些步骤或条件相互依存时，可以使用 fall-through 功能以可读和高效的方式来构建这一逻辑。</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">switch</span> (<span class="hljs-literal">true</span>) {
      <span class="hljs-keyword">case</span> (score &gt;= <span class="hljs-number">90</span>):
          grade = <span class="hljs-string">"A"</span>;
          <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> (score &gt;= <span class="hljs-number">80</span>):
          <span class="hljs-comment">// Fall through to check for specific conditions within this range.</span>
      <span class="hljs-keyword">case</span> (score &gt;= <span class="hljs-number">70</span> &amp;&amp; extraCredit):
          grade = <span class="hljs-string">"B"</span>;
          <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">default</span>:
          grade = <span class="hljs-string">"C"</span>;
  }
</code></pre>
</li>
</ol>
<p>这些示例演示了在多个 cases 共享逻辑或需要跨 case 执行一系列操作的情况下，如何利用fall-through 来编写更高效、可读性和可维护性更强的代码。</p>
<h2 id="heading-python">Python 的模式匹配</h2>
<p>Python 3.10 引入了一个名为 <code>match-case</code> 语句的新特性，也称为模式匹配。该特性为处理条件逻辑提供了一种更具表现力的方式，类似于其他语言（如 JavaScript 或 C++）中的 <code>switch</code> 语句。</p>
<blockquote>
<p>然而，与 <code>switch</code> 语句不同的是，在 Python 的 <code>match-case</code> 语句中，cases 之间没有 "fall-through"。</p>
</blockquote>
<p>下面是一个如何在 Python 中使用 <code>match-case</code> 语句的示例：</p>
<pre><code class="lang-python">status = <span class="hljs-number">404</span>  <span class="hljs-comment"># replace with the actual status</span>
match status:
    case <span class="hljs-number">400</span>:
        result = <span class="hljs-string">"Bad request"</span>
    case <span class="hljs-number">404</span>:
        result = <span class="hljs-string">"Not found"</span>
    case <span class="hljs-number">418</span>:
        result = <span class="hljs-string">"I'm a teapot"</span>
    case _:
        result = <span class="hljs-string">"Unknown status"</span>
print(result)
</code></pre>
<p>在这个示例中，<code>match</code> 关键字后面是要匹配的表达式 (<code>status</code>)，<code>case</code> 后面是要匹配的模式。最后一个 <code>case</code> 语句中的 <code>_</code> 是一个通配符，可以匹配任何内容，类似于 <code>switch</code> 语句中的 <code>default</code> case。</p>
<p>您还可以使用更复杂的模式，并在模式中添加 guard 子句。guard 是一个 <code>if</code> 子句，它进一步细化了 case 的条件。如果 guard 为 false，则 <code>match</code> 会继续尝试下一个 case 块。</p>
<pre><code class="lang-python">point = (<span class="hljs-number">1</span>, <span class="hljs-number">1</span>)  <span class="hljs-comment"># replace with the actual point</span>
match point:
    case (x, y) <span class="hljs-keyword">if</span> x == y:
        <span class="hljs-comment"># the case statement matches a tuple and </span>
        <span class="hljs-comment"># uses a guard to check if the two elements of the tuple are equal.</span>
        print(<span class="hljs-string">f"The point is located on the diagonal Y=X at <span class="hljs-subst">{x}</span>."</span>)
    case (x, <span class="hljs-number">0</span>):
        print(<span class="hljs-string">f"X=<span class="hljs-subst">{x}</span> and the point is on the x-axis."</span>)
    case (<span class="hljs-number">0</span>, y):
        print(<span class="hljs-string">f"Y=<span class="hljs-subst">{y}</span> and the point is on the y-axis."</span>)
    case (<span class="hljs-number">0</span>, <span class="hljs-number">0</span>):
        print(<span class="hljs-string">"The point is at the origin."</span>)
    case (x, y) <span class="hljs-keyword">if</span> x &gt; <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> y &gt; <span class="hljs-number">0</span>:
        print(<span class="hljs-string">f"The point is in the first quadrant at (<span class="hljs-subst">{x}</span>, <span class="hljs-subst">{y}</span>)."</span>)
    case _:
        print(<span class="hljs-string">f"Point is not on the diagonal or axes at (<span class="hljs-subst">{x}</span>, <span class="hljs-subst">{y}</span>)."</span>)
</code></pre>
<h2 id="heading-python-switch-fall-through">如何在 Python 中模拟 switch 的 fall-through</h2>
<h3 id="heading-fall-through-2">不使用 fall-through</h3>
<pre><code class="lang-python"><span class="hljs-keyword">if</span> user_level == <span class="hljs-string">"beginner"</span>:
    beginnerTasks()
    intermediateTasks()
    advancedTasks()
<span class="hljs-keyword">elif</span> user_level == <span class="hljs-string">"intermediate"</span>:
    intermediateTasks()
    advancedTasks()
<span class="hljs-keyword">elif</span> user_level == <span class="hljs-string">"advanced"</span>:
    advancedTasks()
</code></pre>
<h3 id="heading-fall-through-3">模拟 fall-through</h3>
<p>在 Python 中，您可以使用一系列 <code>if</code> 语句和一个标志变量来模拟 <code>switch</code> 语句的 fall-through 行为。以下代码可供参考：</p>
<pre><code class="lang-python">fall_through = <span class="hljs-literal">False</span>

<span class="hljs-keyword">if</span> user_level == <span class="hljs-string">"beginner"</span>:
    beginnerTasks()
    fall_through = <span class="hljs-literal">True</span>
<span class="hljs-keyword">if</span> fall_through <span class="hljs-keyword">or</span> user_level == <span class="hljs-string">"intermediate"</span>:
    intermediateTasks()
    fall_through = <span class="hljs-literal">True</span>
<span class="hljs-keyword">if</span> fall_through <span class="hljs-keyword">or</span> user_level == <span class="hljs-string">"advanced"</span>:
    advancedTasks()
</code></pre>
<p>在这段代码中，<code>fall_through</code> 变量用于控制是否执行后续 <code>if</code> 语句中的代码。如果 <code>user_level</code> 为 "beginner"，则调用 <code>beginnerTasks()</code>，并将 <code>fall_through</code> 设为 <code>True</code>。这将导致执行下一个 <code>if</code> 语句中的代码，而不验证 <code>user_level</code> 的值。同样的逻辑也适用于 "intermediate" 级别。如果 <code>user_level</code> 是 "advanced"，那么只有 <code>advancedTasks()</code> 被调用，因为 <code>fall_through</code> 在开始时是 <code>False</code>。</p>
<h2 id="heading-python-match-case">Python 的 match-case 语句的优点</h2>
<p>在支持 fall-through 的语言（如 C 或 JavaScript）中，它的风险在于，如果程序员忘记在每个 <code>case</code> 的结尾加入 <code>break</code> 语句，就可能导致错误。如果没有 <code>break</code>，程序将继续执行下一个 <code>case</code> 的代码，这可能不是预期的行为，会导致意想不到的结果。</p>
<p>Python 3.10 引入的 <code>match-case</code> 语句的优点包括：</p>
<ol>
<li><p>无跳转： Python 的 <code>match-case</code> 没有 fall-through 行为，这消除了意外执行多个 cases 的风险。一旦发现匹配，Python 会执行相应 case 块中的语句，然后跳到 <code>match</code> 块的末尾，继续执行程序的其余部分。</p>
</li>
<li><p>模式匹配：<code>match-case</code> 语句是为模式匹配而设计的，它比简单的值匹配更强大。它允许匹配类型模式，而不仅仅是值，这可以使代码更具表现力和可读性。</p>
</li>
<li><p>复杂匹配： Python 的 <code>match-case</code> 可以处理复杂的匹配，并且可以在单个 <code>case</code> 块中处理多种可能的情况，这可以简化逻辑并减少嵌套 <code>if</code> 语句的需要。</p>
</li>
<li><p>可读性： <code>match-case</code> 语句提供了一种结构清晰的方式来处理多个条件，从而使代码更具可读性，这通常比一长串 <code>if-elif-else</code> 语句更优雅。</p>
</li>
<li><p>多重模式： 您可以使用 <code>|</code> 操作符在单例中匹配多个模式，从而以简洁的方式处理多个相关条件，而无需重复代码。</p>
</li>
<li><p>默认情况：<code>match-case</code> 语句中的默认情况用下划线 <code>_</code> 表示，它可以捕获前面 cases 中没有匹配到的任何值，确保涵盖所有可能性。</p>
</li>
</ol>
<p>总之，Python 的 <code>match-case</code> 语句为传统 fall-through 行为的 <code>switch</code> 语句提供了一个更安全、更强大的替代方案，减少了 bug 的风险，提高了代码的清晰度。</p>
]]></content:encoded></item><item><title><![CDATA[Mimic the fall-through behavior of switch in Python]]></title><description><![CDATA[What is fall-through
In JavaScript, the switch statement allows for fall-through behavior. When a match is found in a switch statement, the corresponding block of code is executed until a break statement is encountered, at which point the switch stat...]]></description><link>https://blog.iread.fun/mimic-the-fall-through-behavior-of-switch-in-python</link><guid isPermaLink="true">https://blog.iread.fun/mimic-the-fall-through-behavior-of-switch-in-python</guid><category><![CDATA[fall-through]]></category><category><![CDATA[Switch case]]></category><category><![CDATA[match-case]]></category><category><![CDATA[Python 3]]></category><category><![CDATA[javascript control flow]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Mon, 05 Feb 2024 05:58:39 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-what-is-fall-through">What is fall-through</h2>
<p>In JavaScript, the <code>switch</code> statement allows for fall-through behavior. When a match is found in a <code>switch</code> statement, the corresponding block of code is executed until a <code>break</code> statement is encountered, at which point the <code>switch</code> statement is exited. If a <code>break</code> statement is not provided, the program will continue executing the next case, regardless of whether it matches the condition or not. This is known as fall-through behavior.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">switch</span> (Animal) {
    <span class="hljs-keyword">case</span> <span class="hljs-string">"Dog"</span>:
    <span class="hljs-keyword">case</span> <span class="hljs-string">"Cow"</span>:
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"This animal is friend of people."</span>);
    <span class="hljs-keyword">case</span> <span class="hljs-string">"Giraffe"</span>:
    <span class="hljs-keyword">case</span> <span class="hljs-string">"Pig"</span>:
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"This animal is not extinct."</span>);
        <span class="hljs-keyword">break</span>;
    <span class="hljs-keyword">case</span> <span class="hljs-string">"Dinosaur"</span>:
    <span class="hljs-keyword">default</span>:
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"This animal is extinct."</span>);
}
</code></pre>
<h2 id="heading-when-will-fall-through-be-useful">When will fall-through be useful</h2>
<p>Fall-through in a <code>switch</code> statement can be very useful in several scenarios where multiple cases share the same code block or when a sequence of operations needs to be executed across multiple cases. Here are some examples where fall-through is particularly beneficial:</p>
<ol>
<li><p><strong>Grouping Multiple Cases Together</strong>: When several cases should execute the same block of code, fall-through allows you to list these cases one after the other without repeating the code block for each case. This can make the code more concise and easier to maintain.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">switch</span> (dayOfWeek) {
     <span class="hljs-keyword">case</span> <span class="hljs-string">"Saturday"</span>:
     <span class="hljs-keyword">case</span> <span class="hljs-string">"Sunday"</span>:
         <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"It's the weekend!"</span>);
         <span class="hljs-keyword">break</span>;
     <span class="hljs-keyword">default</span>:
         <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Looking forward to the Weekend"</span>);
 }
</code></pre>
</li>
<li><p><strong>Sequential Operations for Different Cases</strong>: In situations where you want to execute a sequence of operations that build on each other, but only start at different points in the sequence for different cases, fall-through allows you to structure these operations without duplicating code.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">switch</span> (userLevel) {
     <span class="hljs-keyword">case</span> <span class="hljs-string">"beginner"</span>:
         beginnerTasks();
         <span class="hljs-comment">// Fall through to execute intermediate tasks as well.</span>
     <span class="hljs-keyword">case</span> <span class="hljs-string">"intermediate"</span>:
         intermediateTasks();
         <span class="hljs-comment">// Fall through to execute advanced tasks as well.</span>
     <span class="hljs-keyword">case</span> <span class="hljs-string">"advanced"</span>:
         advancedTasks();
         <span class="hljs-keyword">break</span>;
 }
</code></pre>
</li>
<li><p><strong>Setting Defaults with Overridden Specifics</strong>: You can use fall-through to set default values for certain cases, then override those defaults for specific cases that follow.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">switch</span> (productType) {
     <span class="hljs-keyword">case</span> <span class="hljs-string">"book"</span>:
         basePrice = <span class="hljs-number">5</span>;
         <span class="hljs-keyword">break</span>;
     <span class="hljs-keyword">case</span> <span class="hljs-string">"video"</span>:
     <span class="hljs-keyword">case</span> <span class="hljs-string">"software"</span>:
         <span class="hljs-comment">// These types have a base price and additional licensing fee.</span>
         basePrice = <span class="hljs-number">20</span>;
         <span class="hljs-comment">// Fall through to add licensing fee.</span>
     <span class="hljs-keyword">default</span>:
         licensingFee = <span class="hljs-number">10</span>;
 }
</code></pre>
</li>
<li><p><strong>Complex Conditional Logic</strong>: When the logic for triggering a case is complex and involves multiple steps or conditions that build upon each other, fall-through can be used to structure this logic in a readable and efficient manner.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">switch</span> (<span class="hljs-literal">true</span>) {
     <span class="hljs-keyword">case</span> (score &gt;= <span class="hljs-number">90</span>):
         grade = <span class="hljs-string">"A"</span>;
         <span class="hljs-keyword">break</span>;
     <span class="hljs-keyword">case</span> (score &gt;= <span class="hljs-number">80</span>):
         <span class="hljs-comment">// Fall through to check for specific conditions within this range.</span>
     <span class="hljs-keyword">case</span> (score &gt;= <span class="hljs-number">70</span> &amp;&amp; extraCredit):
         grade = <span class="hljs-string">"B"</span>;
         <span class="hljs-keyword">break</span>;
     <span class="hljs-keyword">default</span>:
         grade = <span class="hljs-string">"C"</span>;
 }
</code></pre>
</li>
</ol>
<p>These examples illustrate how fall-through can be leveraged to write more efficient, readable, and maintainable code in scenarios where multiple cases share logic or when a sequence of operations needs to be executed across cases.</p>
<h2 id="heading-pythons-pattern-matching">Python's pattern matching</h2>
<p>Python 3.10 introduced a new feature called the <code>match-case</code> statement, also known as pattern matching. This feature provides a more expressive way to handle conditional logic and is similar to the <code>switch</code> statement found in other languages like JavaScript or C++.</p>
<blockquote>
<p>However, unlike the <code>switch</code> statement, there is <strong>no</strong> "fall-through" between cases in Python's <code>match-case</code> statement.</p>
</blockquote>
<p>Here's an example of how to use the <code>match-case</code> statement in Python:</p>
<pre><code class="lang-python">status = <span class="hljs-number">404</span>  <span class="hljs-comment"># replace with the actual status</span>
match status:
    case <span class="hljs-number">400</span>:
        result = <span class="hljs-string">"Bad request"</span>
    case <span class="hljs-number">404</span>:
        result = <span class="hljs-string">"Not found"</span>
    case <span class="hljs-number">418</span>:
        result = <span class="hljs-string">"I'm a teapot"</span>
    case _:
        result = <span class="hljs-string">"Unknown status"</span>
print(result)
</code></pre>
<p>In this example, the <code>match</code> keyword is followed by the expression to match (<code>status</code>), and <code>case</code> is followed by the pattern to match against. The <code>_</code> in the last <code>case</code> statement is a wildcard that matches anything, similar to the <code>default</code> case in a <code>switch</code> statement.</p>
<p>You can also use more complex patterns and add a guard clause to a pattern. A guard is an <code>if</code> clause that further refines the condition for the case. If the guard is false, <code>match</code> goes on to try the next case block.</p>
<pre><code class="lang-python">point = (<span class="hljs-number">1</span>, <span class="hljs-number">1</span>)  <span class="hljs-comment"># replace with the actual point</span>
match point:
    case (x, y) <span class="hljs-keyword">if</span> x == y:
        <span class="hljs-comment"># the case statement matches a tuple and </span>
        <span class="hljs-comment"># uses a guard to check if the two elements of the tuple are equal.</span>
        print(<span class="hljs-string">f"The point is located on the diagonal Y=X at <span class="hljs-subst">{x}</span>."</span>)
    case (x, <span class="hljs-number">0</span>):
        print(<span class="hljs-string">f"X=<span class="hljs-subst">{x}</span> and the point is on the x-axis."</span>)
    case (<span class="hljs-number">0</span>, y):
        print(<span class="hljs-string">f"Y=<span class="hljs-subst">{y}</span> and the point is on the y-axis."</span>)
    case (<span class="hljs-number">0</span>, <span class="hljs-number">0</span>):
        print(<span class="hljs-string">"The point is at the origin."</span>)
    case (x, y) <span class="hljs-keyword">if</span> x &gt; <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> y &gt; <span class="hljs-number">0</span>:
        print(<span class="hljs-string">f"The point is in the first quadrant at (<span class="hljs-subst">{x}</span>, <span class="hljs-subst">{y}</span>)."</span>)
    case _:
        print(<span class="hljs-string">f"Point is not on the diagonal or axes at (<span class="hljs-subst">{x}</span>, <span class="hljs-subst">{y}</span>)."</span>)
</code></pre>
<h2 id="heading-how-to-mimic-the-fall-through-behavior-of-switch-in-python">How to mimic the fall-through behavior of switch in Python</h2>
<h3 id="heading-without-fall-through">Without fall-through</h3>
<pre><code class="lang-python"><span class="hljs-keyword">if</span> user_level == <span class="hljs-string">"beginner"</span>:
    beginnerTasks()
    intermediateTasks()
    advancedTasks()
<span class="hljs-keyword">elif</span> user_level == <span class="hljs-string">"intermediate"</span>:
    intermediateTasks()
    advancedTasks()
<span class="hljs-keyword">elif</span> user_level == <span class="hljs-string">"advanced"</span>:
    advancedTasks()
</code></pre>
<h3 id="heading-mimic-the-fall-through">Mimic the fall-through</h3>
<p>You can mimic the fall-through behavior of a <code>switch</code> statement in Python using a series of <code>if</code> statements and a flag variable. Here's the code for reference:</p>
<pre><code class="lang-python">fall_through = <span class="hljs-literal">False</span>

<span class="hljs-keyword">if</span> user_level == <span class="hljs-string">"beginner"</span>:
    beginnerTasks()
    fall_through = <span class="hljs-literal">True</span>
<span class="hljs-keyword">if</span> fall_through <span class="hljs-keyword">or</span> user_level == <span class="hljs-string">"intermediate"</span>:
    intermediateTasks()
    fall_through = <span class="hljs-literal">True</span>
<span class="hljs-keyword">if</span> fall_through <span class="hljs-keyword">or</span> user_level == <span class="hljs-string">"advanced"</span>:
    advancedTasks()
</code></pre>
<p>In this code, the <code>fall_through</code> variable is used to control whether the code in the subsequent <code>if</code> statements should be executed. If <code>user_level</code> is "beginner", then <code>beginnerTasks()</code> is called and <code>fall_through</code> is set to <code>True</code>. This causes the code in the next <code>if</code> statement to be executed, regardless of the value of <code>user_level</code>. The same logic applies to the "intermediate" level. If <code>user_level</code> is "advanced", then only <code>advancedTasks()</code> is called, because <code>fall_through</code> is <code>False</code> at the start.</p>
<h2 id="heading-the-pros-of-pythons-match-case-statement">The pros of Python's <code>match-case</code> statement</h2>
<p>The risk of fall-through in languages that support it, such as C or JavaScript, is that it can lead to bugs if the programmer forgets to include a <code>break</code> statement at the end of each <code>case</code>. Without a <code>break</code>, the program will continue executing the next <code>case</code>'s code, which might not be the intended behavior and can cause unexpected results.</p>
<p>The pros of Python's <code>match-case</code> statement, introduced in Python 3.10, include:</p>
<ol>
<li><p><strong>No Fall-Through</strong>: Python's <code>match-case</code> does not have fall-through behavior, which eliminates the risk of accidentally executing multiple cases. Once a match is found, Python executes the statements in the corresponding case block and then skips to the end of the <code>match</code> block, continuing with the rest of the program.</p>
</li>
<li><p><strong>Pattern Matching</strong>: The <code>match-case</code> statement is designed for pattern matching, which is more powerful than simple value matching. It allows for matching patterns of types, not just values, which can lead to more expressive and readable code.</p>
</li>
<li><p><strong>Complex Matches</strong>: Python's <code>match-case</code> can handle complex matches and can be designed to handle multiple possible cases in a single case block, which can simplify the logic and reduce the need for nested <code>if</code> statements.</p>
</li>
<li><p><strong>Readability</strong>: The <code>match-case</code> statement can make code more readable by providing a clear and structured way to handle multiple conditions, which is often more elegant than a long series of <code>if-elif-else</code> statements.</p>
</li>
<li><p><strong>Multiple Patterns</strong>: You can match multiple patterns in a single case using the <code>|</code> operator, which allows for a concise way to handle multiple related conditions without duplicating code.</p>
</li>
<li><p><strong>Default Case</strong>: The default case in a <code>match-case</code> statement is represented by an underscore <code>_</code>, which acts as a catch-all for any values not matched by previous cases, ensuring that all possibilities are covered.</p>
</li>
</ol>
<p>In summary, Python's <code>match-case</code> statement provides a safer and more powerful alternative to traditional <code>switch</code> statements with fall-through behavior, reducing the risk of bugs and improving code clarity.</p>
]]></content:encoded></item><item><title><![CDATA[防范并识别 html/JS 应用内存泄漏的策略]]></title><description><![CDATA[随着时间的推移，内存泄漏会降低应用程序的性能，并可能导致崩溃或其他问题。因此，在应用程序中有效管理内存非常重要。
防范内存泄漏
要防范 HTML/JS 应用程序中的内存泄漏，您可以遵循以下策略：

避免不必要的引用： 不必要的引用是内存泄漏的常见原因。当不再需要的对象仍被代码的其他部分引用时，就会发生这种情况，从而导致垃圾回收器无法释放这些对象所使用的内存[3]。
 var detachedNode = document.getElementById('someElement');
 detac...]]></description><link>https://blog.iread.fun/strategies-to-prevent-identify-memory-leaks-in-html-js-cn</link><guid isPermaLink="true">https://blog.iread.fun/strategies-to-prevent-identify-memory-leaks-in-html-js-cn</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[HTML]]></category><category><![CDATA[Memory Leak]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Wed, 24 Jan 2024 10:41:51 GMT</pubDate><content:encoded><![CDATA[<p>随着时间的推移，内存泄漏会降低应用程序的性能，并可能导致崩溃或其他问题。因此，在应用程序中有效管理内存非常重要。</p>
<h2 id="heading-6ziy6iyd5yaf5a2y5roe5ryp">防范内存泄漏</h2>
<p>要防范 HTML/JS 应用程序中的内存泄漏，您可以遵循以下策略：</p>
<ol>
<li><p>避免不必要的引用： 不必要的引用是内存泄漏的常见原因。当不再需要的对象仍被代码的其他部分引用时，就会发生这种情况，从而导致垃圾回收器无法释放这些对象所使用的内存[3]。</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">var</span> detachedNode = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'someElement'</span>);
 detachedNode.parentNode.removeChild(detachedNode);
</code></pre>
<p> 在上面的示例中，尽管 <code>someElement</code> 已从 DOM 中移除，但由于 <code>detachedNode</code> 中存在对它的引用，所以它仍在内存中。</p>
</li>
<li><p>合适的事件监听器管理： 不删除事件监听器会导致内存泄漏。当不再需要事件监听器时，请务必将其移除。</p>
</li>
<li><p>避免使用全局变量： 全局变量不会被垃圾回收器回收，因为它们处于全局范围内。如果全局变量持有对某个对象的引用，则该对象无法被垃圾回收器回收[1]。</p>
</li>
<li><p>避免闭包引用不需要的数据： 闭包可能会无意中保留对不再需要的较大对象或作用域的引用，从而导致内存泄漏[1]。</p>
<pre><code class="lang-javascript">  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">outerFunction</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">var</span> largeObject = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>(<span class="hljs-number">1000000</span>).fill(<span class="hljs-string">'Memory Leak'</span>);
      <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">innerFunction</span>(<span class="hljs-params"></span>) </span>{
          <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
      }
  }
  <span class="hljs-keyword">var</span> closure = outerFunction();
</code></pre>
<p> 在上例中，<code>innerFunction</code> 的闭包存在于 <code>outerFunction</code> 的作用域里，其中包括 <code>largeObject</code>。尽管 <code>innerFunction</code> 不会使用 <code>largeObject</code>，但由于闭包的存在，只要 <code>innerFunction</code> 存在，它就会保留在内存中。</p>
</li>
<li><p>避免第三方库的内存泄漏： 某些第三方库可能存在内存泄漏。请始终使用最新版本的库和框架，因为这些版本通常都有内存泄漏修复[1]。</p>
</li>
<li><p>代码审查： 定期审查代码有助于捕捉常见的内存泄漏模式[1]。</p>
</li>
<li><p>删除不必要的 DOM 元素： 如果您动态创建了 DOM 元素，但以后不再需要它们，请确保删除它们以及对它们的任何引用[5]。</p>
</li>
</ol>
<h2 id="heading-6kg5yir5yaf5a2y5roe5ryp">识别内存泄漏</h2>
<p>要识别 HTML/JS 应用程序中的内存泄漏，可以使用以下工具和库：</p>
<ol>
<li><p>MemLab： <code>MemLab</code> 是由 Meta（前身为 Facebook）开发的一个开源框架，用于查找 JavaScript 内存泄漏。它能自动检测内存泄漏，并结合特定框架知识来完善泄漏对象列表。<code>MemLab</code> 可以生成驻留追踪（retainer traces），帮助开发人员了解对象未被垃圾回收的原因[6]。</p>
</li>
<li><p>Chrome 开发者工具： Chrome 开发者工具（DevTools） 提供了一系列内存使用情况剖析工具。时间轴视图和配置文件视图（现在是新版 Chrome 浏览器内存面板的一部分）对于发现异常内存模式和识别内存泄漏至关重要。时间轴视图可以显示内存使用量的周期性跳变，而这种跳变在垃圾回收后并不会缩小，从而帮助你发现内存泄漏。分配时间轴/剖析器会周期性拍摄堆快照，帮助你研究可疑的内存分配图[4][7]。</p>
</li>
</ol>
<p>这些工具可以深入了解内存分配和驻留情况，帮助你检测内存泄漏，从而优化代码，提高性能和稳定性。</p>
<blockquote>
<p>参考链接</p>
<p>[1] <a target="_blank" href="https://nolanlawson.com/2020/02/19/fixing-memory-leaks-in-web-applications/">https://nolanlawson.com/2020/02/19/fixing-memory-leaks-in-web-applications/</a></p>
<p>[2] <a target="_blank" href="https://www.ditdot.hr/en/causes-of-memory-leaks-in-javascript-and-how-to-avoid-them">https://www.ditdot.hr/en/causes-of-memory-leaks-in-javascript-and-how-to-avoid-them</a></p>
<p>[3] <a target="_blank" href="https://blog.logrocket.com/escape-memory-leaks-javascript/">https://blog.logrocket.com/escape-memory-leaks-javascript/</a></p>
<p>[4] <a target="_blank" href="https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/">https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/</a></p>
<p>[5] <a target="_blank" href="https://stackoverflow.com/questions/49147182/deleting-html-elements-in-javascript-to-avoid-memory-leaks">https://stackoverflow.com/questions/49147182/deleting-html-elements-in-javascript-to-avoid-memory-leaks</a></p>
<p>[6] <a target="_blank" href="https://engineering.fb.com/2022/09/12/open-source/memlab/">https://engineering.fb.com/2022/09/12/open-source/memlab/</a></p>
<p>[7] <a target="_blank" href="https://www.lambdatest.com/blog/eradicating-memory-leaks-in-javascript/">https://www.lambdatest.com/blog/eradicating-memory-leaks-in-javascript/</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Strategies to prevent/identify memory leaks in HTML/JS]]></title><description><![CDATA[Memory leaks can degrade the performance of your application over time and can lead to crashes or other issues. Therefore, it's important to manage memory effectively in your applications.
Prevent Memory Leaks
To prevent memory leaks in HTML/JS appli...]]></description><link>https://blog.iread.fun/strategies-to-prevent-identify-memory-leaks-in-html-js</link><guid isPermaLink="true">https://blog.iread.fun/strategies-to-prevent-identify-memory-leaks-in-html-js</guid><category><![CDATA[Memory Leak]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[HTML]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Wed, 24 Jan 2024 10:15:40 GMT</pubDate><content:encoded><![CDATA[<p>Memory leaks can degrade the performance of your application over time and can lead to crashes or other issues. Therefore, it's important to manage memory effectively in your applications.</p>
<h2 id="heading-prevent-memory-leaks">Prevent Memory Leaks</h2>
<p>To prevent memory leaks in HTML/JS applications, you can follow these strategies:</p>
<ol>
<li><p><strong>Avoid Unwanted References</strong>: Unwanted references are a common cause of memory leaks. These occur when objects that are no longer needed are still referenced by other parts of your code, preventing the garbage collector from freeing up the memory used by these objects[3].</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">var</span> detachedNode = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'someElement'</span>);
 detachedNode.parentNode.removeChild(detachedNode);
</code></pre>
<p> In the above example, even though <code>someElement</code> has been removed from the DOM, it's still in memory because there's a reference to it in <code>detachedNode</code>.</p>
</li>
<li><p><strong>Proper Event Listener Management</strong>: Not removing event listeners can lead to memory leaks. Always remove event listeners when they are no longer needed.</p>
</li>
<li><p><strong>Avoid Global Variables</strong>: Global variables are not garbage collected as they are in the global scope. If a global variable holds a reference to an object, that object cannot be garbage collected[1].</p>
</li>
<li><p><strong>Avoid Closures that Reference Unneeded Data</strong>: Closures can inadvertently keep references to larger objects or scopes that are no longer needed, leading to memory leaks[1].</p>
<pre><code class="lang-javascript"> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">outerFunction</span>(<span class="hljs-params"></span>) </span>{
     <span class="hljs-keyword">var</span> largeObject = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>(<span class="hljs-number">1000000</span>).fill(<span class="hljs-string">'Memory Leak'</span>);
     <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">innerFunction</span>(<span class="hljs-params"></span>) </span>{
         <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
     }
 }
 <span class="hljs-keyword">var</span> closure = outerFunction();
</code></pre>
<p> In the above example, <code>innerFunction</code> has a closure over the scope of <code>outerFunction</code>, which includes <code>largeObject</code>. Even though <code>largeObject</code> is not used by <code>innerFunction</code>, it's kept in memory as long as <code>innerFunction</code> exists because of the closure.</p>
</li>
<li><p><strong>Avoid Memory Leaks in Third-Party Libraries</strong>: Some third-party libraries may have memory leaks. Always use the latest version of libraries and frameworks, as these versions often have memory leak fixes[1].</p>
</li>
<li><p><strong>Code Review</strong>: Regular code reviews can help catch common memory leak patterns[1].</p>
</li>
<li><p><strong>Delete Unnecessary DOM Elements</strong>: If you create DOM elements dynamically and don't need them later, make sure to remove them and any references to them[5].</p>
</li>
</ol>
<h2 id="heading-identify-memory-leaks">Identify Memory Leaks</h2>
<p>To identify memory leaks in HTML/JS applications, you can use the following tools and libraries:</p>
<ol>
<li><p><strong>MemLab</strong>: MemLab is an open-source framework developed by Meta (formerly Facebook) for finding JavaScript memory leaks. It automates the detection of memory leaks and incorporates framework-specific knowledge to refine the list of leaked objects. MemLab can generate retainer traces to help developers understand why objects are not being garbage collected[6].</p>
</li>
<li><p><strong>Chrome DevTools</strong>: Chrome DevTools provides a set of tools to profile memory usage. The Timeline view and the Profiles view (now part of the Memory panel in newer versions of Chrome) are essential for discovering unusual memory patterns and identifying memory leaks. The Timeline view can help you spot big leaks by showing periodic jumps in memory usage that do not shrink after garbage collection. The Allocation Timeline/Profiler takes heap snapshots periodically and helps you study the graph for suspicious memory allocation[4][7].</p>
</li>
</ol>
<p>These tools can help you detect memory leaks by providing insights into memory allocation and retention, allowing you to optimize your code for better performance and stability.</p>
<blockquote>
<p>Citations:</p>
<p>[1] <a target="_blank" href="https://nolanlawson.com/2020/02/19/fixing-memory-leaks-in-web-applications/">https://nolanlawson.com/2020/02/19/fixing-memory-leaks-in-web-applications/</a></p>
<p>[2] <a target="_blank" href="https://www.ditdot.hr/en/causes-of-memory-leaks-in-javascript-and-how-to-avoid-them">https://www.ditdot.hr/en/causes-of-memory-leaks-in-javascript-and-how-to-avoid-them</a></p>
<p>[3] <a target="_blank" href="https://blog.logrocket.com/escape-memory-leaks-javascript/">https://blog.logrocket.com/escape-memory-leaks-javascript/</a></p>
<p>[4] <a target="_blank" href="https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/">https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/</a></p>
<p>[5] <a target="_blank" href="https://stackoverflow.com/questions/49147182/deleting-html-elements-in-javascript-to-avoid-memory-leaks">https://stackoverflow.com/questions/49147182/deleting-html-elements-in-javascript-to-avoid-memory-leaks</a></p>
<p>[6] <a target="_blank" href="https://engineering.fb.com/2022/09/12/open-source/memlab/">https://engineering.fb.com/2022/09/12/open-source/memlab/</a></p>
<p>[7] <a target="_blank" href="https://www.lambdatest.com/blog/eradicating-memory-leaks-in-javascript/">https://www.lambdatest.com/blog/eradicating-memory-leaks-in-javascript/</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Js 不导致栈溢出的递归函数]]></title><description><![CDATA[堆栈溢出
递归函数（Recursive Function）如果调用自身次数过多，超过栈大小限制，就会导致栈溢出。
一个典型的例子是，用递归函数简陋实现斐波那契数列，如果调用参数过大，将导致栈溢出：
function fibonacci(n) {
  if (n < 2) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

for (let n = 0; n < 100; n++) {
  console.log(`fibo ${n...]]></description><link>https://blog.iread.fun/recursive-functions-dont-casue-stack-overflow-in-js-cn</link><guid isPermaLink="true">https://blog.iread.fun/recursive-functions-dont-casue-stack-overflow-in-js-cn</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Recursive function]]></category><category><![CDATA[asynchronous JavaScript]]></category><category><![CDATA[tail call optimization]]></category><category><![CDATA[call stack]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Mon, 22 Jan 2024 09:23:03 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-5acg5qci5rqi5ye6">堆栈溢出</h2>
<p>递归函数（Recursive Function）如果调用自身次数过多，超过栈大小限制，就会导致栈溢出。</p>
<p>一个典型的例子是，用递归函数简陋实现斐波那契数列，如果调用参数过大，将导致栈溢出：</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fibonacci</span>(<span class="hljs-params">n</span>) </span>{
  <span class="hljs-keyword">if</span> (n &lt; <span class="hljs-number">2</span>) <span class="hljs-keyword">return</span> n;
  <span class="hljs-keyword">return</span> fibonacci(n - <span class="hljs-number">1</span>) + fibonacci(n - <span class="hljs-number">2</span>);
}

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> n = <span class="hljs-number">0</span>; n &lt; <span class="hljs-number">100</span>; n++) {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`fibo <span class="hljs-subst">${n}</span>: <span class="hljs-subst">${fibonacci(n)}</span>`</span>)
}
</code></pre>
<p>这种用递归函数简陋实现的斐波那契数列可能由于大量的冗余计算导致程序运行缓慢。如果输入 <code>n</code> 过大，可能会超过最大调用栈大小，导致栈溢出。</p>
<h2 id="heading-5byc5q2l6ycs5b2s">异步递归</h2>
<p>不过，并非所有多次调用自身的递归函数都会导致栈溢出。</p>
<p>在 JavaScript 中，当每次递归调用都被放在当前执行上下文完成后运行，就会发生异步递归。 例如使用 <code>setTimeout</code>、<code>setInterval</code> 或异步函数（<code>Promise/async/await</code>）时。这里是一个使用 <code>setTimeout</code> 的示例：</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">asyncRecursiveFunction</span>(<span class="hljs-params">n</span>) </span>{
  <span class="hljs-keyword">if</span> (n &gt; <span class="hljs-number">0</span>) {
    <span class="hljs-built_in">console</span>.log(n);
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> asyncRecursiveFunction(n - <span class="hljs-number">1</span>), <span class="hljs-number">1000</span>);
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Done'</span>);
  }
}

asyncRecursiveFunction(<span class="hljs-number">5</span>);
<span class="hljs-comment">/*
5
4
3
2
1
Done
*/</span>
</code></pre>
<p>下面是另一个使用 Promise 的示例：</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sleep</span>(<span class="hljs-params">ms</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-params">resolve</span> =&gt;</span> <span class="hljs-built_in">setTimeout</span>(resolve, ms));
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sleepList</span>(<span class="hljs-params">ts1, ts2, sleepID = <span class="hljs-number">0</span></span>) </span>{
  <span class="hljs-keyword">if</span> (ts1 &gt;= ts2) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Finished processing array'</span>);
    <span class="hljs-keyword">return</span>;
  }

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`sleep <span class="hljs-subst">${sleepID}</span> begin <span class="hljs-subst">${ts1}</span>ms`</span>);

  sleep(ts1)
    .then(<span class="hljs-function"><span class="hljs-params">s</span> =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`sleep <span class="hljs-subst">${sleepID}</span> end <span class="hljs-subst">${ts1}</span>ms`</span>);
      sleepList(ts1 + <span class="hljs-number">1</span>, ts2, sleepID + <span class="hljs-number">1</span>);
    });
}

sleepList(<span class="hljs-number">1000</span>, <span class="hljs-number">1005</span>);
<span class="hljs-comment">/*
sleep 0 begin 1000ms
sleep 0 end 1000ms
sleep 1 begin 1001ms
sleep 1 end 1001ms
sleep 2 begin 1002ms
sleep 2 end 1002ms
sleep 3 begin 1003ms
sleep 3 end 1003ms
sleep 4 begin 1004ms
sleep 4 end 1004ms
Finished processing array
*/</span>
</code></pre>
<h2 id="heading-tail-call-optimizationtco">尾递归优化 (Tail Call Optimization，TCO)</h2>
<p>尾递归优化是指一个函数的最后一个操作是调用另一个函数（或自身），而当前函数的栈帧可以被新函数的栈帧所替代。这可以防止每次递归调用都导致栈增长。不同的编程语言及其编译器对尾递归优化的支持各不相同。当启用优化标记时，某些编译器（如 GCC）会在某些场景下消除尾部调用。</p>
<p>截至 2023 年，JavaScript 环境尚未广泛支持尾递归优化。</p>
<blockquote>
<p><a target="_blank" href="https://stackoverflow.com/questions/37224520/are-functions-in-javascript-tail-call-optimized">https://stackoverflow.com/questions/37224520/are-functions-in-javascript-tail-call-optimized</a></p>
<p><a target="_blank" href="https://stackoverflow.com/questions/37224520/are-functions-in-javascript-tail-call-optimized">https://stackoverflow.com/questions/54719548/tail-call-optimization-implementation-in-javascript-engines</a></p>
<p><a target="_blank" href="https://stackoverflow.com/questions/37224520/are-functions-in-javascript-tail-call-optimized">https://www.reddit.com/r/javascript/comments/pwwbky/askjs_why_so_little_support_for_tco_tail_call/</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Recursive functions don't casue stack overflow  in JS]]></title><description><![CDATA[Stack Overflow
Recursive functions can cause a stack overflow if they call themselves too many times and exceed the stack size limit.
A classic example of a recursive function that can exceed the stack size limit if called with a large input is the n...]]></description><link>https://blog.iread.fun/recursive-functions-dont-casue-stack-overflow-in-js</link><guid isPermaLink="true">https://blog.iread.fun/recursive-functions-dont-casue-stack-overflow-in-js</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Recursive function]]></category><category><![CDATA[asynchronous JavaScript]]></category><category><![CDATA[tail call optimization]]></category><category><![CDATA[call stack]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Mon, 22 Jan 2024 08:56:35 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-stack-overflow">Stack Overflow</h2>
<p>Recursive functions can cause a stack overflow if they call themselves too many times and exceed the stack size limit.</p>
<p>A classic example of a recursive function that can exceed the stack size limit if called with a large input is the naive implementation of the Fibonacci sequence:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fibonacci</span>(<span class="hljs-params">n</span>) </span>{
  <span class="hljs-keyword">if</span> (n &lt; <span class="hljs-number">2</span>) <span class="hljs-keyword">return</span> n;
  <span class="hljs-keyword">return</span> fibonacci(n - <span class="hljs-number">1</span>) + fibonacci(n - <span class="hljs-number">2</span>);
}

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> n = <span class="hljs-number">0</span>; n &lt; <span class="hljs-number">100</span>; n++) {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`fibo <span class="hljs-subst">${n}</span>: <span class="hljs-subst">${fibonacci(n)}</span>`</span>)
}
</code></pre>
<p>This naive implementation of the Fibonacci sequence can cause a program to run slowly due to the large number of redundant computations. If the input <code>n</code> is too large, it can exceed the maximum call stack size and cause a stack overflow.</p>
<h2 id="heading-asynchronous-recursion">Asynchronous Recursion</h2>
<p>However, not all recursive functions that call themselves multiple times will causing a stack overflow.</p>
<p>In JavaScript, asynchronous recursion can occur when each recursive call is scheduled to run after the current execution context has completed, such as when using <code>setTimeout</code>, <code>setInterval</code>, or asynchronous functions (<code>Promise/async/await</code>). Here's an example using <code>setTimeout</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">asyncRecursiveFunction</span>(<span class="hljs-params">n</span>) </span>{
  <span class="hljs-keyword">if</span> (n &gt; <span class="hljs-number">0</span>) {
    <span class="hljs-built_in">console</span>.log(n);
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> asyncRecursiveFunction(n - <span class="hljs-number">1</span>), <span class="hljs-number">1000</span>);
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Done'</span>);
  }
}

asyncRecursiveFunction(<span class="hljs-number">5</span>);
<span class="hljs-comment">/*
5
4
3
2
1
Done
*/</span>
</code></pre>
<p>Here's another example using <code>Promise</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sleep</span>(<span class="hljs-params">ms</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-params">resolve</span> =&gt;</span> <span class="hljs-built_in">setTimeout</span>(resolve, ms));
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sleepList</span>(<span class="hljs-params">ts1, ts2, sleepID = <span class="hljs-number">0</span></span>) </span>{
  <span class="hljs-keyword">if</span> (ts1 &gt;= ts2) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Finished processing array'</span>);
    <span class="hljs-keyword">return</span>;
  }

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`sleep <span class="hljs-subst">${sleepID}</span> begin <span class="hljs-subst">${ts1}</span>ms`</span>);

  sleep(ts1)
    .then(<span class="hljs-function"><span class="hljs-params">s</span> =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`sleep <span class="hljs-subst">${sleepID}</span> end <span class="hljs-subst">${ts1}</span>ms`</span>);
      sleepList(ts1 + <span class="hljs-number">1</span>, ts2, sleepID + <span class="hljs-number">1</span>);
    });
}

sleepList(<span class="hljs-number">1000</span>, <span class="hljs-number">1005</span>);
<span class="hljs-comment">/*
sleep 0 begin 1000ms
sleep 0 end 1000ms
sleep 1 begin 1001ms
sleep 1 end 1001ms
sleep 2 begin 1002ms
sleep 2 end 1002ms
sleep 3 begin 1003ms
sleep 3 end 1003ms
sleep 4 begin 1004ms
sleep 4 end 1004ms
Finished processing array
*/</span>
</code></pre>
<h2 id="heading-tail-call-optimization-tco">Tail Call Optimization (TCO)</h2>
<p>Tail call optimization is a feature where the last action of a function is a call to another function (or itself), and the current function's stack frame can be replaced with the new function's stack frame. This prevents the stack from growing with each recursive call. The support for Tail Call Optimization (TCO) varies across different programming languages and their compilers. Some compilers, such as GCC, have been known to perform tail call elimination in certain cases when optimization flags are used.</p>
<p>As of 2023, TCO is not widely supported in JavaScript environments.</p>
<blockquote>
<p><a target="_blank" href="https://stackoverflow.com/questions/37224520/are-functions-in-javascript-tail-call-optimized">https://stackoverflow.com/questions/37224520/are-functions-in-javascript-tail-call-optimized</a></p>
<p><a target="_blank" href="https://stackoverflow.com/questions/54719548/tail-call-optimization-implementation-in-javascript-engines">https://stackoverflow.com/questions/54719548/tail-call-optimization-implementation-in-javascript-engines</a></p>
<p><a target="_blank" href="https://www.reddit.com/r/javascript/comments/pwwbky/askjs_why_so_little_support_for_tco_tail_call/">https://www.reddit.com/r/javascript/comments/pwwbky/askjs_why_so_little_support_for_tco_tail_call/</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Node.js 从列表中查找最快的 HTTP/2 DoH 服务器]]></title><description><![CDATA[对 DoH（DNS over HTTPS）来说 HTTP/2 尤其有效，因为 HTTP/2 支持多路复用，允许在同一连接上发送多个 DNS 查询，而无需等待之前的响应。这可以大大提高 DNS 解析的性能，尤其是在同时进行多个查询时。
网络上有数百个公开可用的 DoH 服务器，我们可以使用 Node.js HTTP/2 模块来查找在一定阈值（如 1 秒）内响应最快的服务器。
首先，让我们定义一个函数 check_url，它将返回一个 promise，并在 HTTP/2 请求成功时转为 resolv...]]></description><link>https://blog.iread.fun/nodejs-find-fastest-http2-servers-from-doh-list-cn</link><guid isPermaLink="true">https://blog.iread.fun/nodejs-find-fastest-http2-servers-from-doh-list-cn</guid><category><![CDATA[http2]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[DNS over https]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Fri, 19 Jan 2024 13:05:30 GMT</pubDate><content:encoded><![CDATA[<p>对 DoH（DNS over HTTPS）来说 HTTP/2 尤其有效，因为 HTTP/2 支持多路复用，允许在同一连接上发送多个 DNS 查询，而无需等待之前的响应。这可以大大提高 DNS 解析的性能，尤其是在同时进行多个查询时。</p>
<p>网络上有数百个公开可用的 DoH 服务器，我们可以使用 Node.js HTTP/2 模块来查找在一定阈值（如 1 秒）内响应最快的服务器。</p>
<p>首先，让我们定义一个函数 <code>check_url</code>，它将返回一个 promise，并在 HTTP/2 请求成功时转为 resolve 状态。</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> http2 = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http2'</span>);

<span class="hljs-keyword">const</span> timeoutDuration = <span class="hljs-number">1000</span>; <span class="hljs-comment">// 1 seconds</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">check_url</span>(<span class="hljs-params">URL</span>) </span>{

    <span class="hljs-keyword">let</span> fnResolve, fnReject;
    <span class="hljs-keyword">let</span> myPromise = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {

        fnResolve = resolve;
        fnReject = reject;
    });

    <span class="hljs-keyword">const</span> client = http2.connect(URL);<span class="hljs-comment">//https://dns.alidns.com , https://dns.quad9.net</span>

    <span class="hljs-keyword">const</span> req = client.request({ <span class="hljs-string">':path'</span>: <span class="hljs-string">'/dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB'</span> });

    req.on(<span class="hljs-string">'response'</span>, <span class="hljs-function">(<span class="hljs-params">headers, flags</span>) =&gt;</span> {
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> name <span class="hljs-keyword">in</span> headers) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${name}</span>: <span class="hljs-subst">${headers[name]}</span>`</span>);
        }

        fnResolve(<span class="hljs-string">'    '</span> + URL);
    });

    <span class="hljs-keyword">return</span> myPromise;
}
</code></pre>
<p>让我们添加一些处理逻辑，当错误或超时发生时将 promise 转为 reject 状态。</p>
<pre><code class="lang-javascript">    req.on(<span class="hljs-string">'error'</span>, <span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'ClientHttp2Stream error: '</span> + err);
        req.close(http2.constants.NGHTTP2_CANCEL);

        fnReject(<span class="hljs-string">'!!! '</span> + URL)
    });

    <span class="hljs-comment">// Set a timeout on the request</span>
    req.setTimeout(timeoutDuration, <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">`ClientHttp2Stream <span class="hljs-subst">${URL}</span> timed out`</span>);

        req.destroy();

        fnReject(<span class="hljs-string">'--- '</span> + URL)
    });
</code></pre>
<p>最后，添加一个处理函数，在请求流完成并关闭时同时关闭 HTTP/2 连接（请记住，HTTP/2 允许在同一连接上进行多个并发流，因此连接不会自动关闭）。</p>
<pre><code class="lang-javascript">req.on(<span class="hljs-string">'close'</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log( <span class="hljs-string">'ClientHttp2Stream is closed'</span> )
    client.close();
})
</code></pre>
<p>现在，我们可以使用递归函数逐个检查列表中的 url，并返回响应时间在 1 秒以内的最快服务器。</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> dohs = [<span class="hljs-string">"https://dns.google/dns-query"</span>,
    <span class="hljs-string">"https://cloudflare-dns.com/dns-query"</span>,
    <span class="hljs-string">"https://dns.alidns.com/dns-query"</span>,
    <span class="hljs-string">"https://dns.quad9.net/dns-query"</span>];

<span class="hljs-comment">/*
* check_next check doh[index], then doh[++index]...
* show: 
*      0 show urls response within timeoutDuration
*      1 show urls response great than timeoutDuration
*      2 don't show urls, for debug
*/</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">check_next</span>(<span class="hljs-params">index = <span class="hljs-number">0</span>, { show = <span class="hljs-number">0</span> } = {}</span>) </span>{
    <span class="hljs-keyword">if</span> (index &gt;= dohs.length || index &lt; <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span>;

    check_url(dohs[index])
        .then(<span class="hljs-function"><span class="hljs-params">URL</span> =&gt;</span> { <span class="hljs-keyword">if</span> (<span class="hljs-number">0</span> === show) <span class="hljs-built_in">console</span>.log(URL) })
        .catch(<span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> { <span class="hljs-keyword">if</span> (<span class="hljs-number">1</span> === show) <span class="hljs-built_in">console</span>.log(error) })
        .finally(<span class="hljs-function">() =&gt;</span> {
            <span class="hljs-comment">//only check_next when last check is done</span>
            check_next(++index, { show })
        });
}

check_next(<span class="hljs-number">0</span>, { <span class="hljs-attr">show</span>: <span class="hljs-number">0</span> })
</code></pre>
<p>运行 Node 代码，获取最快服务器列表</p>
<pre><code class="lang-bash">node find-fastest-doh-servers.js
<span class="hljs-comment"># 输出结果</span>
<span class="hljs-comment">#    https://dns.alidns.com/dns-query</span>
<span class="hljs-comment">#    https://dns.quad9.net/dns-query</span>
</code></pre>
<p>完整代码在 GitHub Gist 上面</p>
<blockquote>
<p><a target="_blank" href="https://gist.github.com/likev/7c26cec0103b3187ddcb793f94ae593c">https://gist.github.com/likev/7c26cec0103b3187ddcb793f94ae593c</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Node.js Find Fastest HTTP/2 Servers from DoH List]]></title><description><![CDATA[HTTP/2 is particularly beneficial for DoH(DNS over HTTPS) because it allows multiple DNS queries to be sent over the same connection without waiting for previous responses, thanks to its support for multiplexing. This can significantly improve the pe...]]></description><link>https://blog.iread.fun/nodejs-find-fastest-http2-servers-from-doh-list</link><guid isPermaLink="true">https://blog.iread.fun/nodejs-find-fastest-http2-servers-from-doh-list</guid><category><![CDATA[Node.js]]></category><category><![CDATA[http2]]></category><category><![CDATA[DNS over https]]></category><dc:creator><![CDATA[v like]]></dc:creator><pubDate>Fri, 19 Jan 2024 12:49:08 GMT</pubDate><content:encoded><![CDATA[<p>HTTP/2 is particularly beneficial for DoH(DNS over HTTPS) because it allows multiple DNS queries to be sent over the same connection without waiting for previous responses, thanks to its support for multiplexing. This can significantly improve the performance of DNS resolutions, especially when multiple queries are being made.</p>
<p>When hundreds of servers are publicly available, we can use the Node.js HTTP/2 module to find the fastest ones that respond within duration (such as 1s).</p>
<p>First, let's define a function <code>check_url</code> that returns a promise and resolves if the HTTP/2 request is successful.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> http2 = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http2'</span>);

<span class="hljs-keyword">const</span> timeoutDuration = <span class="hljs-number">1000</span>; <span class="hljs-comment">// 1 seconds</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">check_url</span>(<span class="hljs-params">URL</span>) </span>{

    <span class="hljs-keyword">let</span> fnResolve, fnReject;
    <span class="hljs-keyword">let</span> myPromise = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {

        fnResolve = resolve;
        fnReject = reject;
    });

    <span class="hljs-keyword">const</span> client = http2.connect(URL);<span class="hljs-comment">//https://dns.alidns.com , https://dns.quad9.net</span>

    <span class="hljs-keyword">const</span> req = client.request({ <span class="hljs-string">':path'</span>: <span class="hljs-string">'/dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB'</span> });

    req.on(<span class="hljs-string">'response'</span>, <span class="hljs-function">(<span class="hljs-params">headers, flags</span>) =&gt;</span> {
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> name <span class="hljs-keyword">in</span> headers) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${name}</span>: <span class="hljs-subst">${headers[name]}</span>`</span>);
        }

        fnResolve(<span class="hljs-string">'    '</span> + URL);
    });

    <span class="hljs-keyword">return</span> myPromise;
}
</code></pre>
<p>Let's also add logic to reject the promise if an error or timeout occurs.</p>
<pre><code class="lang-javascript">    req.on(<span class="hljs-string">'error'</span>, <span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'ClientHttp2Stream error: '</span> + err);
        req.close(http2.constants.NGHTTP2_CANCEL);

        fnReject(<span class="hljs-string">'!!! '</span> + URL)
    });

    <span class="hljs-comment">// Set a timeout on the request</span>
    req.setTimeout(timeoutDuration, <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">`ClientHttp2Stream <span class="hljs-subst">${URL}</span> timed out`</span>);

        req.destroy();

        fnReject(<span class="hljs-string">'--- '</span> + URL)
    });
</code></pre>
<p>Finally, add a deal function to close the HTTP/2 connection when the request stream is complete and close (remember that HTTP/2 allows multiple concurrent exchanges on the same connection, so the connection will not close automatically).</p>
<pre><code class="lang-javascript">req.on(<span class="hljs-string">'close'</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log( <span class="hljs-string">'ClientHttp2Stream is closed'</span> )
    client.close();
})
</code></pre>
<p>Now we can use a recursive function to check urls from a list one by one and return the fastest server that responds under 1s.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> dohs = [<span class="hljs-string">"https://dns.google/dns-query"</span>,
    <span class="hljs-string">"https://cloudflare-dns.com/dns-query"</span>,
    <span class="hljs-string">"https://dns.alidns.com/dns-query"</span>,
    <span class="hljs-string">"https://dns.quad9.net/dns-query"</span>];

<span class="hljs-comment">/*
* check_next check doh[index], then doh[++index]...
* show: 
*      0 show urls response within timeoutDuration
*      1 show urls response great than timeoutDuration
*      2 don't show urls, for debug
*/</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">check_next</span>(<span class="hljs-params">index = <span class="hljs-number">0</span>, { show = <span class="hljs-number">0</span> } = {}</span>) </span>{
    <span class="hljs-keyword">if</span> (index &gt;= dohs.length || index &lt; <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span>;

    check_url(dohs[index])
        .then(<span class="hljs-function"><span class="hljs-params">URL</span> =&gt;</span> { <span class="hljs-keyword">if</span> (<span class="hljs-number">0</span> === show) <span class="hljs-built_in">console</span>.log(URL) })
        .catch(<span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> { <span class="hljs-keyword">if</span> (<span class="hljs-number">1</span> === show) <span class="hljs-built_in">console</span>.log(error) })
        .finally(<span class="hljs-function">() =&gt;</span> {
            <span class="hljs-comment">//only check_next when last check is done</span>
            check_next(++index, { show })
        });
}

check_next(<span class="hljs-number">0</span>, { <span class="hljs-attr">show</span>: <span class="hljs-number">0</span> })
</code></pre>
<p>Run node code and get the fastest list</p>
<pre><code class="lang-bash">node find-fastest-doh-servers.js
<span class="hljs-comment"># output</span>
<span class="hljs-comment">#    https://dns.alidns.com/dns-query</span>
<span class="hljs-comment">#    https://dns.quad9.net/dns-query</span>
</code></pre>
<p>The full code can be found on GitHub Gist</p>
<blockquote>
<p><a target="_blank" href="https://gist.github.com/likev/7c26cec0103b3187ddcb793f94ae593c">https://gist.github.com/likev/7c26cec0103b3187ddcb793f94ae593c</a></p>
</blockquote>
]]></content:encoded></item></channel></rss>