diff --git a/common-content/en/blocks/prep-dir/index.md b/common-content/en/blocks/prep-dir/index.md index ad274adef..b70533ce0 100644 --- a/common-content/en/blocks/prep-dir/index.md +++ b/common-content/en/blocks/prep-dir/index.md @@ -1,5 +1,5 @@ +++ -title = 'Prep dir' +title = 'Prep Directory' time = 10 [objectives] 1='Create a working prep directory for the module' @@ -9,18 +9,14 @@ time = 10 publishResources = false +++ -### ๐Ÿ“‚ Create a working directory for the module +We will provide some code examples as you progress through the course but you will also write a lot of code yourself. You're going to need somewhere in your system to store it all. -1. Fork the coursework module (always linked in every backlog) and open it in VSCode. -1. In your VSCode terminal, navigate to the root of your project directory. -1. Create a new directory called `prep` to store all the files you'll be working on for this module. +### Create a working directory for the module -As you work through the module, you'll be creating files in this directory to code along with the prep content. You are expected to code along with the prep content. - -For simple one liners, use the terminal REPL to run the code. For more complex problems, create files in the `prep` directory and write the code there. Make commented notes as you go along explaining why you're doing what you're doing. Your future self will thank you. +1. Fork the coursework module (always linked in every backlog), clone it to your laptop and open it in VSCode. +2. In your VSCode terminal, navigate to the root of your project directory. +3. Create a new directory called `prep` to store all the files you'll be working on for this module. -### ๐Ÿ”‘ The most important thing is to secure your understanding - -The prep content is designed to help you understand the concepts you'll be working with in the module. Don't just read it, code along with it. Also take notes, draw diagrams, pose your own questions and try to answer them. +As you work through the module, you'll be creating files in this directory to code along with the prep content. You are expected to code along with the prep content. -To really understand programming, you need to write the code yourself, and do the exercises. You must [take active part](https://www.pnas.org/doi/10.1073/pnas.1319030111) in your learning to succeed. +You will need to do this at the start of every module. We suggest adding further sub-directories for each sprint but it's up to you to organise your files in a way that suits you. For more complex problems you may need to create further sub-directories and write the code there. Try making notes as you go to document the process. Having your own notes will be very useful if you need to remind yourself how to do something in future! diff --git a/common-content/en/module/induction/accounts/index.md b/common-content/en/module/induction/accounts/index.md index 4a918aa7f..d47714bc9 100644 --- a/common-content/en/module/induction/accounts/index.md +++ b/common-content/en/module/induction/accounts/index.md @@ -52,7 +52,7 @@ You will use [GitHub](https://github.com/signup) to store your code and to colla ### LinkedIn -Sign up for LinkedIn. LinkedIn is the largest professional social network. You will use it to help you get a job and to advance your career. +Sign up for [LinkedIn](https://www.linkedin.com/). LinkedIn is the largest professional social network. You will use it to help you get a job and to advance your career. Make a LinkedIn account. Use your real name. Sign in with Google. Connect with your cohort. @@ -79,8 +79,6 @@ See this example fully filled-in Slack profile - make sure yours has at least th ## Applications -If you're working on a library computer, you can't download these applications. You will use [GitHub Dev](https://github.dev/) to complete coursework instead. - ### Google Chrome - [ ] I have downloaded and installed Google Chrome. @@ -90,12 +88,12 @@ Use your professional Chrome profile for all your {{}} work. You will ### VSCode -We will use [Visual Studio Code](https://code.visualstudio.com/) (VSCode), a professional IDE you will use on this course and at work. +We will use [Visual Studio Code](https://code.visualstudio.com/) (VSCode), a customisable text editor you will use on this course and at work. If you are new to using tools like VSCode there are [video resources](https://www.youtube.com/watch?v=B-s71n0dHUk) which can help you familiarise yourself with the interface. - [ ] I have downloaded and installed [Visual Studio Code](https://code.visualstudio.com/). ### Zoom -Usually we use [Meet](https://applieddigitalskills.withgoogle.com/c/college-and-continuing-education/en/google-meet-for-beginners/overview.html), but sometimes we use [Zoom for remote sessions](https://zoom.us/download). Install it now. +Usually we use [Meet](https://applieddigitalskills.withgoogle.com/c/college-and-continuing-education/en/google-meet-for-beginners/overview.html), but sometimes we use [Zoom for remote sessions](https://zoom.us/download). If you are using a library computer you can use the web version, if you are using your own computer you should install it now. - [ ] I have downloaded and installed [Zoom](https://zoom.us/download) onto my computer. diff --git a/common-content/en/module/induction/branching/index.md b/common-content/en/module/induction/branching/index.md index 1d22865a9..d7c42f9e7 100644 --- a/common-content/en/module/induction/branching/index.md +++ b/common-content/en/module/induction/branching/index.md @@ -16,11 +16,13 @@ We can check the commits on the remote repository as before: ![commit-history](commit-history.png) +> When you check the history today your view will be slightly different. The commits in the screenshot will still be there, but there will be newer commits too. + On the left page of the page, we see additional information: ![main-branch-highlighted](main-branch-highlighted.png) -> So what is **`main`**? +So what is `main`? `main` is a **branch**. @@ -35,7 +37,7 @@ gitGraph A branch represents a particular history of development in a project - the different versions there have been. -{{}} +{{}} A **branch** is a sequence of commits in a project. @@ -50,14 +52,18 @@ gitGraph commit commit branch "try-purple" + checkout "try-purple" commit commit checkout main branch "try-blue" commit + checkout main + commit + commit ``` -The **`main`** branch is often treated as a special branch - it's where we put commits which people working on the project have agreed on. Other branches (e.g. the experimental purple branch) may have extra changes that have not been agreed on. If people working on the project agree the changes from the purple branch are good, we'll add those changes to the main branch. +The `main` branch is often treated as a special branch - it's where we put commits which people working on the project have agreed on. Other branches (e.g. the `try-purple` branch) may have extra changes that have not been agreed on. If people working on the project agree the changes from the purple branch are good, we'll add those changes to the main branch. When we're working on something new, we haven't agreed with other people that our new thing is good yet, so we often don't add our changes to the main branch straight away. Instead we make our own branch to experiment on. @@ -75,13 +81,11 @@ gitGraph In the diagram above, we can continue to commit on the "week-1-coursework" branch without altering the history of the `main` branch. -{{}} - -### Creating a local branch +{{}} 1. Open the `education-blog` repository in VSCode. -2. Using this clip, create a new branch called `update-blog-1` in your local repository ๐Ÿ‘‰ https://youtube.com/clip/UgkxvXsnm_98Rx0NUZq25apQWA6POccRoQzw +2. Using [this clip](https://youtube.com/clip/UgkxvXsnm_98Rx0NUZq25apQWA6POccRoQzw), create a new branch called `update-blog-1` in your local repository. ๐Ÿ“‹ How can you check that you've successfully created a branch? diff --git a/common-content/en/module/induction/check-git-installation/index.md b/common-content/en/module/induction/check-git-installation/index.md index d6290c6af..e55465f70 100644 --- a/common-content/en/module/induction/check-git-installation/index.md +++ b/common-content/en/module/induction/check-git-installation/index.md @@ -1,9 +1,9 @@ +++ -title = 'Check Git installation' +title = 'Check Git Installation' time = 15 vocabulary=[] [tasks] -1='Double check Git is installed on your local machine' +1='Check Git is installed on your local machine' [build] render = 'never' list = 'local' @@ -13,9 +13,15 @@ vocabulary=[] ### Git -You will use Git continually as a developer. We will cover Git in more depth later in the course. Right now, we will just check that you have it installed. +{{}} -Open up a terminal and run the command `git --version` to double check you have Git installed. +Git is **version control software** that allows developers to create and manage different versions of a project. + +{{}} + +You will use Git continually as a developer. Before we can do any work with it we need to check that you have it installed. + +Open your computer's terminal application and run the command `git --version` to double check you have Git installed. If it is installed successfully, you should get a version number (which may not be exactly the same as this example, but should look similar): ``` @@ -23,6 +29,3 @@ git version 2.40.0 ``` Otherwise, you will need to [install](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) it or ask for support on your Slack channel. - -> [!TIP] -> If you are working on a library computer, you do not have a terminal, but your github.dev account already has Git installed. (It's called "Source Control".) So you can skip this step. diff --git a/common-content/en/module/induction/checkout-a-commit/index.md b/common-content/en/module/induction/checkout-a-commit/index.md index 22173da0a..007fc9c99 100644 --- a/common-content/en/module/induction/checkout-a-commit/index.md +++ b/common-content/en/module/induction/checkout-a-commit/index.md @@ -16,7 +16,7 @@ Recall that a commit is a snapshot of our project at some point in time. Therefore, we should be able to check out a previous version of our project and look at the files and folders there. We can use the Github interface to check out the files and folders at a previous commit. -{{}} +{{}} Go back to this page https://github.com/CodeYourFuture/education-blog/commits/main diff --git a/common-content/en/module/induction/cyf-blog/index.md b/common-content/en/module/induction/cyf-blog/index.md index 90f74d335..211642be6 100644 --- a/common-content/en/module/induction/cyf-blog/index.md +++ b/common-content/en/module/induction/cyf-blog/index.md @@ -1,5 +1,5 @@ +++ -title = 'Blog' +title = 'CYF Blog' time ="5" hide_from_overview = true [build] @@ -14,6 +14,6 @@ Ahmed and Naima are writing a blog together about their struggles learning codin The published blog is live here ๐Ÿ‘‰ [Educational blog](https://git-demo-week1.netlify.app/) -{{}} +{{}} Explore the [Educational blog](https://git-demo-week1.netlify.app/). Click on the link on the site and check to see if it is working. {{}} diff --git a/common-content/en/module/induction/development-process/index.md b/common-content/en/module/induction/development-process/index.md index 96f49350d..6463c9e7e 100644 --- a/common-content/en/module/induction/development-process/index.md +++ b/common-content/en/module/induction/development-process/index.md @@ -11,15 +11,15 @@ hide_from_overview = true Ahmed and Naima are using the following **development process** for writing their blog: -> - writing the blog in a single file on a **single** computer -> - saving multiple versions of the file on the same computer -> - taking turns to use the computer during the day +- Writing the blog in a single file on a **single** computer +- Saving multiple versions of the file on the same computer +- Taking turns to use the computer during the day At the moment, the computer has a folder with the blog that looks like this: ![different-blog-versions](different-blog-versions.png) -{{}} +{{}} Describe some of the challenges that Ahmed and Naima face when trying to write a blog together in this way. diff --git a/common-content/en/module/induction/dot-dev/index.md b/common-content/en/module/induction/dot-dev/index.md deleted file mode 100644 index a4ea19877..000000000 --- a/common-content/en/module/induction/dot-dev/index.md +++ /dev/null @@ -1,23 +0,0 @@ -+++ -title = 'GitHub.dev' -description = 'Completing coursework on a library computer' -time = 20 -[objectives] -1='Access the dotdev environment on a library computer if you do not have your own' -[build] - render = 'never' - list = 'local' - publishResources = false - -+++ - -If you do not have a computer of your own yet, here's how to complete your work directly on GitHub without a local environment. - -Each repo on GitHub has a `.dev` environment so you can edit the code in your browser using an online VSCode. - -You can go to this environment directly by replacing `github.com` with `github.dev` in the URL. For example, to open the [`Module-Onboarding`](https://github.com/CodeYourFuture/Module-Onboarding) repo, you can go to - -https://github.dev/CodeYourFuture/Module-Onboarding - -> [!TIP] -> If you do have a computer, you should set up VSCode and a local environment. This is a workaround for people who don't yet have the luxury of a personal computer. diff --git a/common-content/en/module/induction/forking-a-repository/index.md b/common-content/en/module/induction/forking-a-repository/index.md index 9661e4c3a..1a2bf7385 100644 --- a/common-content/en/module/induction/forking-a-repository/index.md +++ b/common-content/en/module/induction/forking-a-repository/index.md @@ -12,11 +12,15 @@ time ="10" Often we want to take an existing project and start working on it independently. In other words: we start making our own versions of the project separate from the original project. -We can create a {{}}A **fork** is a copy of a repository that exists on Github{{}}. +We can create a **fork**. A fork is a copy of a repository that exists on Github. -When we create a fork on Github, the new forked repository gets a new url: +A GitHub repository's url looks like this: -#### https://github.com/CodeYourFuture/cyf-demo-repo +``` +https://github.com/CodeYourFuture/cyf-demo-repo +``` + +Like any url it is made up of different parts. ```mermaid flowchart LR @@ -52,13 +56,11 @@ flowchart LR C --> D[cyf-demo-repo] ``` -{{}} - -### ๐Ÿด Fork a repo +{{}} 1. Go to https://github.com/CodeYourFuture/education-blog. -1. Find the **Fork** button on this page. -1. Click on the Fork button to create a new fork of the repository and set yourself as the owner of the fork. +2. Find the **Fork** button on this page. +3. Click on the Fork button to create a new fork of the repository and set yourself as the owner of the fork. ๐Ÿ“‹ How can you check you successfully forked the original repository? diff --git a/common-content/en/module/induction/previous-versions/index.md b/common-content/en/module/induction/previous-versions/index.md index 09f7a7b6f..8d77cc25f 100644 --- a/common-content/en/module/induction/previous-versions/index.md +++ b/common-content/en/module/induction/previous-versions/index.md @@ -9,34 +9,22 @@ time ="20" +++ -We can view the different commits of a project on Github. This means we can see what the website looked like before, in previous versions. +We can view the different commits of a project on Github. This means we can see what an application looked like before, in previous versions. -{{}} -Here are some different versions of the same educational backlog. +{{}} +Here are some different versions of the educational blog we introduced in the previous module. [Deployed version A educational blog](https://git-demo-week1-version-a.netlify.app/) - - [Deployed version B educational blog](https://git-demo-week1-version-b.netlify.app/) - - [Deployed version C educational blog](https://git-demo-week1-version-c.netlify.app/) - - #### Questions 1. What is the difference between Version A and Version B on the index page (the page you first land on after clicking on the link) 1. What is the difference between Version C and the main version of the site. -1. Which commit from the [**education-blog**](https://github.com/CodeYourFuture/education-blog/commits/main) repo correspond to Version C? Remember to check the git history. -1. Which commit from the [**education-blog**](https://github.com/CodeYourFuture/education-blog/commits/main) repo correspond to Version A? +1. Which commit from the [**education-blog**](https://github.com/CodeYourFuture/education-blog/commits/main) repo corresponds to Version C? Remember to check the git history. +1. Which commit from the [**education-blog**](https://github.com/CodeYourFuture/education-blog/commits/main) repo corresponds to Version A? {{}} diff --git a/common-content/en/module/induction/sharing-history/index.md b/common-content/en/module/induction/sharing-history/index.md index eda3b612a..ea833a07e 100644 --- a/common-content/en/module/induction/sharing-history/index.md +++ b/common-content/en/module/induction/sharing-history/index.md @@ -12,9 +12,7 @@ time="30" +++ -Earlier on, Ahmed and Naima realised they also need the following: - -> a way to share the history of the project between different users and different computers +Earlier on, Ahmed and Naima realised they also need a way to share the history of the project between different users and different computers. To share a project and its history, we can use an online platform called **GitHub** @@ -26,15 +24,13 @@ By storing projects on GitHub, multiple users can gain access to the history of On GitHub we call our project and its history a **repository**. {{}} -{{}} - -### Explore ๐Ÿ” +{{}} In this exercise, you'll need to explore a **GitHub repository.** You'll need to look around and figure out where to find different files and find out information about them. -**โš ๏ธ You won't be expected to know what the files do at this stage.** +**You won't be expected to know what the files do at this stage.** Go to the following link: https://github.com/CodeYourFuture/education-blog @@ -42,44 +38,34 @@ It will take you to a GitHub repository called **education-blog**. Answer the following questions using the page linked to above: -a) View the **README.md** file. What do the instructions tell you? -b) How many files are there inside the `blogs` folder? -c) How many lines are there in the **package.json** file? -d) Find the file with the blog content you can see on the live site here [blog 1](https://git-demo-week1.netlify.app/blogs/1) +1. View the **README.md** file. What do the instructions tell you? +2. How many files are there inside the `blogs` folder? +3. How many lines are there in the **package.json** file? +4. Find the file with the blog content you can see on the live site here [blog 1](https://git-demo-week1.netlify.app/blogs/1) You'll learn more about these type of files throughout the course. {{}} -> We can use the Github interface to explore the different **commits** (versions) of a project too. +We can use the Github interface to explore the different **commits** (versions) of a project too. -{{}} - -### Explore ๐Ÿ” +{{}} Go to the following link: https://github.com/CodeYourFuture/education-blog/commits/main -Try answering the following questions: - -Go to the commit that says "add test p element to index page" +Go to the commit that says "add test p element to index page" and try answering the following questions: -#### Questions - -- How many files were changed in this commit? -- Who created the change? -- What time did the change take place? +1. How many files were changed in this commit? +2. Who created the change? +3. What time did the change take place? {{}} -{{}} - -### Explore ๐Ÿ” +{{}} Go to the following link: https://github.com/CodeYourFuture/education-blog/commits/main and locate commit that says "remove \ and # from start of paragraph" -#### Questions - -- How many files were changed in this commit? -- What change was made in this commit? +1. How many files were changed in this commit? +2. What change was made in this commit? {{}} diff --git a/common-content/en/module/induction/version-control/index.md b/common-content/en/module/induction/version-control/index.md index 13f37b8c4..13f922482 100644 --- a/common-content/en/module/induction/version-control/index.md +++ b/common-content/en/module/induction/version-control/index.md @@ -15,17 +15,11 @@ time="10" To improve their way of working, Ahmed and Naima realise they need the following: -> - a way to both know what the most recent version is -> - a way to know what the old versions were, and in what order (i.e. how they got to the current version, and what content they may have deleted that they may want to get back) +- A way to both know what the most recent version is +- A way to know what the old versions were, and in what order (i.e. how they got to the current version, and what content they may have deleted that they may want to get back) To manage the different versions of the blog project, they decide to use **Git**. -{{}} - -Git is **version control software** that allows developers to create and manage different versions of a project. - -{{}} - In Git, we create different versions of a project over time by creating **commits**. A **commit** is a snapshot of our project at a particular point in time. You can also think of a **commit** as a particular version of a project. diff --git a/common-content/en/module/induction/viewing-files/index.md b/common-content/en/module/induction/viewing-files/index.md index a7a8dc388..aa1a43b00 100644 --- a/common-content/en/module/induction/viewing-files/index.md +++ b/common-content/en/module/induction/viewing-files/index.md @@ -1,7 +1,7 @@ +++ title = 'Viewing files from a git clone' time ="20" -objectives=["Open a cloned repository in your IDE","Explore the repository in your IDE","Open the Integrated Terminal in VSCode"] +objectives=["Open a cloned repository in VSCode","Explore the repository in VSCode","Open the Integrated Terminal in VSCode"] [build] render = 'never' list = 'local' @@ -9,23 +9,16 @@ objectives=["Open a cloned repository in your IDE","Explore the repository in yo +++ -Once you've got a local copy of a codebase on your local machine you can start to view the files and folders in that codebase. You can use a code editor like VSCode. +Once you've got a local copy of a codebase on your local machine you can start to view the files and folders in that codebase using VSCode. -VSCode is an application that enables developers to view and edit files on their local machine. - -{{}} - -### Explore VSCode +{{}} 1. Figure out how to open the cloned repository on your local machine in VSCode. 2. Explore the repository in VSCode and use the code editor to look at the various files and folders. -3. Try opening the Integrated Terminal in your VSCode window +3. Use the Source Control tab to view the commit history and explore file changes. -๐Ÿค” If you get stuck on any of these exercises, it's a good idea to search online. For example, you could Google "opening terminal in vscode" +If you get stuck on any of these exercises, it's a good idea to search online. For example, you could Google "viewing commit in vscode" {{}} - -> [!NOTE] -> If you're working on a library computer, use dot dev to open the repo in your browser, and navigate the files and folder there. You cannot open a terminal in the library, so come to class to try this part out. diff --git a/common-content/en/module/induction/working-locally/index.md b/common-content/en/module/induction/working-locally/index.md index 55e7151a5..30db37b91 100644 --- a/common-content/en/module/induction/working-locally/index.md +++ b/common-content/en/module/induction/working-locally/index.md @@ -12,27 +12,30 @@ time ="20" +++ -GitHub is an really useful tool for aiding collaboration, but when it comes to writing and updating the code for a project, we tend to want the flexibility that comes with working on our {{}}A **machine** in this context is any computer, and your **local machine** is the computer (laptop or desktop) on which you do your work.{{}}. So we need to address the following question: +Before we can work on it we need to get a **local copy** of the education blog repo. A repository on GitHub is said to be **remote** and a repository on our own computer is said to be **local**. + +We call a local copy of a GitHub repository a **clone**. The process of copying a remote repository on to a local machine is called **cloning**. + +GitHub is an really useful tool for aiding collaboration, but when it comes to writing and updating the code for a project we tend to want the flexibility that comes with working on our computer. So we need to address the following question: > How can we get a copy of an existing GitHub repository on our local machine? -In other words, we need to get a {{}}A repository on GitHub is said to be **remote**. A repository on our own computer is said to be **local**.{{}} of the repository which is on GitHub. +In other words, we need to get a **local copy** of the repository which is on GitHub. -We call a local copy of a GitHub repository a **clone**. The process of copying a remote repository on to a local machine is called **cloning**. Watch the video below to see instructions on one of the ways you can clone a repo: using the Visual Studio Code interface. +Watch the video below to see instructions on one of the ways you can clone a repo: using the Visual Studio Code interface. {{}}https://www.youtube.com/watch?v=ILJ4dfOL7zs{{}} -{{}} - -##### ๐Ÿ‘ Clone a Repo +{{}} Follow the steps in the above video to make a local copy of the education blog repo that you forked in the previous step. -##### Reminders: +#### Reminders: +- The "Clone Repository" button won't be visible if you are already working in another repository. If you are already working in a repo you can close it by selecting `File --> Close Folder` - Use the URL for **your fork** of the `education-blog` repo when you are cloning, not the URL for the original CYF repo - When selecting the location to clone your files, choose the `CYF` folder you created in an earlier task -- If you are working on a library computer, you won't be able to clone the repo so come to class to try cloning out. In the meantime, you can explore the files using dot dev in the same way as you would in Visual Studio Code + {{}} @@ -61,4 +64,4 @@ flowchart TD linkStyle 0,1 stroke:#0d6efd,stroke-width:2px ``` -Sketch this diagram in your notebook. When you inevitably get mixed up or lost about where your changes are, you can refer back to this diagram to help you understand what's happening. +Sketch this diagram in your notebook. If you get confused about where your changes are you can refer back to this diagram to help you understand what's happening. \ No newline at end of file diff --git a/common-content/en/module/induction/wrapping-up/index.md b/common-content/en/module/induction/wrapping-up/index.md deleted file mode 100644 index 5f8a36ae6..000000000 --- a/common-content/en/module/induction/wrapping-up/index.md +++ /dev/null @@ -1,33 +0,0 @@ -+++ -title = 'Wrapping up Git' - -time ="20" -hide_from_overview = true -[objectives] - 1='Commit changes to a local git branch' -[build] - render = 'never' - list = 'local' - publishResources = false - -+++ - -{{}} - -๐Ÿ“‹ Double check the learning objectives from this sprint. Make a note of those objectives that you're still struggling with. - -Now you'll need to **create a commit**. - -You can use the "How to commit changes and push them in Visual Studio Code" video to figure out how to create a commit. - -We'll cover this topic often in workshops. Come to a CYF centre to work on this with a mentor. - -1. Try opening your clone of education-blog in VSCode -1. Make sure you're on the `main` branch -1. Make a **new** branch for your changes -1. Try fixing a typo in the `README.md` file -1. Try using the video to create a commit of your work. - -{{}} - -{{}}https://www.youtube.com/watch?v=B8RSMBSzFuA{{}} diff --git a/common-content/en/module/js1/check-unix-os/index.md b/common-content/en/module/js1/check-unix-os/index.md index b4fba7fe8..d5567778a 100644 --- a/common-content/en/module/js1/check-unix-os/index.md +++ b/common-content/en/module/js1/check-unix-os/index.md @@ -14,21 +14,18 @@ time = 15 If you get stuck on any of the below or above instructions, please post in your class channel on Slack. -You probably already have this if you have done previous modules. - -{{}} -Code Your Future does not support Windows. +{{}} We have found that we don't reliably have volunteers at class who can debug Windows problems, and they frequently come up, stopping trainees from making progress. We do not support Windows so as to not waste lots of trainee and volunteer time. We have made this decision even though Windows is a popular operating system and has features like WSL which help to get experience with Unix. {{}} -If you have a Mac or Linux machine already, you already have a UNIX based operating system. All CYF-supplied laptops run Mac OS or Linux. If you have your own machine and it runs Windows, you should already have set up a Linux partition. +If you have a Mac or Linux machine already, you already have a UNIX based operating system. All CYF-supplied laptops run Mac OS or Linux. If you have your own machine and it runs Windows you will need to set up a Linux partition. -If you have still not done this, you must do it now. We cannot support learners using Windows. It takes too much time from everybody else. If you need help doing this, post in Slack, or bring your laptop to a CYF co-working space to get support. It's normal to need help with this process. +If you have still not done this you must do it now. If you need help doing this, post in Slack, or bring your laptop to a CYF co-working space to get support. It's normal to need help with this process. The Ubuntu website has [instructions which you can follow](https://help.ubuntu.com/community/WindowsDualBoot) to dual-boot your system. > [!TIP] > @@ -36,4 +33,3 @@ If you have still not done this, you must do it now. We cannot support learners -[Dual Boot on Windows](https://help.ubuntu.com/community/WindowsDualBoot) diff --git a/common-content/en/module/js1/comparison/index.md b/common-content/en/module/js1/comparison/index.md index 3a1e1cce7..2deb8d8e4 100644 --- a/common-content/en/module/js1/comparison/index.md +++ b/common-content/en/module/js1/comparison/index.md @@ -3,9 +3,9 @@ title = 'Comparing current and target output' time = 40 [objectives] - 1='Evaluate an expression that uses a comparison operator' - 2='Explain when to use the === operator in a program' - 3='List the values of the boolean type' + 1='List the values of the boolean type' + 2='Evaluate an expression that uses a comparison operator' + 3='Explain the difference between strict and loose equality' [build] render = 'never' list = 'local' @@ -13,133 +13,85 @@ time = 40 +++ -{{}} -===[[Define current and target]]=== -Let's start with a function declaration of `formatAs12HourClock`: +### Comparing values -```js -function formatAs12HourClock() {} -``` - -Whenever we call `formatAs12HourClock` we expect it to return a particular value, which we call the ๐ŸŽฏ **target output**. For example, we expect `formatAs12HourClock("08:00")` to return `"08:00 am"`. `"08:00 am"` is the ๐ŸŽฏ **target output**. - -However, the **current output** is what the function _actually_ returns right now. - -๐Ÿ‘‰๐Ÿผ [Work through the exercises](#current-1) -===[[Exercise 1]]=== - -Let's start with `formatAs12HourClock` defined like this: - -```js -function formatAs12HourClock() {} -``` +We have learned how to store values in a program and how to access them again when we need them. At some point we will need to **compare** two values. Often our program will need to change its behaviour depending on that comparison. -Suppose we now call the function like this: +For example, think about what happens when you switch on your laptop. Before you do anything else you are asked to enter a password. Whatever you type is compared against a value stored on the computer and if the two match you can carry on using your computer. If they are different you won't be able to access files or use any programs. -```js -formatAs12HourClock("05:30"); -``` +We use comparison operators to compare two expressions. We use the equality operator `==` to check if two values are the same. -{{}} +### Boolean values -๐Ÿ‘‰๐Ÿผ [Keep going](#current-2) -===[[Exercise 2]]=== +Some values are best represented as strings: any piece of text, a name, address, etc will most likely be stored using the string data type. The number data type can store numbers we use in calculations. -Let's continue with `formatAs12HourClock` defined like this: +If we're comparing two things, there are only two different states: **true** or **false**. This leads us to the **boolean** datatype, which only has true or false values. Whenever we compare two values with a comparison operator, we end up with a boolean value: `true` or `false`. It's one or the other. It's boolean. ```js -function formatAs12HourClock() {} -``` +// using the strict equality comparison expression -Suppose we call the function like this: +console.log(42 == 10 + 32); +// logs true -```js -formatAs12HourClock("20:10"); +console.log(10 * 5 == 60); +// logs false ``` -{{% multiple-choice question="When calling formatAs12HourClock('05:30'), what is the current output?" answers="undefined | '05:30 am' | null | An error is thrown" feedback="Correct! Since the function is empty and has no return statement, it returns undefined by default. | Not quite - remember that the function is currently empty with no implementation. | No - an empty function returns undefined, not null. | No - an empty function executes successfully but returns undefined." correct="0" %}} +{{}} -{{}} - -## ๐Ÿงฉ Comparing values - -We have learned how to log values to the console. We can also **compare** two values. We check that a function produces some target output with a comparison. - -We compare the current output of `formatAs12HourClock("08:00")` with the target output of `"08:00 am"` and ask: **are these two values the same?** We use a comparison operator to compare two expressions and check if they evaluate to the same value. We use the strict equality operator `===` to check if two values are the same. - -### Left equals Right +Create a new file to work in and use `console.log` to print the values of these expressions. Try to predict the result before you run the code! ```js -formatAs12HourClock("08:00") === "8:00 am"; -``` +// 1 +"hello" == "hello" -`===` checks if the values on the left and right of the operator are the same. We can think of `formatAs12HourClock("08:00") === "8:00 am"` as the question: "Is the return value of `formatAs12HourClock("08:00")` equal to `"8:00 am"` ?" This leads to the question: +// 2 +"CYF" == "cyf" -> What will the expression `formatAs12HourClock("08:00") === "8:00 am"` evaluate to? +// 3 +const homeTown = "Newcastle" +homeTown == "Liverpool" -## โœ… โŒ Boolean values - -{{}} -===[[Define Boolean]]=== +// 4 +42 == "42" +``` +{{}} -### Does 1 equal 0? Yes or No? True or False? +### Strict Equality -Some values are best represented as strings: any piece of text, a name, address, etc will most likely be stored using the string data type. The number data type can store numbers we use in calculations. +Did anything surprise you about the outputs in that exercise? Number four probably looked strange - the two values have different types, so how can they be equal? -If we're comparing two things, there are only two different states: **true** or **false**. This leads us to the **boolean** datatype, which only has true or false values. Whenever we compare two values with a comparison operator, we end up with a boolean value: `true` or `false`. It's one or the other. It's boolean. +We were using **loose equality** in these examples. Loose equality compares the _value_ of two terms but not their _type_. This might work in our code but it also makes our code vulnerable to bugs. -```js -// using the strict equality comparison expression +To avoid this we will use **strict equality** instead. This checks both value _and_ type and will only evaluate as `true` if both are the same. The strict equality operator is `===`. -console.log(42 === 10 + 32); -// logs true +{{}} -console.log(10 * 5 === 60); -// logs false -``` +Modify your code from the previous exercise to use the strict equality operator `===`. What do you see that is different in the outputs? -๐Ÿ‘‰๐Ÿพ [Now work through the exercises](#booleans-1) -===[[Exercise 1]]=== -Look at the code below and predict what each expression will evaluate to. Write your prediction down. Use the Node REPL to check your answers. Check out [some relevant documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality) if you've not seen a particular operator before. - -```js {linenos=table,linenostart=1} -true === false; -5 == 2 + 4; -4 * 5 == "20"; -3 * 2 === 6; -Math.min(3, 4, 5) === 4; -let mhairiName = "Mhairi"; -typeof mhairiName === "string"; -let mhairiAge = 28; -let isMhairiOldEnoughToDrive = true; -let kilometersMhairiDrivesToWork = 9.4; -``` +{{}} -๐Ÿ‘‰๐Ÿฟ [Keep Going](#booleans-2) -===[[Exercise 2]]=== -Look at the code below and predict what each expression will evaluate to. Write your prediction down. Use the Node REPL to check your answers. Check out [some relevant documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality) if you've not seen a particular operator before - -```js {linenos=table,linenostart=1} -"hello Mhairi" === `hello ${mhairiName}`; -"${mhairiName} is 28" === `Mhairi is ${mhairiAge}`; -isMhairiOldEnoughToDrive; -isMhairiOldEnoughToDrive === true; -mhairiAge >= 18; -29 <= mhairiAge; -Math.round(kilometersMhairiDrivesToWork) === 9; -``` +### Comparing Unequal Values -๐Ÿ‘‰๐Ÿฟ [Keep Going](#booleans-3) -===[[Exercise 3]]=== +Often the condition we want to check isn't about equality. It can be useful to know if a value is greater or less than another. There are four conditions we can check: -### Checking misconceptions ๐Ÿค” +- `value1` is **greater than** `value2`: `value1 > value2` +- `value1` is **greater than or equal to** `value2`: `value1 >= value2` +- `value1` is **less than** `value2`: `value1 < value2` +- `value1` is **less than or equal to** `value2`: `value1 <= value2` -Look at the code below and then predict what the expression will evaluate to. Be sure to explain your answer too. Use the Node Repl to check your answer. Does the REPL output make sense? +These expressions all evaluate to `true` or `false`, just like the equality operators. -Try using the Node Repl to check your answer. Does the REPL output make sense? +### Negation -```js {linenos=table,linenostart=1} -console.log(10 + 32) === 42; -``` +We can also explicitly check that two values are **not** equal to each other. This might sound strange but it is an important part of comparing values which we will use often throughout this course. The `not` operator is the symbol `!` and it replaces the first `=` symbol in an equality operator. For example: -{{}} +```js +// check if two strings are equal +"hello world" === "Hello World!" +// false + +// check if two strings are not equal +"hello world" !== "Hello World!" +// true +``` \ No newline at end of file diff --git a/common-content/en/module/js1/conditionality/index.md b/common-content/en/module/js1/conditionality/index.md index 5ebebcd2e..fd5ca5d7a 100644 --- a/common-content/en/module/js1/conditionality/index.md +++ b/common-content/en/module/js1/conditionality/index.md @@ -15,21 +15,19 @@ time = 30 +++ -> Recall: JavaScript programs are built up from sequences of **declarations** and **statements**. +In programming we can use an **`if` statement** to execute some code when a given condition is `true`. In JavaScript, we can write an `if` statement as follows: -In programming, we can use an **`if` statement** to execute some code when a given condition is `true`. In JavaScript, we can write an `if` statement as follows: - -```js {title="main.js"} +```js if (condition) { - // do some code in here + // code to execute if condition is true } ``` The `if` statement consists of: -1. `if` keyword: this is the start of the `if` statement -2. `condition`: condition is an expression that evaluates to true or false. The condition must be in a pair of parentheses: `()` -3. `{}`: a block statement: any code we want to execute if the condition is true goes inside the curly braces here +1. `if` keyword - this is the start of the `if` statement +2. `condition` - condition is an expression that evaluates to true or false. The condition must be in parentheses: `()` +3. `{}` - a code block: any code we want to execute if the condition is true goes inside these braces We can represent this with a diagram too: @@ -40,54 +38,96 @@ flowchart LR IB[Execute code in body] EXIT([End of if statement]) IC --> |true| IB - IC -.-> |false| EXIT IB --> EXIT + IC -.-> |false| EXIT ``` -{{}} -===[[Exercise 1]]=== +### Writing an `if` statement -### ๐Ÿ•น๏ธ Playing computer +We're going to write some code to implement our password checker example. We'll use `console.log` to print messages for the user which will change depending on the password they enter. Let's start by creating a file called `passwordChecker.js` to work in and initialising some variables. -```js -function checkDivisibility(a, b) { - if (a % b === 0) { - return `${a} is divisible by ${b}`; - } +```js {title="passwordChecker.js"} +const password = "secretword123"; +const userInput = "secretword123"; +``` - return `${a} is not divisible by ${b}`; +We'll assume for now that the user has entered the correct password and we're storing that value in `userInput`. The `password` variable contains the value that we want to compare it to. Let's add an `if` statement and compare the two variables as our `condition`. + +```js {title="passwordChecker.js"} +const password = "secretword123"; +const userInput = "secretword123"; + +if (userInput === password){ + // code will go here } +``` + +Remember to use strict equality! + +The next step is to define what should happen **if the condition is met**. A real password checker would start the process of loading a user's profile, but in our example we'll print a message confirming that the values match. + +```js {title="passwordChecker.js"} +const password = "secretword123"; +const userInput = "secretword123"; -console.log(checkDivisibility(10, 2)); -console.log(checkDivisibility(50, 3)); +if (userInput === password){ + console.log("Correct password entered"); +} ``` -Play computer with the example above, step through each line in the code and work out happens each time the function is called. +### What happens if the condition is `false`? -- What is the **return value** each time the function is called? -- What value is assigned to the **parameters** `a` and `b` each time the function is called? +Our code is great at letting the user know they entered the correct password, but they might make a mistake one time. Try changing the value of `userInput` and see what happens when it doesn't match `password`. -If you've not encountered any syntax before, remember to look it up in some documentation. +That wasn't very helpful, was it? We'll look at how we handle things going wrong in more detail in the next few sections but for know we know we _definitely_ don't want things to fail without telling us anything. We need to tell our program what to do if the values don't match. -===[[Exercise 2]]=== +To do this we will use the `else` keyword. When we add an `else` block to an `if` statement we're saying "if the condition is false do this instead". -### ๐ŸŽฎ Playing computer +```js {title="passwordChecker.js"} +const password = "secretword123"; +const userInput = "thisiswrong"; -```js -function getCountryCode(phoneNumber) { - if (phoneNumber.startsWith("+44")) { - return "UK"; - } +if (userInput === password){ + console.log("Correct password entered"); +} else { + console.log("Incorrect password!"); } +``` + +Try running your code again - you should now see "Incorrect password!" printed in the terminal. + +Try changing `userInput` again so it matches `password` and see what happens now. Note that you will never see both messages printed. If the condition is `true` then the block after it is executed and the program moves on. + +### More than two possibilities -getCountryCode("+447831620328"); -getCountryCode("+989871783972"); +We won't always be dealing with yes/no questions. Sometimes we need to consider additional options. Let's imagine we have a secret password administrators can use to access anyone's account. + +```js {title="passwordChecker.js"} +const password = "secretword123"; +const userInput = "thisiswrong"; +const adminPassword = "override"; + +if (userInput === password){ + console.log("Correct password entered"); +} else { + console.log("Incorrect password!"); +} ``` -Play computer with the example above, step through each line in the code and work out happens each time the function is called. +Our code doesn't specify what should happen if the user enters this admin password. We can change that by adding an `else if` block after the original condition but before the `else` block. This is structured the same way as the initial condition. -- What is the **return value** each time the function is called? -- What value is assigned to the `phoneNumber` parameter each time the function is called? -- Try describing the purpose of this function - what should it do? +```js {title="passwordChecker.js"} +const password = "secretword123"; +const userInput = "thisiswrong"; +const adminPassword = "override"; + +if (userInput === password){ + console.log("Correct password entered"); +} else if (userInput === adminPassword){ + console.log("Admin access granted"); +} else { + console.log("Incorrect password!"); +} +``` -{{}} +We will still only ever see one block being executed, but now our program can handle more than two possibilities. The order of these conditions matters. If `userInput === password` the first block will be executed and the program will move on; we will only check `userInput === adminPassword` if that initial condition is `false`, and we will only execute the code following `else` if _both_ conditions are `false`. \ No newline at end of file diff --git a/common-content/en/module/js1/data/index.md b/common-content/en/module/js1/data/index.md index af84f5f9f..3290735fd 100644 --- a/common-content/en/module/js1/data/index.md +++ b/common-content/en/module/js1/data/index.md @@ -11,19 +11,19 @@ time = 15 +++ -Weโ€™re going to focus on the JavaScript programming language. +We can do a lot more than just print text with the JavaScript programming language. First we need to understand some of the rules we need to follow. -A programming language organises data with rules so we understand what we can and cannot do with it. Languages split data up into different categories called {{}} -A **data type** is a grouping of data with some particular properties{{}}. In JavaScript, we have five data types. We will look first at numbers and strings. +A programming language organises data with rules so we understand what we can and cannot do with it. Languages split data up into different categories called **data types**. A data type is a grouping of data with some particular properties. We will look first at **numbers** and **strings**. -#### Number data type +### Number data type `10` is an example of the number data type. + `3.14` is also part of the number data type; both integers (whole numbers) and non-integers are types of number. `-15` is also part of the number data type. Positive and negative numbers, as well as `0`, are all types of number. -#### String data type +### String data type A string is a sequence of characters demarcated by quotes. @@ -31,7 +31,7 @@ A string is a sequence of characters demarcated by quotes. "Code Your Future"; ``` -### ๐Ÿงฎ Creating expressions +### Creating expressions Think of the numbers `10` and `32`. We could ask questions about these numbers, like: _What is the **sum** of 10 and 32?_ @@ -41,9 +41,9 @@ Another way to say this is _what do 10 and 32 add up to?_ In English we can say 10 + 32; ``` -In JavaScript, `+` is an {{}} An **operator** represents an operation, or act. {{}}. It's a symbol. In this example, `+` represents the operation โ€œmake the sum of the numbersโ€. It symbolises addition. +In JavaScript, `+` is an **operator**. An operator represents an operation, or act. It's a symbol. In this example `+` represents the operation โ€œcalculate the sum of the numbersโ€. It symbolises addition. -The combination of symbols `10 + 32` is an {{}}An **expression** is a value or any valid combination of values and symbols that results in a single value.{{}} We say that expressions **evaluate** to a single value. So we say that `10 + 32` **evaluates** to the value `42`. +The combination of symbols `10 + 32` is an **expression**. An expression is a value or any valid combination of values and symbols that results in a single value. We say that expressions **evaluate** to a single value. So we say that `10 + 32` **evaluates** to the value `42`. `10` is also an expression. It **evaluates** to the value `10`. diff --git a/common-content/en/module/js1/declaring-functions/index.md b/common-content/en/module/js1/declaring-functions/index.md index 7977cb806..175a2cf19 100644 --- a/common-content/en/module/js1/declaring-functions/index.md +++ b/common-content/en/module/js1/declaring-functions/index.md @@ -1,7 +1,7 @@ +++ title = 'Declaring functions' -time = 20 +time = 40 [objectives] 1='Label and describe the syntactic features of a function declaration' 2='Declare your own function using a function declaration' @@ -12,31 +12,105 @@ time = 20 +++ -{{}} -Functions are reusable blocks of code. -{{}} +We have our pseudocode from the previous section and it's time to write our first function. + +```js {title="passwordCheckerFunction.js"} +// Already have the password stored in a variable +// Receive the value which the user entered +// Compare the two values +// If they match print "Correct password entered" +// If they don't match print "Incorrect password, please try again" +``` -To create a function, we can use a function declaration. A function declaration looks like this: +It can be tempting to jump straight to the interesting bit, but just like any other set of instructions we need to start at the beginning. In this case we need to declare a variable to store our password. -```js {linenos=table,linenostart=1} -function convertToPercentage() {} +```js {title="passwordCheckerFunction.js"} +// Already have the password stored in a variable +const password = "secretword123"; + +// Receive the value which the user entered +// Compare the two values +// If they match print "Correct password entered" +// If they don't match print "Incorrect password, please try again" +``` + +To create our function we need to use a function declaration. In JavaScript we declare functions like this: + +```js +function checkPassword(input) {} ``` The `function` declaration consists of the following syntactic elements: -- `function` keyword, begins the function declaration -- `convertToPercentage` - names the function -- `()` - any input to the function will go between these round braces (our function above doesn't take any input (yet), but it still needs the `()`s) -- `{}` - the body of the function is written inside the curly braces (our function above doesn't do anything yet, but it still needs the `{}`s) +- `function` keyword - begins the function declaration +- `checkPassword` - the **name** of the function +- `()` - any input to the function will go between these parentheses. We still need them if a function has no input, we just leave them empty. We call these inputs **parameters**. +- `{}` - the **body** of the function is written inside the braces. The code we want to execute will be written here. + +{{}} +If you have worked with another programming language in the past you have probably worked with functions already, but defined them differently. Every language will have a different syntax for the definition but the purpose is the same. +{{}} -We can create a function declaration by wrapping up the `percentage` variable and the expression for the percentage inside the function. +We can add our function declaration to our code. -```js {linenos=table,linenostart=1 } -const decimalNumber = 0.5; +```js {title="passwordCheckerFunction.js"} +// Already have the password stored in a variable +const password = "secretword123"; -function convertToPercentage() { - const percentage = `${decimalNumber * 100}%`; +// Receive the value which the user entered +function checkPassword(userInput){ + // Compare the two values + // If they match print "Correct password entered" + // If they don't match print "Incorrect password, please try again" } ``` -At the moment `decimalNumber` is not wrapped up inside the body of the function. In the following sections, we will explore what happens when this is the case. +We changed a couple of things here: +- Instead of `input` we named our function's parameter `userInput`. Just like any other variable, we want to use meaningful names which tell us what the value represents. +- We wrapped the braces `{}` around the other steps in the pseudocode. These lines say what we want the function to do, so we place them inside it. +- We **indented** those lines inside the braces. Indentation gives us a visual indication of where a block starts and ends. + +Now it's time to fill in the detail of what our function will do! We have already seen how to do this using an `if` statement in the last sprint. + +{{}} +Add the code to complete the steps described by the pseudocode. Remember to line the comments up with the code! + +
+ Example solution: + + ```js {title="passwordCheckerFunction.js"} + // Already have the password stored in a variable + const password = "secretword123"; + + // Receive the value which the user entered + function checkPassword(userInput){ + // Compare the two values + if (userInput === password) { + // If they match print "Correct password entered" + console.log("Correct password entered"); + } else { + // If they don't match print "Incorrect password, please try again" + console.log("Incorrect password, please try again"); + } + } + ``` +
+{{
}} + +Now we have defined our function we can call it in exactly the same way as we called `Math.round()` before. Try it with different inputs to check that it works! + +```js {title="passwordCheckerFunction.js"} +checkPassword("secretword123"); +// "Correct password entered" + +checkPassword("WrongGuess99"); +// "Incorrect password, please try again" +``` + +{{}} +When we call a function we have a special name for the values we place in the parentheses: **arguments**. When we provide a value as an input we are **passing an argument** to the function. + +There is an important distinction between parameters and arguments: +- A function's **parameters** are the placeholder values used when we **define** the function +- A function's **arguments** are the actual values in the program when we **call** the function +{{}} diff --git a/common-content/en/module/js1/define-computer/index.md b/common-content/en/module/js1/define-computer/index.md index 8c9e7f370..6d6f70b44 100644 --- a/common-content/en/module/js1/define-computer/index.md +++ b/common-content/en/module/js1/define-computer/index.md @@ -13,4 +13,5 @@ time = 5 Modern computers are **complicated**: it would be too difficult and time-consuming to list all the components that make up a modern computer. So to build our mental model, we will use this simple definition of a computer: +>[!Definition] > A **computer** is a device used to store and perform operations on data. diff --git a/common-content/en/module/js1/errors/index.md b/common-content/en/module/js1/errors/index.md index ebc772cda..b245e66ef 100644 --- a/common-content/en/module/js1/errors/index.md +++ b/common-content/en/module/js1/errors/index.md @@ -12,9 +12,7 @@ time = 20 +++ -> ๐Ÿ—ฃ๏ธ Recall: A programming language is a set of rules for writing computer instructions. - -So we need to understand what happens when we **_break_** those rules. +Recall that a programming language is a set of rules for writing computer instructions. What would happen if we **_break_** those rules? Let's take an example: @@ -28,21 +26,21 @@ On line 1, we have a variable declaration, but the string has a missing `"` We'r When we execute the code above, we get this: -```node +```console const firstName = "Francesco; ^^^^^^^^^^^ Uncaught SyntaxError: Invalid or unexpected token ``` -We get a **SyntaxError** message. This error message is telling us that we've broken the rules of the language. +We get a **SyntaxError** message. This error message is telling us that we've broken one of the rules of the language. In this case the interpreter didn't expect to see the semicolon - it needs us to add the missing `"` before the expression makes sense. -{{}} +{{}} -Each block of code in this activity is broken. Before you run each block of code: +Each block of code in this activity is broken. Create a new file to test these expressions in, but before you run each block of code: 1. Predict the error. -1. Explain why the error happened. +2. Explain why the error happened. ```js const volunteer = "Shadi"; @@ -59,47 +57,3 @@ console.log(Math.round(10.3); ``` {{}} - -### Saving return values - -We can store the return value of a function in a variable. Function calls are also expressions. This means their value can also be stored in variables, just like with operations on numbers or strings. - -Suppose we have a file `arithmetic.js` containing this code: - -```js title="arithmetic.js" -const result = Math.round(10.3); -``` - -When this program is executed, it creates a variable called `result` and assigns to it **the return value of the function**, in this case the rounded number. - -So `result` will have a value of `10`. - -### ๐Ÿ”ญ Logging and returning - -Most functions return values we can use in our program. - -`Math.round` takes a single input, does a calculation and then returns a value that we can use when our program is running. - -Some functions don't produce useful return values in our running program; but they can still cause **effects**. - -{{}} - -```js -const result = console.log("hello world"); -``` - -1. Predict what `result` will _evaluate to_ when the code above runs. -1. Execute this line in the Node REPL. -1. Evaluate the value of the `result` variable to observe what happens. - -{{}} - -When this program runs, the variable `result` will evaluate to `undefined`. `undefined` is a data type in JavaScript which usually means no value has been assigned. Unlike the `number` data type, which contains many possible values (`1`, `2`, `10.3`, etc), the `undefined` data type has exactly one value, `undefined`. - -This can feel confusing as `console.log` _is_ a function with a set of instructions. `console.log` _does_ have an effect: it logs values to the console. However, `console.log` doesn't produce an output that we can use _inside_ the rest of our running program. - -{{}} - -Key fact: `console.log` is used to print values to the terminal. It doesnโ€™t produce an output in the running program. - -{{}} diff --git a/common-content/en/module/js1/fixing-the-error/index.md b/common-content/en/module/js1/fixing-the-error/index.md new file mode 100644 index 000000000..179ad126a --- /dev/null +++ b/common-content/en/module/js1/fixing-the-error/index.md @@ -0,0 +1,45 @@ ++++ +title = 'Fixing the error' + +time = 30 +[objectives] +1='Fix the error flagged by the interpreter' +[build] + render = 'never' + list = 'local' + publishResources = false + ++++ + +We saw this error: + +``` +TypeError: Assignment to constant variable. +``` + +Now that we understand it, let's fix it. + +If a variable has been declared to be a constant we are not allowed to reassign it, but that's what we're attempting to do on line 11: + +```js {title="passwordChecker.js" linenos=table,hl_lines=["11"],linenostart=1} +const password = "secretword123"; +const userInput = "thisiswrong"; +const adminPassword = "override"; +const response = ""; + +if (userInput === password){ + response = "Correct password entered"; +} else if (userInput === adminPassword){ + response = "Admin access granted"; +} else { + response = "Incorrect password!"; +} + +console.log(response); +``` + +{{}} +Using what you have learned about variables already in this sprint, try to fix the error. + +If you see a different error message you can apply the same techniques we used in the last section to understand it. +{{}} \ No newline at end of file diff --git a/common-content/en/module/js1/functions/index.md b/common-content/en/module/js1/functions/index.md index 596c77795..19ce42255 100644 --- a/common-content/en/module/js1/functions/index.md +++ b/common-content/en/module/js1/functions/index.md @@ -3,9 +3,8 @@ title = 'Functions' time = 20 [objectives] - 1='Explain what a function is in programming' - 2='Call a built-in function with an input in the REPL' - 3='Evaluate a call expression to the value it returns' + 1='Explain the purpose of a function in programming' + 2='Evaluate a function expression' [build] render = 'never' list = 'local' @@ -13,48 +12,51 @@ time = 20 +++ -Consider the number `10.3`. +When we are writing programs we often find ourselves needing to do the same thing over and over again. Think back to our password checker from the previous sprint: there are lots of places where you need to enter a password! -> ๐Ÿค” "What is the nearest whole number to `10.3`?" +We could re-write the code to check a password every time we needed to use it but that wouldn't be very efficient. It would take a long time to write and there's a chance we could make a mistake and introduce a bug. It would be much easier if we could write the code once and reuse it anywhere it was needed. -The process of finding the nearest whole number to a decimal number is called **rounding**. So we could rephrase our question as: +This applies to any repeated process. Let's look at how we can round a decimal to the nearest whole number. -> ๐Ÿค” "What does the number `10.3` **round** to?โ€ +### Reusing instructions -## โ™ป๏ธ Reusing instructions - -We can add or multiply numbers with operators, like `10 + 32` or `36 * 45`. But there is no operator for rounding the number `10.3` in JavaScript. And we will want to round numbers **again and again**. We should use a {{}}A **function** is a reusable set of instructions.{{}}. +There is no operator for rounding a number in JavaScript, but we will want to round numbers **again and again**. We can use a **function** to do this. A function is a reusable set of instructions. We don't need to declare this function ourselves. JavaScript comes with many **built-in** functions, ready for us to use, and rounding is so common that there is already one for it: `Math.round`. Functions usually take **inputs** and then **apply their set of instructions to the inputs** to produce an **output**. `Math.round` takes a number as an input and produces the nearest whole number as its output. Because the number is an input, and not fixed inside the instructions, `Math.round` can round _any_ number we give it, not just `10.3`. -{{}} -===[[Try it yourself]]=== +{{}} +Create a new file to work in and add the following line: -1. Write `Math.round` in the Node REPL -1. Hit enter to evaluate our expression +```js +console.log(Math.round); +``` -The REPL output `[Function: round]` is telling us `Math.round` is a function. +Take a look at the output in the console: -===[[Watch and follow along]]=== -![rounding](round.gif "[Function: round] indicates that Math.round is a function") +```console +[Function: round] +``` + +This is telling us that `Math.round` is a function. + +{{}} -{{}} -## ๐Ÿ“ฒ Calling a function +### Calling a function -For our function to work, we need Node to read the instructions and {{}}Execution means the computer reads and follows instructions.{{}} them. Write the following in the REPL: +For our function to work, we need Node to read the instructions and **execute** them. Execution simply means the computer will run the code with the instructions in it. Update your code to add some extra information. ```js -Math.round(10.3); +console.log(Math.round(10.3)); ``` -Notice the `(` and `)` brackets after the name of the function and a number inside the brackets. These brackets mean we are calling the function. The number inside the brackets is the **input** we're passing to the function. +Notice the `(` and `)` brackets after the name of the function and a number inside the brackets. These brackets mean we are **calling** the function. The number inside the brackets is the **input** we're passing to the function. -{{}} +{{}} -**Calling a function** means telling the computer to read the function's instructions and carry out its instructions. When calling a function we can also pass inputs to the function. +**Calling a function** means telling the computer to read the function's instructions and carry them out. When calling a function we can also pass inputs to the function. {{}} @@ -66,16 +68,26 @@ If we type `Math.round(10.3)` then we get the result `10`. So we say that `Math. A **call expression** is an **expression** which **evaluates** to the value returned by the function when it is called. So the expression `Math.round(10.3)` evaluates to the value `10`. -If we assign that expression to a variable, or use it in a string, we'll get the value `10`. So we can write: +If we assign that expression to a variable, or use it in a string, we'll get the value `10`. We can use this value just like any other that we store in a variable. -```js -const roundedValue = Math.round(10.3); -``` +{{}} +1. Update your code from earlier to store the result of calling `Math.round(10.3)` in a variable and print the variable using `console.log` +2. Create a second variable to store the result of `Math.round(4.2)` and print the sum of the two values. -or we can write: +
+ Example solution: -```js -const roundedValueInAString = `10.3 rounds to ${Math.round(10.3)}`; -``` + ```js {{title="Part 1"}} + roundedNumber = Math.round(10.3); -Both of these instructions **evaluate** the call expression `Math.round(10.3)` to the returned value `10` as soon as the call expression appears. The variable `roundedValue` will have a numeric value `10` (just like if we'd written `const roundedValue = 10;`), and the variable `roundedValueInAString` will have a string value `"10.3 rounds to 10"`. + console.log(roundedNumber); + ``` + + ```js {{title="Part 2"}} + firstRoundedNumber = Math.round(10.3); + secondRoundedNumber = Math.round(4.2); + + console.log(firstRoundedNumber + secondRoundedNumber); + ``` +
+{{
}} diff --git a/common-content/en/module/js1/functions/round.gif b/common-content/en/module/js1/functions/round.gif deleted file mode 100644 index 496f4c714..000000000 Binary files a/common-content/en/module/js1/functions/round.gif and /dev/null differ diff --git a/common-content/en/module/js1/install-node/index.md b/common-content/en/module/js1/install-node/index.md index b69ec9ef8..c138257c4 100644 --- a/common-content/en/module/js1/install-node/index.md +++ b/common-content/en/module/js1/install-node/index.md @@ -18,29 +18,29 @@ Check if you already have NodeJS installed by running `node -v` in a terminal. T {{
}} -## ๐Ÿง On Ubuntu +### ๐Ÿง On Ubuntu 1. Install nvm by running the following commands in your terminal: -```terminal +```bash curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash ``` 2. After the installation is complete, you'll need to source the nvm script by running: -```terminal +```bash source ~/.bashrc ``` 3. Install the latest LTS version of Node.js by running: -```terminal +```bash nvm install --lts ``` 4. Check that you have successfully installed Node.js by running: -```terminal +```bash node -v ``` @@ -48,17 +48,17 @@ You should see a version number like `v22.11.0`. 5. Check that you have successfully installed npm by running: -```terminal +```bash npm -v ``` You should see a version number like `10.9.0`. -## ๏ฃฟ On Mac +### ๏ฃฟ On Mac 1. Install the the Xcode Command Line Developer Tools by running the following command in your terminal: -```terminal +```bash xcode-select --install ``` @@ -66,31 +66,31 @@ These may already be installed, in which case you will see "xcode-select: note: 2. Create a (Non-Login Interactive) Shell Configuration File: -```terminal +```bash touch ~/.zshrc ``` 3. Install nvm: -```terminal +```bash curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash ``` 4. After the installation is complete, you'll need to source the nvm script by running: -```terminal +```bash source ~/.zshrc ``` 5. Install the latest LTS version of Node.js by running: -```terminal +```bash nvm install --lts ``` 6. Check that you have successfully installed Node.js by running: -```terminal +```bash node -v ``` @@ -98,7 +98,7 @@ You should see a version number like `v22.11.0`. 7. Check that you have successfully installed npm by running: -```terminal +```bash npm -v ``` diff --git a/common-content/en/module/js1/interpreting-errors/index.md b/common-content/en/module/js1/interpreting-errors/index.md index 8b64bbf6e..c09041b76 100644 --- a/common-content/en/module/js1/interpreting-errors/index.md +++ b/common-content/en/module/js1/interpreting-errors/index.md @@ -12,33 +12,58 @@ time = 20 +++ -## An error is thrown +### An error is thrown -When we run the file with Node, we get an error in the console: +Let's revisit our password checker, but this time we'll create a variable to hold our response and print it at the end: + +```js {title="passwordChecker.js" linenos=table,hl_lines=["1"],linenostart=1} +const password = "secretword123"; +const userInput = "thisiswrong"; +const adminPassword = "override"; +const response = ""; + +if (userInput === password){ + response = "Correct password entered"; +} else if (userInput === adminPassword){ + response = "Admin access granted"; +} else { + response = "Incorrect password!"; +} + +console.log(response); +``` + +When we run the file with Node we get an error in the console: ```console -% node clock-example.js -/Users/dwh/CYF/clock-example.js:12 -const currentOutput = formatAs12HourClock("23:00"); - ^ - -SyntaxError: Identifier 'currentOutput' has already been declared - at wrapSafe (node:internal/modules/cjs/loader:1383:18) - at Module._compile (node:internal/modules/cjs/loader:1412:20) - at Module._extensions..js (node:internal/modules/cjs/loader:1551:10) - at Module.load (node:internal/modules/cjs/loader:1282:32) - at Module._load (node:internal/modules/cjs/loader:1098:12) - at TracingChannel.traceSync (node:diagnostics_channel:315:14) - at wrapModuleLoad (node:internal/modules/cjs/loader:215:24) - at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:158:5) - at node:internal/main/run_main_module:30:49 - -Node.js v22.4.1 +% node passwordChecker.js + +/Users/yourname/cyf/passwordChecker.js:11 + response = "Incorrect password!"; + ^ + +TypeError: Assignment to constant variable. + at Object. (/Users/colinfarquhar/clients/cyf/content_testing/passwordChecker.js:11:12) + at Module._compile (node:internal/modules/cjs/loader:1829:14) + at Module._extensions..js (node:internal/modules/cjs/loader:1969:10) + at Module.load (node:internal/modules/cjs/loader:1552:32) + at Module._load (node:internal/modules/cjs/loader:1354:12) + at wrapModuleLoad (node:internal/modules/cjs/loader:255:19) + at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5) + at node:internal/main/run_main_module:33:47 + +Node.js v25.9.0 ``` -When an error is thrown, the program stops and an error report is sent to the user. +{{}} +When this happens we say the program has **thrown** an error. +{{}} + +When an error is thrown the program stops. For errors like this one where there is a fundamental problem in the structure of the code this is unavoidable, but in some situations we can let the user know something went wrong without crashing the program. This is called **catching** an error and we will learn more in a later module. + +When an error like this is thrown an error report is sent to the user. It will act like a map for us and lead us to where the error happened. -As programmers, we will see a lot of errors. It's useful for us to be able to read them. +As programmers we will see a lot of errors. It's useful for us to be able to read them. ### Interpreting the output @@ -46,52 +71,46 @@ Each line of output here tells us something useful. The first line is: -``` -/Users/dwh/CYF/clock-example.js:12 +```console +/Users/yourname/cyf/passwordChecker.js:11 ``` -Your output was probably different. But it will have the same parts. Some text, then a colon (`:`), then a number. +Your output was probably different. But it will have the same parts: some text, then a colon (`:`), then a number. -{{}} +{{}} 1. Work out what the parts of this line mean. -2. Why are they different on my computer than yours? +2. Why are they different in this example than on your computer? 3. How can we use both pieces of information? {{}} -Often, looking at one line of a file is enough to understand what's wrong. So the message also shows us a copy of the line that caused the problem: +Often, looking at one line of a file is enough to understand what's wrong. The error message gives us the file name (`passwordChecker.js`) and the line number (11) so we can identify exactly where the problem is. It also shows us a copy of the line that caused the problem: -``` -const currentOutput = formatAs12HourClock("23:00"); +```console +response = "Incorrect password!"; ``` Then the output tells us the error message: -``` -SyntaxError: Identifier 'currentOutput' has already been declared +```console +TypeError: Assignment to constant variable. ``` We may not know what this means yet, but it's something we can learn about. -{{}} -Write down three ways you could find out what this means. -{{}} - Each line starting with "at" is showing us a "Stack trace". We'll skip over this for now. In the future we'll see how it can be useful to us. Finally, we have this line: -``` -Node.js v22.4.1 +```console +Node.js v25.9.0 ``` -{{}} +{{}} What does this line mean? Why might it be useful to know this information? -Add your answer to your spaced repetition calendar. Your understanding of this will grow over time. Answer the question again in the future, and compare it to your previous answer. - {{}} diff --git a/common-content/en/module/js1/interpreting-this-error/index.md b/common-content/en/module/js1/interpreting-this-error/index.md index ec2cb68dc..9439c50ad 100644 --- a/common-content/en/module/js1/interpreting-this-error/index.md +++ b/common-content/en/module/js1/interpreting-this-error/index.md @@ -17,42 +17,22 @@ time = 20 We saw this error - let's try to understand it: ``` -SyntaxError: Identifier 'currentOutput' has already been declared +TypeError: Assignment to constant variable. ``` ### Knowing what we changed It can be useful to remember when our code last worked, and what we changed since then. -{{}} +{{}} Source control can help here. If you commit your code every time you make something work, you can use git to easily see what changed since your last commit. {{}} -When we just had the first 10 lines of code here, everything worked. When we added the rest, we got this error: - -```js {linenos=table,linenostart=1,hl_lines=["12-17"]} -function formatAs12HourClock(time) { - return `${time} am`; -} - -const currentOutput = formatAs12HourClock("08:00"); -const targetOutput = "08:00 am"; -console.assert( - currentOutput === targetOutput, - `current output: ${currentOutput}, target output: ${targetOutput}` -); - -const currentOutput = formatAs12HourClock("23:00"); -const targetOutput = "11:00 pm"; -console.assert( - currentOutput === targetOutput, - `current output: ${currentOutput}, target output: ${targetOutput}` -); -``` +Everything worked until we made the refactor in the last section. The error appeared when we made the changes. The problem is that we made changes in a few places. -{{}} +{{}} Run your code very often. @@ -65,7 +45,7 @@ If we changed one thing since our code last worked, we know what change is the p The error message tries to tell us useful information: ``` -SyntaxError: Identifier 'currentOutput' has already been declared +TypeError: Assignment to constant variable. ``` When we get an error, we should make sure we understand all of the words in the error message. If we don't, we should look them up or ask someone. @@ -86,14 +66,18 @@ Make sure you _understand_ each word. Make sure you could explain the word to so Expand for example definitions - only expand this after you have written yours down. Compare your answers with these. -- **SyntaxError** - If we Google "JavaScript SyntaxError", [MDN tells us](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError) this is "an error when trying to interpret syntactically invalid code". So - we wrote some code which isn't allowed. -- **Identifier** - If we Google "JavaScript Identifier", [MDN tells us](https://developer.mozilla.org/en-US/docs/Glossary/Identifier): this is "a sequence of characters in the code that identifies a variable, function, or property". On line 12, the identifier is the variable name: `currentOutput`. -- **currentOutput** - This is the variable name we used in our code. This is the **identifier** that the error is about. -- **has**, **already**, and **been** are all standard English words with no special meaning. -- **declared** - We learnt about this already in this course - a **declaration** is where we make a new name (e.g. a new variable) in JavaScript. +- **TypeError** - If we Google "JavaScript SyntaxError", [MDN tells us](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError) this is "an error when an operation could not be performed". It goes on to say they can be thrown when "attempting to modify a value that cannot be changed". We may be trying to modify something when we aren't allowed to do so. +- **Assignment** - If we Google "JavaScript Identifier", the first hit from [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment) talks about "assigning a value to a variable or property". That's exactly what we're trying to do on line 11. +- **to** is a standard English word with no special meaning. +- **constant** - If we Google "JavaScript constant", [MDN tells us](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) that "the value of a constant can't be changed through reassignment using the assignment operator". It also references the `const` keyword which we use earlier in the program. +- **variable** - We learnt about this already in this course - a **variable** is used to store a piece of data in a program. Reading that back, we can rephrase this error message: -We wrote some code which isn't allowed. We tried to declare a new variable named `currentOutput`. But we had already declared something named `currentOutput`. +We tried to modify something which we weren't allowed to modify. We tried to assign a new value to the `response` variable on line 11, but because it was declared using the `const` keyword its value can't be changed. + +{{}} +In every example here we have included "JavaScript" in our Google search. We need to be specific, other languages may not describe errors in the same way. +{{}} diff --git a/common-content/en/module/js1/logging/index.md b/common-content/en/module/js1/logging/index.md index bc092314b..20f123b8e 100644 --- a/common-content/en/module/js1/logging/index.md +++ b/common-content/en/module/js1/logging/index.md @@ -11,6 +11,9 @@ time = 10 +++ +>[!caution] +> Should combine this with scripts section + ### Printing to the terminal To look at values when our program runs, we can use a function called `console.log`. diff --git a/common-content/en/module/js1/parameters/index.md b/common-content/en/module/js1/parameters/index.md index 85a3188ff..7e8607663 100644 --- a/common-content/en/module/js1/parameters/index.md +++ b/common-content/en/module/js1/parameters/index.md @@ -1,13 +1,10 @@ +++ title = 'Parameterising a function' -time = 40 +time = 30 [objectives] - 1='Define a parameter' - 2='Identify the value assigned to a parameter when a function is invoked' - 3='Differentiate between parameters and arguments' - 4='Invoke a given function with an appropriate argument to produce some target output' - 5='Reuse code to perform the same calculation with different inputs' + 1='Identify the value assigned to a parameter when a function is invoked' + 2='Explain how the output of a function will change with the ordering of its parameters' [build] render = 'never' @@ -16,68 +13,111 @@ time = 40 +++ -At the moment, `decimalNumber` is a variable in the global scope of our program: +Our `checkPassword` function is nice and reusable now with its ability to check any value we pass to it as an argument, but in practice we will see lots of functions which need more than one piece of information to do their job. How we provide this information is critical. In a future sprint we will look at ways of testing our code to ensure we have set everything up correctly but we can avoid a lot of problems by paying close attention to how we use our functions. -```js -const decimalNumber = 0.5; // defined in the global scope of our program +Let's create a new function to work with for this example. In a new file let's define a function which will print a greeting for someone with a different message depending on what time of day it is. -function convertToPercentage() { - const percentage = `${decimalNumber * 100}%`; - return percentage; +```js +function greet(timeOfDay, name){ + console.log(`Good ${timeOfDay}, ${name}.`); } +``` -const output1 = convertToPercentage(0.5); -const output2 = convertToPercentage(0.231); +#### Ordering + +If a function expects to receive two pieces of information then it expects to receive them in the order they are defined. In our example we have said the first argument `greet` receives will represent the `timeOfDay` parameter and the second argument will be for `name`. We can test it to see what happens: + +```js +greet("afternoon", "Colin"); +// "Good afternoon, Colin." ``` -So long as `decimalNumber` is always in the global scope, `convertToPercentage` will always go to the global scope to get the value of `decimalNumber`. +{{}} +Try to predict what will happen if we swap the order of the arguments when calling the function. -> However, we want `convertToPercentage` to work for _any_ input we pass to it. +
+ Answer: -To make a function work for any number, we need to handle inputs. We do this using a {{}} A parameter is a special kind of variable: its value is defined by the caller. -{{}}. + ```js + greet("Colin", "afternoon"); + // "Good Colin, afternoon." + ``` +
+{{
}} -`decimalNumber` is still a variable - but as a **parameter** we don't assign `decimalNumber` a value inside the function's body. It is a placeholder. When we call the function, we pass an input to the function, and the value of that input is assigned to the `decimalNumber` parameter when the function is called. This happens automatically. +As far as the function is concerned everything is fine: it needed two pieces of information and it got two, so it's happy. The output doesn't make sense to us as users though! -We can add a parameter `decimalNumber` to our function: +The output may not make much sense, but it could be worse. What might happen if one of the arguments was expected to be a number? If we're not careful when passing arguments we can cause errors by trying to do something we're not able to do to a value. -```js {linenos=table,hl_lines=["1"] ,linenostart=1} -function convertToPercentage(decimalNumber) { - // now decimalNumber is a parameter of convertToPercentage - const percentage = `${decimalNumber * 100}%`; - return percentage; -} +#### Wrong number of arguments -const output1 = convertToPercentage(0.5); -const output2 = convertToPercentage(0.231); -``` +Some languages are very strict about passing the right number of arguments to a function when it is called. JavaScript is not one of those languages. JavaScript is quite forgiving and will do its best with what we give it. -In the example above, we're calling `convertToPercentage` twice: first with an **input** of `0.5` and second with an **input** of `0.231`. In JavaScript instead of **input** we use the word {{}} Arguments are inputs given to a function inside `()`. An argument means an input.{{}}. +{{}} +Try to predict what will happen if we omit the second argument when calling our function. **Hint**: think about the value of a variable which we declare but never initialise. -We're calling `convertToPercentage` twice: first with an **argument** of `0.5` and next with an **argument** of `0.231`. +
+ Answer: -Think of a function as a box. We put data in and then act on it using the rules in the box; at the end, the box gives us new data back. In programming we say that we _pass arguments_ into a function, the function's code is executed and we get a return value after the function has finished executing. Here's a diagram: + ```js + greet("afternoon"); + // "Good afternoon, undefined." + ``` -```mermaid + When the function is called `timeOfDay` and `name` are both declared but we only have a value to assign to `timeOfDay`. `name` will remain `undefined` while the code is executed. +
-flowchart LR - A[argument] --> B{function} - B --> C[return] -``` +Now predict what will happen if we omit the _first_ argument. -Here's a diagram of what happens when `convertToPercentage` is passed a specific **argument**: +
+ Answer: -```mermaid + ```js + greet("Colin"); + // "Good Colin, undefined." + ``` -flowchart LR - A[0.231] --> B{convertToPercentage} - B --> C[23.1%] -``` + Remember that ordering matters. The interpreter will assign the first value it receives to the first parameter, it doesn't know there was meant to be something else there first. +
+ +{{
}} + +{{}} +Try to predict what will happen if we pass a third argument to our function. + +
+ Answer: + + ```js + greet("afternoon", "Colin", 2026); + // "Good afternoon, Colin." + ``` + + The function only expects two pieces of information and once it has them it doesn't care about anything else we give it. Remember about the ordering though! It only expects two values and it will take the **first** two values, whatever they are. +
+ +{{
}} + +#### Default values + +There are many reasons why we might be missing a piece of data which is actually quite important for our program. In production code we would usually have several checks in place to ensure we didn't even try to call our function if something was missing but it never hurts to have another one. + +In our `greet` example we were able to get away with the missing value because we can still print `undefined` but that won't always be the case. We can't add two numbers together if once of them is `undefined`, for example. To help avoid this we can assign **default values** to parameters when we define a function. If a function expects to receive a value when it is called but doesn't it will substitute the parameter's default, avoiding the value being `undefined`. + +{{}} +Research how to assign default values to a parameter and update the function definition so that it prints "user" instead of "undefined" if the `name` argument is not passed. **Hint**: The [functions page of the MDN docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions) could be a good place to start! + +
+ Solution: + + ```js + function greet(timeOfDay, name="user"){ + console.log(`Good ${timeOfDay}, ${name}.`) + } + ``` -In this interactive widget we have defined a parameter `decimalNumber` in the function declaration inside parentheses after the function name `convertToPercentage`. In our mental model, a function call means going to `convertToPercentage` and running the code inside the function. +
-### ๐ŸŽฎ Play computer +{{
}} - -Use the interactive widget to see what happens when the code above is executed. Pay close attention to what happens inside the `convertToPercentage` frame. diff --git a/common-content/en/module/js1/refactoring/index.md b/common-content/en/module/js1/refactoring/index.md new file mode 100644 index 000000000..a320a6e72 --- /dev/null +++ b/common-content/en/module/js1/refactoring/index.md @@ -0,0 +1,85 @@ ++++ +title = 'Refactoring' + +time = 20 +[objectives] +1='Define "refactoring"' +2='Modify code to change its structure without changing its functionality' +[build] + render = 'never' + list = 'local' + publishResources = false + ++++ + +Our `checkPassword` function is doing its job well but it's getting quite long. We also need to think about how it will interact with other parts of an application. + +Returning a string is fine when we're printing an output to the console but it's actually not that useful if we want to do something else with it in code. If another function wanted to use the returned value the workflow would look like this: + +```mermaid + +flowchart TB + +A[Get user input] --> B[Check if input matches password] +B --> C[Return string with message] +C --> D{Check the value of that string} +D --Correct message string--> E[Proceed] +D --Incorrect message string--> F[Inform user] + +``` + +We make two comparisons in a row: we ask if two strings match, which produces a string, then we check that string to see what it says. That's not very efficient. It would be much simpler if our password check gave a "yes" or "no" answer. + +In programming we can use the boolean values `true` and `false` when asking yes/no questions like this. We can update `checkPassword` to return these values by **refactoring** it. + +### Editing our code + +When we refactor code we make changes to its structure without changing how it behaves. In this example we will go slightly beyond what a typical refactor would involved because we will be changing the return values too, but our function will still be doing the same job. Let's swap the strings for `true` and `false`. + +```js {title="passwordCheckerFunction.js"} +const password = "secretword123"; + +function checkPassword(userInput){ + + let response; + + if (userInput === password) { + response = true; + } else { + response = false; + } + + return response; +} +``` + +Calling this function with different arguments will now return either `true` if the argument matches the value stored in `password` or `false` if it doesn't. So far so good! By making `response` a boolean we have made our code easier to understand, but also made it less likely that we will make a mistake by trying to match a complex string. + +We could go even further and reduce our function's length. Our if statement is evaluating an expression, and if it evaluates to `true` we are setting `response = true`. Likewise if the expression is `false`. Why not just store the result of the evaluation in `response`? That would get rid of three lines of code! + +```js {title="passwordCheckerFunction.js"} +function checkPassword(userInput){ + + const response = userInput === password; + + return response; +} +``` + +{{}} +We have just made a fairly big change to our code so don't worry if it takes a moment to fully understand what has happened. You can check that everything still works by calling the function with different arguments and observing the output. +{{}} + +We have also switched to use `const` in the variable declaration since we don't need to reassign it any more. We can go even further, though. We declare the `response` variable then immediately return it without using it for anything else. Since we are done with it so quickly, why bother with the variable declaration at all? Why not go straight to returning the expression? + +```js {title="passwordCheckerFunction.js"} +function checkPassword(userInput){ + + return userInput === password; + +} +``` + +Now it's even shorter! If we _really_ wanted to we could get the whole thing on one line but we'll leave that for now. We'll find out how we can do that with a different way of declaring functions in a future module. + +There is a trade-off here. We have made our function much shorter but this often happens at the expense of readability. Don't be tempted to refactor too far and make things difficult for anyone (including yourself) reading your code in the future. \ No newline at end of file diff --git a/common-content/en/module/js1/return/index.md b/common-content/en/module/js1/return/index.md index eb6e66689..175313d02 100644 --- a/common-content/en/module/js1/return/index.md +++ b/common-content/en/module/js1/return/index.md @@ -5,7 +5,6 @@ time = 30 [objectives] 1='Identify the return value at a call site given its function declaration' 2='Log the return value of a function' - 3='Given a short program, state the number of times a given function is called' [build] render = 'never' list = 'local' @@ -13,81 +12,42 @@ time = 30 +++ -We need a way to access the percentage string that is created inside `convertToPercentage`. To access values created inside functions, we write {{}}We write a return statement to specify a function's return value. If your function call is like a question, the return value is the answer. It's what comes back.{{}}. +We need a way to access the value that is created inside `checkPassword`. To access values created inside functions, we use the **return** keyword. When we **return** something from a function we make it available at the point the function was called. -We can add a return statement to `convertToPercentage` like this: +Let's undo our global variable changes from the last section and add a return statement to the function: -```js {linenos=table,hl_lines=["4-5"],linenostart=1} -const decimalNumber = 0.5; +```js {title="passwordCheckerFunction.js"} +const password = "secretword123"; -function convertToPercentage() { - const percentage = `${decimalNumber * 100}%`; - return percentage; -} -``` - -If we want, we could also remove the variable `percentage`, since we can return the value of the expression directly: - -```js {linenos=table,hl_lines=["4"],linenostart=1} -const decimalNumber = 0.5; - -function convertToPercentage() { - return `${decimalNumber * 100}%`; -} -``` - -### ๐Ÿ”Ž Checking the output - -We can store a function's return value in a variable. - -```js -const result = Math.round(10.3); -console.log(result); // logs 10 to the console -``` - -We call `Math.round` which takes the input `10.3` and then returns the rounded number `10`. So `result` stores a value of `10`. - -`Math.round` is a function implemented by other developers and `convertToPercentage` is a function _we're_ implementing, but calling `convertToPercentage` is just like calling `Math.round`. - -Now we want to **call** the function `convertToPercentage` and **store the return value** in a variable. - -{{}} +function checkPassword(userInput){ -===[[Store the return value]]=== + let response; -We can store the return value in a variable in exactly the same way: + if (userInput === password) { + response = "Correct password entered"; + } else { + response = "Incorrect password, please try again"; + } -```js {linenos=table,hl_lines=["8"],linenostart=1} -const decimalNumber = 0.5; - -function convertToPercentage() { - const percentage = `${decimalNumber * 100}%`; - return percentage; + return response; } - -const result = convertToPercentage(0.5); ``` -===[[Log the return value]]=== +We haven't quite fixed everything though. If we call the function and try to print `response` like before we'll still get a `ReferenceError`. -Log out the value of `result` to the console using `console.log`. +### Using the output -```js {linenos=table,hl_lines=["9"],linenostart=1} -const decimalNumber = 0.5; +We sometimes refer to the value returned by a function as its **output**. We can store that output in a variable. -function convertToPercentage() { - const percentage = `${decimalNumber * 100}%`; - return percentage; -} - -const result = convertToPercentage(0.5); -console.log(result); +```js {title="passwordCheckerFunction.js"} +const output = checkPassword("secretword123"); ``` -This will now print the following when run: +Now the value returned by our function is stored in the `output` variable and can be handled just like any other variable. Let's try printing it to check everything worked: -``` -50% +```js {title="passwordCheckerFunction.js"} +console.log(output); +// "Correct password entered" ``` -{{}} +Success! \ No newline at end of file diff --git a/common-content/en/module/js1/reusing-variable-names/index.md b/common-content/en/module/js1/reusing-variable-names/index.md deleted file mode 100644 index 910cdd821..000000000 --- a/common-content/en/module/js1/reusing-variable-names/index.md +++ /dev/null @@ -1,119 +0,0 @@ -+++ -title = 'Reusing variable names' - -time = 30 -[objectives] -1='Fix code which declares the same identifier more than once' -[build] - render = 'never' - list = 'local' - publishResources = false - -+++ - -We saw this error: - -``` -SyntaxError: Identifier 'currentOutput' has already been declared -``` - -Now that we understand it, let's fix it. - -We're not allowed to declare a new variable with the same name as an old one. Both lines 5 and 12 here try to declare a new variable named `currentOutput`: - -```js {linenos=table,linenostart=1,hl_lines=["5", "12"]} -function formatAs12HourClock(time) { - return `${time} am`; -} - -const currentOutput = formatAs12HourClock("08:00"); -const targetOutput = "08:00 am"; -console.assert( - currentOutput === targetOutput, - `current output: ${currentOutput}, target output: ${targetOutput}` -); - -const currentOutput = formatAs12HourClock("23:00"); -const targetOutput = "11:00 pm"; -console.assert( - currentOutput === targetOutput, - `current output: ${currentOutput}, target output: ${targetOutput}` -); -``` - -{{}} - -Make sure you understand the error message before you try to fix the code. - -If you don't understand what's wrong, you probably won't be able to fix it! - -{{}} - -### Fixing the error - -We want to do multiple assertions. And we're using variables in our assertions. But we're not allowed to use the same name twice. The simplest way we can fix this problem is by changing the name of the second variable. Remember to also change where we _use_ the variable, not just where we declare it! - -```js {linenos=table,linenostart=1,hl_lines=["12", "15", "16"]} -function formatAs12HourClock(time) { - return `${time} am`; -} - -const currentOutput = formatAs12HourClock("08:00"); -const targetOutput = "08:00 am"; -console.assert( - currentOutput === targetOutput, - `current output: ${currentOutput}, target output: ${targetOutput}` -); - -const currentOutput2 = formatAs12HourClock("23:00"); -const targetOutput = "11:00 pm"; -console.assert( - currentOutput2 === targetOutput, - `current output: ${currentOutput2}, target output: ${targetOutput}` -); -``` - -### Trying again - -After making this change, let's try running our code again. We get this output: - -```console -% node clock-example.js -/Users/dwh/CYF/clock-example.js:13 -const targetOutput = "11:00 pm"; - ^ - -SyntaxError: Identifier 'targetOutput' has already been declared - at wrapSafe (node:internal/modules/cjs/loader:1383:18) - at Module._compile (node:internal/modules/cjs/loader:1412:20) - at Module._extensions..js (node:internal/modules/cjs/loader:1551:10) - at Module.load (node:internal/modules/cjs/loader:1282:32) - at Module._load (node:internal/modules/cjs/loader:1098:12) - at TracingChannel.traceSync (node:diagnostics_channel:315:14) - at wrapModuleLoad (node:internal/modules/cjs/loader:215:24) - at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:158:5) - at node:internal/main/run_main_module:30:49 - -Node.js v22.4.1 -``` - -Fortunately, we've seen this kind of error before. It's exactly the same as the last one, but about the `targetOutput` variable on line 13, instead of the `currentOutput` variable on line 12. - -{{}} -Fix this error, and try running your code again. -{{}} - -Now the second assertion fails with the following message: - -```console -% node clock-example.js -Assertion failed: current output: 23:00 am, target output: 11:00 pm -``` - -We expect this. Our function just adds " am" to the end of the time, which only works for times in the morning. We have proven our code isn't complete yet. Next we can fix it so that this test passes. - -{{}} - -โœ๏ธ Write another assertion that checks `formatAs12HourClock` returns the target output when passed another _time input in the afternoon._ - -{{}} diff --git a/common-content/en/module/js1/scope/index.md b/common-content/en/module/js1/scope/index.md index d5c7cf259..b88de256c 100644 --- a/common-content/en/module/js1/scope/index.md +++ b/common-content/en/module/js1/scope/index.md @@ -12,23 +12,69 @@ time = 20 +++ -The function `convertToPercentage` will only be useful if we can access the `percentage` string that it creates. Otherwise, we won't be able to use the result of `convertToPercentage` in other parts of our code. We can try accessing the `percentage` variable outside the function body like this: +At the moment our password checking function does what we need it to but is quite limited. The only way it can let us know if the input was correct or not is by printing a message, but what if another part of the program needs to know? -```js {linenos=table,hl_lines=["8"],linenostart=1} -const decimalNumber = 0.5; +For that to happen we will need to store the response in a variable, so let's make some changes to our code: -function convertToPercentage() { - const percentage = `${decimalNumber * 100}%`; +```js {title="passwordCheckerFunction.js"} +const password = "secretword123"; + +function checkPassword(userInput){ + + let response; + + if (userInput === password) { + response = "Correct password entered"; + } else { + response = "Incorrect password, please try again"; + } } +``` + +Now we can call our function then try printing `response`: -convertToPercentage(0.5); -console.log(percentage); +```js {title="passwordCheckerFunction.js"} +checkPassword("secretword123"); + +console.log(response); ``` -However if we run the code above, we get an error: +It looks like we have a problem though... ```console -ReferenceError: percentage is not defined +ReferenceError: response is not defined +``` + +We definitely did define `response` though, it's right there above the `if` statement! It's the only variable which throws this error: if we print `password` the value will be displayed. So why does it work for one and not the other? + +We get an error because of the variable's **scope**. Scope determines where a variable can be accessed from in our code. When we define `passwordChecker` we also define a **local scope** - the block of code enclosed inside `passwordChecker`'s function body. This means any variables we declare inside that local scope can only be accessed within the same block. If we attempt to reference a variable from outside the scope where it was declared we get a `ReferenceError`. + +The `response` variable is declared _inside_ `passwordChecker`'s local scope so when we try to print it the `ReferenceError` is thrown. The `password` variable is declared _outside_ the function's local scope so we can access it without the error being thrown. + +### Global Scope + +There are two ways in which we could fix this. The first is to move the `response` declaration outside of the function. That means it is no longer within the function's scope but that could cause some problems for us in future. What happens if the code in the function isn't executed? Our variable would always have the value `undefined` and we may not be prepared to handle that. + +The second is to remove the declaration altogether and handle declaration and assignment at the same time in the `if` block. TRy it now and see what happens! + +```js {title="passwordCheckerFunction.js"} +const password = "secretword123"; + +function checkPassword(userInput){ + if (userInput === password) { + response = "Correct password entered"; + } else { + response = "Incorrect password, please try again"; + } +} + +checkPassword("secretword123"); + +console.log(response); ``` -We get an error because of {{}}Scope means where variables are and what you can access. {{}}. When we define `convertToPercentage` we also define a **local scope** - the region of code enclosed inside `convertToPercentage`'s function body. This region is `convertToPercentage`'s **local scope**. This means any variables we declare inside `convertToPercentage`'s **local scope** can only be accessed within this region. If we attempt to reference a variable outside the scope where it was declared, then get a `ReferenceError`. +No error, and the correct value is printed. So why does this work? + +When we declare a variable using `const` or `let` it gives the variable local scope. When we don't use a keyword the variable has **global** scope instead. Now there are no restrictions, the variable can be accessed from anywhere. That doesn't sound very secure though, does it? + +We have a stand-off: on one side our code is secure but we can't access the value we need, on the other we can access the value but so can everything else. We need to make some changes to our function to fix this. diff --git a/common-content/en/module/js1/scripts/index.md b/common-content/en/module/js1/scripts/index.md index d421d4fa6..ed9261ca2 100644 --- a/common-content/en/module/js1/scripts/index.md +++ b/common-content/en/module/js1/scripts/index.md @@ -1,9 +1,10 @@ +++ title = 'Running scripts' -time = 10 +time = 20 [objectives] 1='Execute a JavaScript file with Node' + 2='Use `console.log()` to print a value' [build] render = 'never' list = 'local' @@ -11,37 +12,76 @@ time = 10 +++ -So far weโ€™ve seen how expressions can be evaluated using the Node REPL. The Node REPL is useful for evaluating expressions quickly. +It's time to write our first lines of JavaScript! -But usually, our programs have many instructions, and we want to keep and re-run them instead of typing them out each time. So we save our instructions in files. Node can also execute instructions written in a file. +There are some tools available which will enable us to write code and instantly see the results. These are called **REPL**s - **R**ead, **E**valuate, **P**rint and **L**oop. These are great for quickly checking something but not very practical for production uses. -We use the `node` command to run a JavaScript file in the terminal. A JavaScript file ends with `.js` - this is the "file extension". +Usually our programs will have many instructions which we want to keep and re-run instead of typing them out each time. So we save our instructions in files. We can run these files from the terminal. -Letโ€™s suppose we have a file `age.js`. We run the command `node age.js`. This terminal command is an instruction to execute the program written inside `age.js`. Our program has five lines. -So the computer will read and execute the program one line at a time: +We use the `node` command to run a JavaScript file in the terminal. A JavaScript file ends with the `.js` file extension. -```js -const yearOfBirth = 1990; // declaration -let currentYear = 2023; // declaration +Letโ€™s suppose we have a file `hello_world.js`. We run the command `node hello_world.js`. This terminal command is an instruction to execute the program written inside `hello_world.js`. -currentYear++; // statement -`I am ${currentYear - yearOfBirth} years old`; // statement + +### Printing to the terminal + +Our first program will print the text "Hello World!" in the terminal. First we need to create a file to work in. + +Open a terminal. You can either do this using your Terminal app or in VSCode, it doesn't matter. Navigate to the `prep` directory you created in the last section and create a file called `hello_world.js`. + +{{}} +Remember that you can use the `pwd` command to **p**rint **w**orking **d**irectory if you lose track of where you are in your file system. +{{}} + +```shell {title="Terminal"} +cd Module-Onboarding/prep # Replace this with your file path if it's different +touch hello_world.js ``` -{{}} +Open your new file in VSCode. -### Check you can run a file with Node: +JavaScript prints values to the terminal using a function called `console.log`. -1. In your terminal, create a new file called `example.js`. -2. Try writing a few lines in the file. -3. Get Node to run this file. (Don't use the REPL now - you should run a command to execute the whole file.) +{{}} +**console** usually means _a text interface_ like a terminal. A **log** is a written record of something that happened. + +So `console.log` will _record something that happens in our program_ and print it to a _text based interface_. {{}} -Once the computer executes these statements, the execution of the program is complete. But weโ€™re left with a problem. With the REPL, when the user inputs an expression statement or declaration, the computer reads and executes the line and _immediately_ prints feedback to the terminal. With a file, the computer will execute each line sequentially until completion _without_ printing the values of each expression it evaluates. +`console.log` prints the result of expressions while our program is executing. Usually we will interact with our programs using some sort of graphical interface like a web browser so we won't use this function often, but it is a very useful tool to help us solve problems in our code. It lets us check what values expressions evaluate to at _specific moments_ of our program execution. + +Let's see how to use `console.log` . In your `hello_world.js` file write the name of the function `console.log`, a set of parentheses `()` and the message to be printed. + +```js {title="hello_world.js"} +console.log("Hello World!"); +``` + +{{}} +Note that we have added a semicolon (`;`) at the end of the expression. Different programming languages handle semicolons in different ways: in some languages they are essential, in others including them will cause an error. -So this new problem can be expressed as a question: +JavaScript code will run with or without a semicolon at the end of expressions but it's good practice to include them. They help to keep your code organised and are helpful for anyone reviewing your code. Plus it's good practice if you ever use a language like Java where they are required! +{{}} -> โ“ Problem -> -> "How can we check what the values evaluated to in our program during execution?" +Now switch to the terminal and run the file using `node`: + +```sh {title="Terminal"} +node hello_world.js +``` + +{{}} +You may see an error message saying "cannot find module" when you run this command. That means Node can't find the file you have asked it to run. Use `pwd` to check you are in the right directory. If not, navigate to teh correct place using `cd` and try again. +{{}} + +We should see the string `"Hello World!"` logged out in the terminal. Congratulations, you have written your first JavaScript program! + + +{{}} + +Let's try again from the beginning + +1. In your terminal, create a new file called `facts.js`. +2. Pick one of your fun facts from the Git sections in the first sprint +3. Run the file using Node. + +{{}} diff --git a/common-content/en/module/js1/strategy/index.md b/common-content/en/module/js1/strategy/index.md index a474edcc5..fe3f5db5e 100644 --- a/common-content/en/module/js1/strategy/index.md +++ b/common-content/en/module/js1/strategy/index.md @@ -13,28 +13,29 @@ hide_from_overview = true +++ -Our function works for morning inputs like `"08:00"`. In this case, the function returns the target output of `"08:00 am"` as required. However, at the moment, the output of `formatAs12HourClock("23:00")` is `"23:00 am"`. +Let's return to our password example from the previous section. Our code needs to be able to handle two possible scenarios: -> ๐Ÿ’ก We need to execute some different logic when the time is beyond midday +- The user enters the correct password +- The user enters the wrong password -We can interpret this behaviour as a question: +When we design our code we can interpret this as a question: ```mermaid flowchart LR -A{Is the time before midday?} -- true --> B[Add am to time string] -A -- false --> C[???] +A{Did the user enter the correct password?} -- true --> B[Load the user's desktop] +A -- false --> C[Prompt the user to try again] ``` -We need to make two changes to our code. +We need to consider both possibilities when writing our code. -1. We need to do something different depending on whether the time is before midday. This is called running code **conditionally**. -2. And then we need to know what we do if the time is after midday. +1. We should only load the desktop if the correct password is entered. This is called running code **conditionally**. +2. We need to know what to do if the incorrect password is entered. -We don't need to solve the whole problem at once. First let's work out how to do something different depending on the time. We can worry about what we need to do differently once we've solved this problem. +We don't need to solve the whole problem at once. First let's work out how to do something different if the password is correct. We can worry about what we need to do differently once we've solved this problem. -{{}} +{{}} It's easier to search for the solutions to smaller parts of problems than the whole problem. Programming is all about breaking down problems into smaller pieces which we can solve. diff --git a/common-content/en/module/js1/terminal/index.md b/common-content/en/module/js1/terminal/index.md index 460947828..ce5a5caf3 100644 --- a/common-content/en/module/js1/terminal/index.md +++ b/common-content/en/module/js1/terminal/index.md @@ -12,35 +12,66 @@ time = 10 +++ -Programmers need interfaces to ask computers to do things. A computer terminal is an **interface** where programmers can issue commands to a computer. Because users enter text instructions and receive text output, we say that the terminal is a **text-based interface**. +Programmers need interfaces to ask computers to do things. A computer terminal is an **interface** where programmers can issue commands to a computer. Because users enter text instructions and receive text output, we say that the terminal is a **text-based interface**. It is also often referred to as the **command line**. -### Open Your Terminal +### Opening the Terminal -#### Interface via the terminal +#### The Terminal Application -We can input a command into the prompt and hit enter. The terminal then passes this command to the computer to execute. Find your own terminal and input the `ls` command: +Every computer has a built-in application which we can use as a terminal. On Mac and Linux this app is conveniently called "Terminal"! -``` -ls -``` - -#### The terminal on Mac +When you open the terminal you will see a blank screen with a cursor waiting for input. You can type instructions here and the computer will carry them out. Some instructions are quite simple, others can be quite complex. Anything you can do in an application like Explorer can be done here by typing a command, and you can often do it much quicker in the terminal! The example below shows a user listing the contents of a directory. ![terminal](terminal.gif "The terminal is a window on the computer, prompting users for instructions. ") -### ๐Ÿ–Š๏ธ Writing computer instructions +#### The Terminal in VSCode + +We can also open a terminal within VSCode, meaning we don't need to switch between applications while we work. This is really useful when we need to refer back to the results of previous commands, such as logging output or test results. Anything we can do in the terminal app can be done within VSCode. + +You can open a terminal in VSCode by clicking `Terminal -> New Terminal`. + +![VSCode Terminal](vscode_terminal.png "Opening a Terminal in VSCode") + +### Writing Commands + +We can issue commands to the computer using the terminal. These commands are instructions that the computer knows how to interpret. As we go through the course we will introduce some commands which need particular tools to work, but for now we will focus on exploring our file system. + +One of the most useful commands is `pwd`, for **print working directory**. This will tell you where you are in your file system, like pulling out a map with a big "you are here" sign on it. + +The `ls` command means **"list the files and directories in the current directory"**. + +To move from one directory to another we can use the `cd` (**change directory**) command. This is an example of a command which needs some extra information - we need to tell it where we want to go! For example, we would navigate to our `Downloads` folder using `cd Downloads`. -We can issue commands to the computer using the terminal. These commands are instructions that the computer knows how to interpret. +{{}} -The computer knows `ls` means **"list the files and directories in the current directory"**. +The commands we use are **case-sensitive**, which means we need to take care with capital letters. As far as the computer is concerned a folder called `downloads` and another called `Downloads` have totally different names! This is a really common cause of bugs, so if something doesn't work the way you expect you should always check your spelling! -During the execution of a computer program, a computer will store and modify {{}}Data is information. Text, images, numbers are all _forms_ of data.{{}} The data in an executing program is sometimes called the **state**. A computer program will modify data with {{}} Operations modify or create data, from the current data in the program. Adding numbers, joining words, changing text to ALLCAPS, are all operations. -{{}} +{{}} + +We can make our own new directories using the `mkdir` command. When we use this command we need to provide a name for our new directory, eg. `mkdir my_stuff`. + +We create new files using `touch`, and just like with directories we need to provide a name. An important part of creating a file is providing a **file extension**. This tells the computer what kind of file we have created, for example `document.txt` will be a text file and `picture.png` will be an image. You can create any kind of file using the terminal. + +{{}} + +Coming up with names for things is one of the most challenging aspects of programming. In general a good name will make it obvious what a file contains without being too long, although there will be occasions where a file needs to have a specific name in order for something to work. + +- โœ… `shopping_list.txt` +- โŒ `things_i_need_to_by_in_tesco_this_weekend_version_2.txt` +- โŒ `stuff.txt` + +{{}} -`ls` is a shell command. Shell is a programming language we use to interact with the files and folders on our computer. You already know at least two more programming languages. Can you name them? +{{}} -{{}} +Visit [Terminal Temple](https://www.terminaltemple.com/) and try to complete the following tasks. Don't worry if something goes wrong, you can reset by pasting `resetterm --force` into the interface and pressing enter. -A **programming language** is a limited set of rules for writing computer instructions. +1. Move into the `Documents` folder. +2. Create a new directory called `study-plans`. +3. Move into your new directory. +4. Create two new files: `week1.txt` and `week2.txt`. +5. Move back to the `Documents` directory - this will need some further research! +6. Delete `empty-file.txt`. This will also need some research! +7. Check that the file was deleted by listing the contents of the directory. {{}} diff --git a/common-content/en/module/js1/terminal/vscode_terminal.png b/common-content/en/module/js1/terminal/vscode_terminal.png new file mode 100644 index 000000000..5ad41a91c Binary files /dev/null and b/common-content/en/module/js1/terminal/vscode_terminal.png differ diff --git a/common-content/en/module/js1/variables/index.md b/common-content/en/module/js1/variables/index.md index 69f892b14..67bfc0f2a 100644 --- a/common-content/en/module/js1/variables/index.md +++ b/common-content/en/module/js1/variables/index.md @@ -1,11 +1,13 @@ +++ title = 'Saving expressions' -time = 15 +time = 25 [objectives] 1='Identify the syntactic features of a variable declaration' 2='Explain why we use variable declarations' 3='Create strings using variables and template literals' +4='Describe the difference between `const` and `let`' +5='Describe the difference between a declaration and a statement' [build] render = 'never' list = 'local' @@ -15,13 +17,15 @@ time = 15 In programming we often want to _reuse_ our work. Consider the string: `"Hello there"` -Suppose we want to create different greetings for different people, like: `"Hello there, Alicia"` `"Hello there, Barny"` +Suppose we want to create different greetings for different people, like: `"Hello there, Alicia"` or `"Hello there, Barney"` -We can use a **variable** to store this string and reuse it. How can we create a {{}}A **variable** is a label for a piece of data. We assign a piece of data to a label and then refer back to this label, in place of the data.{{}} +We can use a **variable** to store this string and reuse it. A variable is a label for a piece of data. We assign a piece of data to a label and then refer back to this label, in place of the data. -We can create a variable in our program by writing a **variable** {{}}A _declaration_ is an instruction that binds an identifier to a value.{{}}, like this: +### Declaring variables -```js title="variable declaration" +We can create a variable in our program by writing a **variable declaration**. A declaration is an instruction that binds an identifier to a value, like this: + +```js const greeting = "Hello there"; ``` @@ -32,65 +36,79 @@ Break down the different syntactic elements of this variable declaration: - `=` is the assignment operator. It means assign to the label `greeting` the value of the expression on the right hand side. - `"Hello there"` - this is the expression whose value we're assigning to the label `greeting`. -{{}} +{{}} +In your terminal create a new file called `greeting.js`. Open the file in VSCode and declare a variable called `greeting` like we did above. +{{}} -===[[Try it yourself]]=== -Type this variable declaration into the REPL: -``` -const greeting = "Hello there"; -``` +### Accessing variables -Now refer to the label `greeting` in the REPL: +Our data is stored in a variable, so how can we use it again later? -``` -`${greeting}, Alicia` +To access the data stored in a variable we just need to type the variable's name. When our code is executed the appropriate value will be inserted and the expression will be evaluated. Try it now with your new variable: + +```js {title="greeting.js"} +console.log(greeting); ``` -Our `greeting` variable is stored in memory. We can reuse it to build more expressions: +`"Hello there"` has been printed to the terminal even though we didn't explicitly write that in the code. -``` -`${greeting}, Barny` -``` -===[[Watch and follow along]]=== +### Using variables in expressions -![greeting](greeting.gif "Store your string in a variable and reuse it") +Accessing variables can form part of complex expressions. Let's add a second variable called `name` to our program. We'll also add this variable to our `console.log` call so we print the greeting and the name together. -{{}} +```js {title="greeting.js"} +const greeting = "Hello there"; +const name = "Alicia"; +console.log(`${greeting}, ${name}`); +``` We just used backticks to create a template literal. ```js -`A template literal places ${expressions} inside strings; +A template literal places ${expressions} inside strings; ``` With template literals, we can insert expressions into strings to produce new strings. Any time we want to reference a variable inside a template literal we use a dollar sign `$` and a set of curly braces `{}`. We can put any expression (e.g. a variable name) inside the curly braces. The value that expression evaluates to is then placed inside the string. -When an operation uses an expression, that expression is immediately evaluated, and how it was written is forgotten about. That means that the `greetAlicia` variable is the same in all three of these cases: +When an operation uses an expression, that expression is immediately evaluated, and how it was written is forgotten about. Each of these expressions evaluates to the same thing: ```js -const greetAlicia = "Hello there, Alicia"; +"Hello there, Alicia"; +`Hello there, ${name}`; +`${greeting}, ${name}`; +greeting + ", " + name; ``` -{{}} -In this example, we don't use a variable or a template to create a string. Instead we write a string `"Hello there, Alicia"`. +{{}} +In the first example we don't use a variable or a template to create a string. Instead we write a string `"Hello there, Alicia"`. A sequence of characters enclosed in quotation marks is called a **string literal**. `"Hello there, Alicia"` is a string literal. Similarly, `10` is a **number literal**. - ## {{}} -```js -const name = "Alicia"; -const greetAlicia = `Hello there, ${name}`; -``` +### Reassigning a variable -```js +Let's say we want to greet people in a different way. That would mean changing the value of our `greeting` variable. This is a very common thing to do, in fact many of the programs you write will need you to do this. + +We reassign a variable using the `=` operator: + +```js {title="greeting.js"} const greeting = "Hello there"; -const name = "Alicia"; -const greetAlicia = `${greeting}, ${name}`; +greeting = "Good morning" +``` + +If we try to run our code now we'll see an error (more on these at the end of this sprint). What went wrong? + +The `const` keyword means that our variable is a **constant** - we can't change its value! If we need to reassign a variable we need to use the `let` keyword when declaring the function instead. + +```js {title="greeting.js"} +let greeting = "Hello there"; +greeting = "Good morning" ``` -The `greetAlicia` variable doesn't remember whether you used variables to make it or not - in all three cases, `greetAlicia` contains the string `"Hello there, Alicia"`. Once a value is made, it doesn't matter _how_ it was made. +Now it works! + +The first line of this block is the variable **declaration**, the second line is a **statement**. Note that we don't need to use `let` again when reassigning the variable. diff --git a/common-content/en/module/onboarding/expectations/index.md b/common-content/en/module/onboarding/expectations/index.md index 88ba05649..6842d1f17 100644 --- a/common-content/en/module/onboarding/expectations/index.md +++ b/common-content/en/module/onboarding/expectations/index.md @@ -11,21 +11,21 @@ hide_from_overview="true" publishResources = false +++ -## Learners, we expect you to: +### Learners, we expect you to: - Work in groups and individually, in class and during the week. - Show up on time and participate in all activities, including helping others. - Complete the work in the way it is specified. - Do your best. -## Learners, you can expect: +### Learners, you can expect: - Fair, achievable requirements, explained as clearly as possible. - Help from volunteers and other learners with your questions and blockers. - A safe, inclusive environment where you can learn and grow. - Many opportunities to succeed. -## We expect everyone to: +### We expect everyone to: - Follow the [Code of Conduct](https://codeyourfuture.io/about/code-of-conduct/). - Help each other. diff --git a/common-content/en/module/onboarding/git/configuring-git-vscode/index.md b/common-content/en/module/onboarding/git/configuring-git-vscode/index.md new file mode 100644 index 000000000..916bb8925 --- /dev/null +++ b/common-content/en/module/onboarding/git/configuring-git-vscode/index.md @@ -0,0 +1,103 @@ ++++ +title = "Configuring Git with VSCode" +time = 20 +[tasks] +1 = "Install Git on your machine" +2 = "Configure Git with your name and email" +3 = "Set VSCode as your default Git editor" +4 = "Test your Git configuration" +[build] + render = 'never' + list = 'local' + publishResources = false ++++ + +Git is a version control system that helps developers track changes to their code. Before you can use Git effectively, you need to configure it on your machine and connect it with VSCode, your code editor. + +### What is Git? + +Git allows you to: +- Track every change you make to your files +- Work collaboratively with other developers +- Save different versions of your project +- Revert to previous versions if something goes wrong + +### Step 1: Install Git + +#### On Mac +1. Go to [https://git-scm.com/download/mac](https://git-scm.com/download/mac) +2. Download and install the package +3. Open Terminal and type: `git --version` to verify installation + +#### On Linux +Open your terminal and run: +``` +sudo apt-get install git +``` +Then verify: `git --version` + +{{}} +A terminal (also called command line or console) is a text-based interface where you type commands to control your computer. Think of it as giving your computer instructions in its native language. + +We will learn a lot more about the terminal in future sprints. +{{}} + +### Step 2: Configure Git with Your Name and Email + +Git needs to know who you are. Open your terminal and type these commands (replace the values with your own): + +``` +git config --global user.name "Your Full Name" +git config --global user.email "your.email@example.com" +``` + +**Why is this important?** Every commit (version save) will be labeled with your name and email, so others can see who made changes. + + +### Step 3: Set VSCode as Your Default Git Editor + +When you make a commit, Git might open a text editor to let you write a detailed message. Let's tell Git to use VSCode: + +``` +git config --global core.editor "code --wait" +``` + +This tells Git: "When I need an editor, use VSCode and wait for me to save and close it before continuing." + +### Step 4: Verify Your Configuration + +Run this command to see all your Git settings: + +``` +git config --list +``` + +You should see: +- `user.name=Your Full Name` +- `user.email=your.email@example.com` +- `core.editor=code --wait` + +{{}} +If the configuration doesn't appear, or if you see errors, don't worry. The most important settings are `user.name` and `user.email`. You can always reconfigure later. + +**Can't open terminal?** +- Mac: Press `Cmd + Space`, type "Terminal" +- Linux: Right-click desktop and select "Open Terminal Here" + +If the output doesn't make sense or you can't find what you're looking for you can post a screenshot in Slack and ask for advice. You can also ask a volunteer in class. +{{}} + +### What's Next? + +Now that Git knows who you are, you're ready to: +1. Create a local repository +2. Make commits (save versions of your work) +3. Push your code to GitHub + +You'll learn these skills in the next sections! + +### Further Reading + +- [Git Official Documentation](https://git-scm.com/doc) +- [Atlassian Git Tutorial - Getting Started](https://www.atlassian.com/git/tutorials/setting-up-a-repository) +- [GitHub's Git Guides](https://github.github.io/training-kit/) diff --git a/common-content/en/module/onboarding/git/creating-a-commit/commit-history.png b/common-content/en/module/onboarding/git/creating-a-commit/commit-history.png new file mode 100644 index 000000000..a377a6350 Binary files /dev/null and b/common-content/en/module/onboarding/git/creating-a-commit/commit-history.png differ diff --git a/common-content/en/module/onboarding/git/creating-a-commit/first-commit.png b/common-content/en/module/onboarding/git/creating-a-commit/first-commit.png new file mode 100644 index 000000000..8909535bc Binary files /dev/null and b/common-content/en/module/onboarding/git/creating-a-commit/first-commit.png differ diff --git a/common-content/en/module/onboarding/git/creating-a-commit/index.md b/common-content/en/module/onboarding/git/creating-a-commit/index.md new file mode 100644 index 000000000..2605cadee --- /dev/null +++ b/common-content/en/module/onboarding/git/creating-a-commit/index.md @@ -0,0 +1,139 @@ ++++ +title = 'Creating a Commit' +time ="45" +objectives = [ + "Use Git to identify which files have been changed", + "Selected files to be included in a commit", + "Create a commit" +] +hide_from_overview = true +[build] + render = 'never' + list = 'local' + publishResources = false + ++++ + +A **commit** is a saved version of your project at a particular moment in time. Think of it like saving a document, but with a detailed message explaining what changed and why. + +### Understanding the Three States + +Git has three states for your files: + +1. **Modified** - You changed the file, but haven't saved the version yet +2. **Staged** - You've marked the file as ready to be saved +3. **Committed** - The file is now saved in Git history + +```mermaid + +flowchart LR + +A["`Working Directory +(Modified)`"] --> B["`Staging Area +(Staged)`"] +B --> C["`Git Repository +(Committed)`"] +``` + +### Step 1: Create a New Repository + +A repository is a folder where Git tracks all your files and their changes. + +1. Create a new folder for your project called `my-first-repository`. Open it in VSCode. + +2. We're going to **initialise a Git repository** in this folder. Open the `Source Control` tab on the left of the VSCode window (highlighted red in the screenshot below) then click the `Initialize Repository` button. + +![VSCode source control tab for repo initialisation](initialise-repo.png) + +The tab should now look like this: + +![VSCode source control tab after repo initialisation](new-repo-view.png) + +### Step 2: Create a File and Make Changes + +Let's create a simple text file: + +1. Create a new file called `notes.txt` in your `my-first-repository` folder. +2. Add some text: + ```console + My First Git Project + + Today I'm learning Git! + This is my first commit. + ``` +3. Save the file + +### Step 3: Check the Status of Your Repository + +Let's see what's changed in VSCode after adding our file. The first thing you will notice is that our file name is now green with the letter U next to it: + +![explorer view after adding new file](new-file-explorer-view.png) + +We also now have an icon on the source control tab. If we click there we can see our file is listed here too: + +![source control view after adding new file](new-file-source-control-view.png) + +The green U means our file is **untracked**. + +Git is saying: "I see a file called `notes.txt`, but you haven't told me to track it yet." + +### Step 4: Stage Your Changes + +Now we tell Git we want to save this version of the file. This is called **staging**. When you hover your mouse over the file name a plus symbol will appear: + +![staging highlight](staging-highlight.png) + +Click the button and the file will move to a new section called `Staged Changes`: + +![staged change](staged-change.png) + +The letter has changed to an A for **added** too. Git is saying: "I'm ready to save this file." + +### Step 5: Create Your First Commit + +It's time to make our first commit and save this version of our file into our Git history. In the text box in the source control tab we can enter a **commit message**. The message describes what we changed. Add the text "Add initial project notes" then click the "Commit" button to make our first commit! + +![first commit message](first-commit.png) + +{{}} +Write messages that explain **what** you changed and **why**: +- โœ… Good: "Add login button to homepage" +- โœ… Good: "Fix bug where users can't save files" +- โŒ Avoid: "stuff", "changes", "update" + +Keep messages short but clear (under 50 characters is ideal). +{{}} + +### Step 6: View Your Commit History + +VSCode has a tool which lets us see the messages attached to every commit in our repository. Scroll down to the "graph" section of the page to see it. + +![commit history](commit-history.png) + +You should see your commit with: +- Your name +- Your commit message +- The word `main` next to it. This is the **branch** of our repository we are working on and we'll explain more about this in the next sprint. + +You can click on a commit message to display a list of the files it changed underneath. + +### Workflow Summary + +Here's the complete workflow for making commits: + +1. **Modify files** in your editor +2. **Stage changes** in the source control tab +3. **Create commit** with a meaningful message + + + +{{}} +1. Create a new file called `planning.txt` +2. Add some text to it +3. Save it +4. Stage your changes +5. Make a commit with the message `"Add project planning document"` +6. Check the history to see both commits +{{}} + + diff --git a/common-content/en/module/onboarding/git/creating-a-commit/initialise-repo.png b/common-content/en/module/onboarding/git/creating-a-commit/initialise-repo.png new file mode 100644 index 000000000..2353be71a Binary files /dev/null and b/common-content/en/module/onboarding/git/creating-a-commit/initialise-repo.png differ diff --git a/common-content/en/module/onboarding/git/creating-a-commit/new-file-explorer-view.png b/common-content/en/module/onboarding/git/creating-a-commit/new-file-explorer-view.png new file mode 100644 index 000000000..7be832798 Binary files /dev/null and b/common-content/en/module/onboarding/git/creating-a-commit/new-file-explorer-view.png differ diff --git a/common-content/en/module/onboarding/git/creating-a-commit/new-file-source-control-view.png b/common-content/en/module/onboarding/git/creating-a-commit/new-file-source-control-view.png new file mode 100644 index 000000000..da8800465 Binary files /dev/null and b/common-content/en/module/onboarding/git/creating-a-commit/new-file-source-control-view.png differ diff --git a/common-content/en/module/onboarding/git/creating-a-commit/new-repo-view.png b/common-content/en/module/onboarding/git/creating-a-commit/new-repo-view.png new file mode 100644 index 000000000..27e251031 Binary files /dev/null and b/common-content/en/module/onboarding/git/creating-a-commit/new-repo-view.png differ diff --git a/common-content/en/module/onboarding/git/creating-a-commit/staged-change.png b/common-content/en/module/onboarding/git/creating-a-commit/staged-change.png new file mode 100644 index 000000000..b6204a257 Binary files /dev/null and b/common-content/en/module/onboarding/git/creating-a-commit/staged-change.png differ diff --git a/common-content/en/module/onboarding/git/creating-a-commit/staging-highlight.png b/common-content/en/module/onboarding/git/creating-a-commit/staging-highlight.png new file mode 100644 index 000000000..dd92a8111 Binary files /dev/null and b/common-content/en/module/onboarding/git/creating-a-commit/staging-highlight.png differ diff --git a/common-content/en/module/onboarding/git/ignoring-files/index.md b/common-content/en/module/onboarding/git/ignoring-files/index.md new file mode 100644 index 000000000..ebc839ea1 --- /dev/null +++ b/common-content/en/module/onboarding/git/ignoring-files/index.md @@ -0,0 +1,18 @@ ++++ +title = 'Ignoring Files' +time =45 +[objectives] + 1="Create a .gitignore file" +[build] + render = 'never' + list = 'local' + publishResources = false + ++++ + +TODO: + +- Create an additional file in a repo - **do not commit** +- Explain why we may not want to commit it +- Create `.gitignore` +- Use `git status` (or equivalent in VSCode) to show file is being ignored \ No newline at end of file diff --git a/common-content/en/module/onboarding/git/merging/branch-name.png b/common-content/en/module/onboarding/git/merging/branch-name.png new file mode 100644 index 000000000..a04025d3c Binary files /dev/null and b/common-content/en/module/onboarding/git/merging/branch-name.png differ diff --git a/common-content/en/module/onboarding/git/merging/commit-history-branch.png b/common-content/en/module/onboarding/git/merging/commit-history-branch.png new file mode 100644 index 000000000..ca788ff93 Binary files /dev/null and b/common-content/en/module/onboarding/git/merging/commit-history-branch.png differ diff --git a/common-content/en/module/onboarding/git/merging/commits-ahead.png b/common-content/en/module/onboarding/git/merging/commits-ahead.png new file mode 100644 index 000000000..5a5432b91 Binary files /dev/null and b/common-content/en/module/onboarding/git/merging/commits-ahead.png differ diff --git a/common-content/en/module/onboarding/git/merging/github-branches.png b/common-content/en/module/onboarding/git/merging/github-branches.png new file mode 100644 index 000000000..4d032db0b Binary files /dev/null and b/common-content/en/module/onboarding/git/merging/github-branches.png differ diff --git a/common-content/en/module/onboarding/git/merging/index.md b/common-content/en/module/onboarding/git/merging/index.md new file mode 100644 index 000000000..36475b619 --- /dev/null +++ b/common-content/en/module/onboarding/git/merging/index.md @@ -0,0 +1,106 @@ ++++ +title = 'Merging' +time =45 +[objectives] + 1="Push a branch to GitHub" + 2="Create a pull request" + 3="Merge a pull request to `main`" +[build] + render = 'never' + list = 'local' + publishResources = false + ++++ + +If you have successfully created a new branch you will see that it is now displayed instead of `main` in the bottom left of the VSCode window: + +![branch name](branch-name.png) + +It's time to make some changes! + +{{}} +1. Add an `h2` heading to the blog with the title "Tips" +2. Commit your change +3. Add an unordered list with three tips for getting un-stuck. Try Google if you need some ideas! +4. Make another commit with your list + +Remember: This is a markdown file so your heading and list will need to use markdown syntax. [This cheat sheet](https://www.markdownguide.org/cheat-sheet/) will help if you get stuck. +{{}} + +Now we have made changes we can check our Git history and see the commits listed there. Something is different this time, though: + +![history including a branch](commit-history-branch.png) + +The commits we made on the branch are a different colour to those on `main` (your colours may not be the same as mine). This can be really helpful when we are tracking changes through a project. + +We need our work to be on GitHub to share with our colleagues. We can push a branch in the same way as we push to `main` by clicking the "publish branch" button. + +### Branches on GitHub + +When we look at the repository on GitHub we can see something has changed here too. It now says we have two branches and clicking on the branch name opens a drop-down listing all the branches which have been pushed. For now it's just our `update-blog-1` branch. + +![github branch list](github-branches.png) + +Click `update-blog-1` in the list and the UI will update to show our files as they are on the branch. + +{{}} +Use the UI to navigate to the file we just edited. Can you see the changes we made? +{{}} + +We also see a summary of the difference between our branch and `main` at the top of the page: + +![commit difference](commits-ahead.png) + +When we see a message like this saying our branch is "`N` commits ahead" it means there is work on our branch which isn't available on `main`. We need to **merge** our work with the rest of the project. + +### Creating a pull request + +When we merge our work we will combine our commits with those on the branch we are merging to. In this example we will take commits from `update-blog-1` and **merge them onto** `main`. + +GitHub has tools which will help us manage this process. We're going to create a **pull request** and see how it will help us. + +Click the "Pull requests" tab then the green "New pull request" button. The next page will say there is nothing to compare, but that's because by default it won't be looking at our changes. Instead it will try to compare the `main` branch of our fork with the `main` branch of the original repository and neither of them have changed. + +Click the left drop-down and select your fork of the repository. + +![selecting a base repo](pull-request-set-base.png) + +{{}} +You will skip this step when submitting work from your backlog. Unless the instruction say otherwise you will **always** set the base of your pull request to be the CYF repo you created the fork from. + +We are doing things differently here to demonstrate the complete merging process. If everyone tried to merge the same changes to the original repository it would cause problems. +{{}} + +The UI still tells us there are still no changes to compare. Let's fix that by selecting a branch to compare. In the right-hand drop-down select your `update-blog-1` branch and the UI will change: + +![pull request summary](pull-request-summary.png) + +There are a couple of things to note here: + +- GitHub tells us it is **able to merge automatically**. This won't always be the case, but we'll look at how to handle that in a later workshop. +- We can see a list of all the commits we are about to merge +- We see a display of all the changes which will be made to the files. We are only adding content here so everything is highlighted green. If we were deleting lines they would be highlighted in red. + +Click the "create pull request" button to move to the next stage. Here we can give our pull request a title and a description. Every organisation has it's own way of structuring these and CYF is no different. You can find [instructions for how to title a pull request in the guides section](/guides/reviewing/trainee-pr-guide/). + +For now we'll leave the defaults in place since this is just a practice pull request. Click the green button to finish creating it. + +### Merging + +Now we have created a pull request and we're ready to merge our work. In a typical professional workflow you would ask a senior colleague to review your work before merging. We will follow a similar process with the work you submit for CYF: a volunteer will review your pull requests and give you feedback on your code. + +In a future workshop we will spend more time exploring the interface but for now we'll concentrate on the box in the middle of the page: + +![merge confirmation](merge-confirm.png) + +Clicking the green button will open a form asking for a commit message. Typically we can leave this as the default value. When we finalise the merge a new commit will be created on `main`, just like for any other change we make to the code. Click "confirm merge" to complete the process. + +{{}} +The prompt told us there were "no conflicts with the base branch". We won't always be able to merge our work so easily, sometimes another engineer will have made changes to the same files as us. When this happens Git isn't able to figure out which change takes priority and a **merge conflict** occurs. + +You shouldn't come across this while submitting work. If you do post a message on Slack and get help to resolve it. We will look at merge conflicts in detail in a future workshop. +{{}} + +Navigate back to the "code" tab in GitHub and make sure you are viewing the `main` branch. Take a moment to explore the files - our changes are now on `main`! + +Now it's time to put our new skills to work! \ No newline at end of file diff --git a/common-content/en/module/onboarding/git/merging/merge-confirm.png b/common-content/en/module/onboarding/git/merging/merge-confirm.png new file mode 100644 index 000000000..32c3ada71 Binary files /dev/null and b/common-content/en/module/onboarding/git/merging/merge-confirm.png differ diff --git a/common-content/en/module/onboarding/git/merging/pull-request-set-base.png b/common-content/en/module/onboarding/git/merging/pull-request-set-base.png new file mode 100644 index 000000000..8e8457716 Binary files /dev/null and b/common-content/en/module/onboarding/git/merging/pull-request-set-base.png differ diff --git a/common-content/en/module/onboarding/git/merging/pull-request-summary.png b/common-content/en/module/onboarding/git/merging/pull-request-summary.png new file mode 100644 index 000000000..8617039dd Binary files /dev/null and b/common-content/en/module/onboarding/git/merging/pull-request-summary.png differ diff --git a/common-content/en/module/onboarding/git/pushing-and-pulling/index.md b/common-content/en/module/onboarding/git/pushing-and-pulling/index.md new file mode 100644 index 000000000..72f9803ba --- /dev/null +++ b/common-content/en/module/onboarding/git/pushing-and-pulling/index.md @@ -0,0 +1,103 @@ ++++ +title = 'Pushing and Pulling' +time ="30" +objectives = [ + "Link local and remote repositories", + "Upload files to GitHub" +] +hide_from_overview = true +[build] + render = 'never' + list = 'local' + publishResources = false + ++++ + +Now that your local and remote repositories are connected, you need to learn how to synchronize them. **Pushing** sends your local commits to GitHub, and **pulling** gets updates from GitHub. + +### The Git Workflow + +```mermaid +flowchart LR + A(Make changes locally) --> B(Commit changes) + B --> C(Push to GitHub) + C --> D(Your code is now on GitHub) +``` + +### Step 1: Push Your Commits to GitHub + +You have commits on your local machine, but they're not on GitHub yet. Send them using the "Publish Branch" button. + +![publish branch button in VSCode](publish-branch.png) + +This is called **pushing**. We don't need to push every time we commit, but our colleagues won't be able to access it if we don't. + +You might be asked to authenticate. Follow GitHub's instructions. Depending on how you linked the repositories you may be able to authenticate using SSH instead of entering a username and password. + +{{}} +The **Secure Shell Protocol** (SSH) enables encrypted connections between two computers. We recommend taking the time to [configure SSH with GitHub](https://docs.github.com/en/authentication/connecting-to-github-with-ssh) which will avoid the need to keep entering passwords when pushing and pulling. +{{}} + +### Step 2: View Your Code on GitHub + +1. Go to your repository on GitHub (https://github.com/YOUR-USERNAME/my-first-project) +2. You should see your files! +3. Click on a file to view its contents +4. Click the "History" button (clock icon) to see commits + +Congratulations! Your code is now on GitHub and you have a portfolio piece! ๐ŸŽ‰ + +### Step 3: Make Changes and Push Again + +The workflow for subsequent changes is simpler: + +1. Modify a file (e.g., add more text to `notes.txt`) +2. Stage and commit the change +3. Push to GitHub + +That's it! Your changes are now on GitHub. + +{{}} +1. Create a file called `facts.txt` in VSCode +2. Add your favourite fun fact to the file +3. Save the file +4. Commit your changes +5. Add another fact. Commit this change. +6. Push to GitHub +7. Go to GitHub and refresh to see your changes! +{{}} + +### Understanding Push and Pull + +Remember our diagram from the last section + +```mermaid +flowchart LR + A["`Local Repository + (On your computer)`"] --"push"--> B["`Remote Repository + (GitHub)`"] + B--"pull"-->A +``` + +When you **push** a copy of your commits is sent to GitHub. Your colleagues can now access them. Even though you don't need to push after every commit it is still important to do it regularly. + +When you **pull** you get any commits that were sent to GitHub by your teammates. We will look at pulling in more detail in a later section. + +### The Complete Git Journey + +You now know: +- โœ… How to configure Git +- โœ… How to make commits (save versions) +- โœ… How to connect to GitHub (remote) +- โœ… How to push commits to GitHub + +**You're ready to:** +- Build projects and track changes +- Share code with others +- Build a portfolio on GitHub + +### What to Practice + +1. Create 3-5 small projects locally +2. Push each one to GitHub +3. Make changes and push again diff --git a/common-content/en/module/onboarding/git/pushing-and-pulling/publish-branch.png b/common-content/en/module/onboarding/git/pushing-and-pulling/publish-branch.png new file mode 100644 index 000000000..4918f9263 Binary files /dev/null and b/common-content/en/module/onboarding/git/pushing-and-pulling/publish-branch.png differ diff --git a/common-content/en/module/onboarding/git/remote-repositories/add-remote-vscode.png b/common-content/en/module/onboarding/git/remote-repositories/add-remote-vscode.png new file mode 100644 index 000000000..781e7520e Binary files /dev/null and b/common-content/en/module/onboarding/git/remote-repositories/add-remote-vscode.png differ diff --git a/common-content/en/module/onboarding/git/remote-repositories/github-new-repo.png b/common-content/en/module/onboarding/git/remote-repositories/github-new-repo.png new file mode 100644 index 000000000..0646f32df Binary files /dev/null and b/common-content/en/module/onboarding/git/remote-repositories/github-new-repo.png differ diff --git a/common-content/en/module/onboarding/git/remote-repositories/index.md b/common-content/en/module/onboarding/git/remote-repositories/index.md new file mode 100644 index 000000000..23b593d7e --- /dev/null +++ b/common-content/en/module/onboarding/git/remote-repositories/index.md @@ -0,0 +1,95 @@ ++++ +title = 'Remote Repositories' +time ="20" +objectives = [ + "Understand what a remote repository is", + "Create a new repository on GitHub", + "Connect your local repository to GitHub", + "Verify the connection" +] +hide_from_overview = true +[build] + render = 'never' + list = 'local' + publishResources = false + ++++ + +So far, our commits are saved on our computer. A **remote repository** is a copy of our project stored on a server (like GitHub), so others can access it and we have a backup. + +### Why Use Remote Repositories? + +1. **Backup** - Your code is safe on GitHub's servers +2. **Collaboration** - Other developers can access your code +3. **Portfolio** - Employers can see your work on your GitHub profile +4. **Team projects** - Work together on the same codebase + +### Local vs Remote + +```mermaid +flowchart LR + A["`Local Repository + (On your computer)`"] --"push"--> B["`Remote Repository + (GitHub)`"] + B--"pull"-->A +``` + +### Step 1: Create a Repository on GitHub + +1. Go to [https://github.com](https://github.com) +2. Click the **+** icon in the top right +3. Select **"New repository"** +4. Give it a name (e.g., `my-first-project`) +5. Add a description (optional) +6. Choose **"Public"** (so your portfolio is visible) +7. **Don't** initialize with README, .gitignore, or license +8. Click **"Create repository"** + +{{}} +If you initialize with files on GitHub, your local and remote repositories will be different, which causes conflicts. Since we already have commits locally, we'll connect them directly. +{{}} + +### Step 2: Add the Remote Connection + +GitHub will show you a page with instructions. You need to tell your local Git about this remote repository. + +First copy the url to your clipboard. + +![github url for a newly created repo](github-new-repo.png) + +Then go back to VSCode's version control tab, expand the menu next to the repo name and go down to "remotes". Select "Add remote". + +![adding a remote in VSCode](add-remote-vscode.png) + +In the dialogue box which appears paste the url you copied from GitHub. + +![pasting remote url](remote-url.png) + +Finally give the remote a name. For now we will give it the name `origin`. We _could_ name it anything we like, but we will follow convention. + +![naming the remote](naming-remote.png) + +We have now linked our local repository with our GitHub repository! + +#### Understanding "origin" and "main" + +There are two terms we have seen now which are probably unfamiliar. Both are important and we'll learn more about why in the coming weeks. + +- `origin` - The name used to refer to your remote repository (GitHub). +- `main` - The name of your default **branch**. + +{{}} +A branch is like an alternative version of your project. Most projects have a "main" branch (the stable version) and feature branches (experimental versions). For now, you'll only use "main". +{{}} + +{{}} +A remote is a place we can upload our code to. We have already created our `origin` remote but we may also want to create others if we want to share our code somewhere else. For example, if we wanted to host a website on AWS we would need to create a remote there too. +{{}} + +### What's Next? + +Now that your repositories are connected, you're ready to: +- **Push** - Send your local commits to GitHub +- **Pull** - Get updates from GitHub +- **Collaborate** - Work with other developers + diff --git a/common-content/en/module/onboarding/git/remote-repositories/naming-remote.png b/common-content/en/module/onboarding/git/remote-repositories/naming-remote.png new file mode 100644 index 000000000..8d2f11f29 Binary files /dev/null and b/common-content/en/module/onboarding/git/remote-repositories/naming-remote.png differ diff --git a/common-content/en/module/onboarding/git/remote-repositories/remote-url.png b/common-content/en/module/onboarding/git/remote-repositories/remote-url.png new file mode 100644 index 000000000..b2c68c4e0 Binary files /dev/null and b/common-content/en/module/onboarding/git/remote-repositories/remote-url.png differ diff --git a/common-content/en/module/onboarding/git/undoing-a-commit/git-revert-ui.png b/common-content/en/module/onboarding/git/undoing-a-commit/git-revert-ui.png new file mode 100644 index 000000000..7256f711a Binary files /dev/null and b/common-content/en/module/onboarding/git/undoing-a-commit/git-revert-ui.png differ diff --git a/common-content/en/module/onboarding/git/undoing-a-commit/index.md b/common-content/en/module/onboarding/git/undoing-a-commit/index.md new file mode 100644 index 000000000..bd807a3b0 --- /dev/null +++ b/common-content/en/module/onboarding/git/undoing-a-commit/index.md @@ -0,0 +1,50 @@ ++++ +title = 'Undoing a Commit' +time =45 +[objectives] + 1="Undo a commit" +[build] + render = 'never' + list = 'local' + publishResources = false + ++++ + +TODO: + +- Add some extra content to an existing repo (education blog?) +- Revert a commit and examine history +- Reset to a previous commit and examine history + +One of the great things about Git is that it captures the complete history of a project. Because we know exactly what was changed with each commit we are able to deconstruct the changes made to a project and revert it to a previous state. We can jumping back and forth between versions if we need to see what our project looked like before some changes were made. + +We can also _undo_ those changes, acting as if they never actually happened. This is particularly useful in a situation where we accidentally commit something we didn't mean to, which can easily happen! + +### Undoing a commit + +Let's revisit the [educational blog](https://github.com/CodeYourFuture/education-blog) we looked at in Sprint 1. Open the folder in VSCode and take a moment to refamiliarise yourself with the files. + +Let's imagine a world where we're putting this page online using a platform like GitHub Pages. usually we need to include some sort of configuration information when we deploy an application, typically things like GitHub urls to load content from or passwords for third-party services. We're going to add a fake file which will store some credentials for our imaginary deployment. + +Create a file called `passwords.json` at the directory's root and add the following object to it: + +```json {title="passwords.json"} +{ + "db": "storage_is_awesome", + "apiKey": "acbd1234" +} +``` + +We would usually want to make a commit at this point, so switch over to the source control tab and commit this new file. + +We may have just made a mistake though. Things like passwords and API keys are typically personal to a particular user, do we want to share them with the entire team? What if our repository is public, do we want them visible to everyone on the internet? We need to undo this commit before our details get shared! + +There are multiple ways of doing this with Git but not all are supported natively by VSCode's source control tools. In VSCode we can only undo the most recent commit but later we will see how to apply this to any commit. + +Click the dots next to the repo name in the source control tab. From there click `Commit --> Undo Last Commit`. + +![undoing commit UI](git-revert-ui.png) + +After clicking the button you will see the changes made in the commit have been returned to staging. From here you can remove anything that shouldn't be there and commit again, or remove everything. The files themselves and the changes made are unaffected, it is only the commit which is deleted. + +VSCode is fairly limited here - it can only undo the last commit. If another commit has been made since the one we want to undo we have a problem. Git does have functionality which enables us to undo any commit though, which we will look at in a later section. For now let's take a look at a way of avoiding this happening at all. diff --git a/common-content/en/module/onboarding/goals/index.md b/common-content/en/module/onboarding/goals/index.md index 6e2fa6cff..734eb2add 100644 --- a/common-content/en/module/onboarding/goals/index.md +++ b/common-content/en/module/onboarding/goals/index.md @@ -37,16 +37,12 @@ _By the end of this module_ you will have tracked changes to data (your code) ov #### Requirements and Testing -_By the end of this module_ you will have tested your work using acceptance criteria, manual testing, and automated testing. Your goal is to interpret requirements and write code to meet acceptance criteria. +_By the end of this module_ you will have written code to solve specific problems and verified that it does what it is supposed to. Your goal is to interpret requirements and write code to meet acceptance criteria. #### Code review _By the end of this module_ you will have revised, refactored, and reviewed code using code review. Your goal is to form the habits of a professional who can think, talk, and write in a technical context. -#### Data - -_By the end of this module_ you will have manipulated data with HTML, Git, and Google Sheets. Your goal is to begin to understand how data is structured and how to manipulate it. - #### Scientific method _By the end of this module_ you will have written and asked well-structured developer questions. Your goal is to build a strategy to methodically solve problems. diff --git a/common-content/en/module/onboarding/help/index.md b/common-content/en/module/onboarding/help/index.md index 7cc959182..4f86902b6 100644 --- a/common-content/en/module/onboarding/help/index.md +++ b/common-content/en/module/onboarding/help/index.md @@ -35,15 +35,9 @@ We can help you with data access if you need support with it. See our [internet It will always be provided in class. -{{}} - -If you need a computer, you must be enrolled as a trainee before we can help you. - #### ๐Ÿ’ป A computer -The onboarding module can be completed entirely on a library computer. Once you have completed this module and enrolled as a Trainee, we can lend you a laptop if you need. - -{{}} +If you do not have access to a computer, or if you are worried your computer won't be able to run everything needed during the course, we can lend you a laptop. Let us know **as soon as possible** if you need to borrow one. We ask that you complete the onboarding module step before we enrol you as a Trainee. We are obliged to only enrol people we have a reasonable expectation of being able to complete the whole course. But predicting the future is a challenge! We have created this module to try to give as many people as possible a fair chance to show they can do this. diff --git a/common-content/en/module/onboarding/problem-solving/index.md b/common-content/en/module/onboarding/problem-solving/index.md new file mode 100644 index 000000000..a0df5999f --- /dev/null +++ b/common-content/en/module/onboarding/problem-solving/index.md @@ -0,0 +1,16 @@ ++++ +title = 'Breaking Down a Problem' +time =20 +[objectives] + 1="Breakdown a problem into smaller steps" +[build] + render = 'never' + list = 'local' + publishResources = false + ++++ + +TODO: + +- Set up the [workshop](https://curriculum.codeyourfuture.io/itp/structuring-data/sprints/2/day-plan/#problem-solving-workshop) +- Relate to previous page on pseudocode if possible \ No newline at end of file diff --git a/common-content/en/module/onboarding/pseudocode/index.md b/common-content/en/module/onboarding/pseudocode/index.md new file mode 100644 index 000000000..b1d149005 --- /dev/null +++ b/common-content/en/module/onboarding/pseudocode/index.md @@ -0,0 +1,60 @@ ++++ +title = 'Planning a function' +time = 30 +[objectives] + 1="Define 'pseudocode'" + 2="Plan code using pseudocode" +[build] + render = 'never' + list = 'local' + publishResources = false + ++++ + +When we write code we are doing it to solve a problem. Before we start writing it's important to think about the problem in simple terms. For our password checker: + +> Given a password entered by a user, I want to check if it is valid or not + +The password we picked was `secretword123`, so if the user types that we want our program to behave a certain way. If they type anything else then it should do something different. + +### Planning the process + +In the previous section we used the `Math.round` function to round decimals to whole numbers. When we called the function a set of instructions were carried out and we got our result. The value of the result changed when we changed the value of the input. + +The `Math.round` function was provided for us as part of the core JavaScript language. We are able to use it but we didn't have to think about what the instructions were. Checking passwords isn't a core part of JavaScript so we will have to define the instructions ourselves. + +Before we think about how the code should be structured we need to think about the overall process. We think about the input we will receive, what we want to happen and what the output should be using the **Given-When-Then** structure: + +- **Given** an input +- **When** I execute some code +- **Then** this should be the result + +These steps can be as simple or as complex as necessary. In our example: + +> **Given** a password entered by a user +> +> **When** I compare it to the variable containing the correct password +> +> **Then** the program should tell me if the user entered the correct password or not + +### Writing pseudocode + +Once we have defined the criteria for our function we can start thinking about how the code should look. We want to be sure we have a good understanding of what we should be writing before we start, so we will plan our function using **pseudocode**. + +{{}} +When we write pseudocode we follow the same structure as the code would (eg. correct indentation) but we write in a way that is closer to natural language. We can still use keywords such as `if` and `else` to show which structures we need but we use plain English as much as possible. +{{}} + +We'll also need to create a new file to work in. We'll call it `passwordCheckerFunction.js`. + +We're going to use comments to describe what each section of code should do. As we write the function we'll leave the comments in place to act as a guide then delete them when we're finished. We don't need to be too specific with coding terms here, we want to concentrate on the process. + +```js {title="passwordCheckerFunction.js"} +// Already have the password stored in a variable +// Receive the value which the user entered +// Compare the two values +// If they match print "Correct password entered" +// If they don't match print "Incorrect password, please try again" +``` + +Now we have a plan, let's look at how we define our new function. \ No newline at end of file diff --git a/common-content/en/module/onboarding/throwing-errors/index.md b/common-content/en/module/onboarding/throwing-errors/index.md new file mode 100644 index 000000000..a434ed5c2 --- /dev/null +++ b/common-content/en/module/onboarding/throwing-errors/index.md @@ -0,0 +1,18 @@ ++++ +title = 'Throwing Errors' +time =45 +[objectives] + 1="Throw an error if something isn't right when code runs" +[build] + render = 'never' + list = 'local' + publishResources = false + ++++ + +TODO: + +- Discuss good vs bad ways for something to fail +- Construct a function to validate an input, eg. `checkOverMinCharacterLength(stringToCheck)` +- Have it throw an error if condition not satisfied +- Example of using `catch` to handle the error? \ No newline at end of file diff --git a/org-cyf/content/itp/onboarding/sprints/1/prep/index.md b/org-cyf/content/itp/onboarding/sprints/1/prep/index.md index fe2633f02..eecef6f17 100644 --- a/org-cyf/content/itp/onboarding/sprints/1/prep/index.md +++ b/org-cyf/content/itp/onboarding/sprints/1/prep/index.md @@ -7,45 +7,6 @@ weight = 1 name="Do the prep" src="module/onboarding/do-the-prep" [[blocks]] -name="GitHub Dot Dev" -src="module/induction/dot-dev" -[[blocks]] -name="Install VS Code" -src="module/induction/install-vscode" -time=10 -[[blocks]] -name="Check Git" -src="module/induction/check-git-installation" -time=5 -[[blocks]] -name="Create CYF Folder" -src="module/induction/cyf-folder" -time=5 -[[blocks]] -name="Fork your Planner" -src="https://www.youtube.com/watch?v=cnx0RuAu2tc" -time=5 -[[blocks]] -name="Make your Planning Board" -src="https://www.youtube.com/watch?v=Hbtfil-G0h0" -time=15 -[[blocks]] -name="Set up Planner" -src="https://github.com/CodeYourFuture/Coursework-Planner/tree/main" -time=30 -[[blocks]] -name="CYF Blog" -src="module/induction/cyf-blog" -[[blocks]] -name="Development Process" -src="module/induction/development-process" -[[blocks]] -name="Version Control" -src="module/induction/version-control" -[[blocks]] -name="Sharing History" -src="module/induction/sharing-history" -[[blocks]] name="Explore" src="module/induction/checkout-a-commit" [[blocks]] @@ -64,15 +25,29 @@ src="module/induction/viewing-files" name="Branching" src="module/induction/branching" [[blocks]] -name="Wrapping up Git" -src="module/induction/wrapping-up" +name="Merging" +src="module/onboarding/git/merging" +[[blocks]] +name="Fork your Planner" +src="https://www.youtube.com/watch?v=cnx0RuAu2tc" +time=5 +[[blocks]] +name="Make your Planning Board" +src="https://www.youtube.com/watch?v=Hbtfil-G0h0" time=15 [[blocks]] +name="Set up Planner" +src="https://github.com/CodeYourFuture/Coursework-Planner/tree/main" +time=30 +[[blocks]] name="Forms in 25 minutes" title="Form building" src="https://www.youtube.com/watch?v=fNcJuPIZ2WE" time=25 [[blocks]] +name="What are Forms" +src="module/html-css/what-are-forms" +[[blocks]] name="Backlog" src="blocks/backlog" +++ diff --git a/org-cyf/content/itp/onboarding/sprints/2/prep/index.md b/org-cyf/content/itp/onboarding/sprints/2/prep/index.md index 9b2df8e65..4625f8038 100644 --- a/org-cyf/content/itp/onboarding/sprints/2/prep/index.md +++ b/org-cyf/content/itp/onboarding/sprints/2/prep/index.md @@ -7,15 +7,53 @@ weight = 1 name="Spaced Repetition" src="blocks/spaced-repetition" [[blocks]] -name="What are Forms" -src="module/html-css/what-are-forms" +name="Install a unix based os" +src="module/js1/check-unix-os" [[blocks]] -name="Google Sheets Query Function Explained" -src="https://www.youtube.com/watch?v=oCKvAcXTLZo" -time=20 +name="Install Node" +src="module/js1/install-node" [[blocks]] -name="Databases with Google Sheets" -src="module/databases/databases-with-sheets" +name="Define a computer" +src="module/js1/define-computer" +[[blocks]] +name="Interface" +src="module/js1/interface" +[[blocks]] +name="Terminal" +src="module/js1/terminal" +[[blocks]] +name="Prep Directory" +src="blocks/prep-dir" +[[blocks]] +name="Scripts" +src="module/js1/scripts" +[[blocks]] +name="Data" +src="module/js1/data" +[[blocks]] +name="Variables" +src="module/js1/variables" +[[blocks]] +src="module/js1/comparison" +name="Comparison" +[[blocks]] +src="module/js1/strategy" +name="Strategy" +[[blocks]] +src="module/js1/conditionality" +name="Conditionality" +[[blocks]] +name="Errors" +src="module/js1/errors" +[[blocks]] +src="module/js1/interpreting-errors" +name="Interpreting errors" +[[blocks]] +src="module/js1/interpreting-this-error" +name="Interpreting this error" +[[blocks]] +src="module/js1/fixing-the-error" +name="Fixing the error" [[blocks]] name="Backlog" src="blocks/backlog" diff --git a/org-cyf/content/itp/onboarding/sprints/3/prep/index.md b/org-cyf/content/itp/onboarding/sprints/3/prep/index.md index b3ce79c1e..eefe7bf35 100644 --- a/org-cyf/content/itp/onboarding/sprints/3/prep/index.md +++ b/org-cyf/content/itp/onboarding/sprints/3/prep/index.md @@ -8,14 +8,51 @@ name="Enroll as a Trainee" src="https://github.com/CodeYourFuture/Module-Onboarding/issues/72" time=30 [[blocks]] -name="Record a Goose" -title="Accessibility audit" -src="https://github.com/CodeYourFuture/Project-Record-A-Goose/" -time=180 -[[blocks]] name="Learn about Interview Introductions" src="module/induction/interview-introductions" [[blocks]] +name="Functions" +src="module/js1/functions" +[[blocks]] +name="Planning a function" +src="module/onboarding/pseudocode" +[[blocks]] +name="Defining functions" +src="module/js1/declaring-functions" +# [[blocks]] +# name="Playing computer" +# src="module/js1/playing-computer" +[[blocks]] +name="Scope" +src="module/js1/scope" +[[blocks]] +name="Return" +src="module/js1/return" +# [[blocks]] +# name="Reuse" +# src="module/js1/reuse" +[[blocks]] +name="Parameters" +src="module/js1/parameters" +# [[blocks]] +# name="Solving problems with functions ๐Ÿ“ผ" +# src="module/js1/functions-workshop" +[[blocks]] +name="Refactoring" +src="module/js1/refactoring" +[[blocks]] +name="Throwing Errors" +src="module/onboarding/throwing-errors" +[[blocks]] +name="Breaking Down Problems" +src="module/onboarding/problem-solving" +[[blocks]] +name="Undoing a Commit" +src="module/onboarding/git/undoing-a-commit" +[[blocks]] +name="Ignoring Files" +src="module/onboarding/git/ignoring-files" +[[blocks]] name="Backlog" src="blocks/backlog" +++ diff --git a/org-cyf/content/itp/structuring-data/prerequisites/index.md b/org-cyf/content/itp/structuring-data/prerequisites/index.md deleted file mode 100644 index 622fb2bbf..000000000 --- a/org-cyf/content/itp/structuring-data/prerequisites/index.md +++ /dev/null @@ -1,13 +0,0 @@ -+++ -title = 'Pre-Reqs' -description = 'Things you must set up to get started' -layout = 'prep' -menu_level = ['module'] -weight = 1 -[[blocks]] -name="Install a unix based os" -src="module/js1/check-unix-os" -[[blocks]] -name="Install Node" -src="module/js1/install-node" -+++ diff --git a/org-cyf/content/itp/structuring-data/sprints/1/_index.md b/org-cyf/content/itp/structuring-data/sprints/1/_index.md index cd4327ae6..60fee00d9 100644 --- a/org-cyf/content/itp/structuring-data/sprints/1/_index.md +++ b/org-cyf/content/itp/structuring-data/sprints/1/_index.md @@ -3,6 +3,6 @@ title = 'Sprint 1' description = 'The plan for this sprint' layout = 'sprint' menu_level = ['module'] -weight = 2 +weight = 1 theme = "Programming fundamentals" +++ diff --git a/org-cyf/content/itp/structuring-data/sprints/1/prep/index.md b/org-cyf/content/itp/structuring-data/sprints/1/prep/index.md index c909103ab..eaeea4588 100644 --- a/org-cyf/content/itp/structuring-data/sprints/1/prep/index.md +++ b/org-cyf/content/itp/structuring-data/sprints/1/prep/index.md @@ -5,18 +5,6 @@ layout = 'prep' menu_level = ['sprint'] weight = 1 [[blocks]] -name="Define a computer" -src="module/js1/define-computer" -[[blocks]] -name="Interface" -src="module/js1/interface" -[[blocks]] -name="Terminal" -src="module/js1/terminal" -[[blocks]] -name="Data" -src="module/js1/data" -[[blocks]] name="REPL" src="module/js1/repl" [[blocks]] diff --git a/org-cyf/content/itp/structuring-data/sprints/2/_index.md b/org-cyf/content/itp/structuring-data/sprints/2/_index.md index 4c250b5ad..97c5203e0 100644 --- a/org-cyf/content/itp/structuring-data/sprints/2/_index.md +++ b/org-cyf/content/itp/structuring-data/sprints/2/_index.md @@ -3,6 +3,6 @@ title = 'Sprint 2' description = 'The plan for this sprint' layout = 'sprint' menu_level = ['module'] -weight = 3 +weight = 2 theme = "Comparisons, assertions, and breaking down problems" +++ diff --git a/org-cyf/content/itp/structuring-data/sprints/2/prep/index.md b/org-cyf/content/itp/structuring-data/sprints/2/prep/index.md index 7be767d1c..cf49c0ad2 100644 --- a/org-cyf/content/itp/structuring-data/sprints/2/prep/index.md +++ b/org-cyf/content/itp/structuring-data/sprints/2/prep/index.md @@ -13,21 +13,6 @@ name="Comparison" src="module/js1/assertions" name="Assertions" [[blocks]] -src="module/js1/interpreting-errors" -name="Interpreting errors" -[[blocks]] -src="module/js1/interpreting-this-error" -name="Interpreting this error" -[[blocks]] -src="module/js1/reusing-variable-names" -name="Reusing variable names" -[[blocks]] -src="module/js1/strategy" -name="Strategy" -[[blocks]] -src="module/js1/conditionality" -name="Conditionality" -[[blocks]] src="module/js1/sub-goal" name="Sub-goal" [[blocks]] diff --git a/org-cyf/content/itp/structuring-data/sprints/3/_index.md b/org-cyf/content/itp/structuring-data/sprints/3/_index.md index 309ab50bd..ac74cc086 100644 --- a/org-cyf/content/itp/structuring-data/sprints/3/_index.md +++ b/org-cyf/content/itp/structuring-data/sprints/3/_index.md @@ -3,6 +3,6 @@ title = 'Sprint 3' description = 'The plan for this sprint' layout = 'sprint' menu_level = ['module'] -weight = 4 +weight = 3 theme = "Test cases with Jest" +++ diff --git a/org-cyf/content/itp/welcome/backlog/creating-a-commit/index.md b/org-cyf/content/itp/welcome/backlog/creating-a-commit/index.md new file mode 100644 index 000000000..a79ac9802 --- /dev/null +++ b/org-cyf/content/itp/welcome/backlog/creating-a-commit/index.md @@ -0,0 +1,187 @@ ++++ +title = "Creating a Commit" +time = 25 +[tasks] +1 = "Initialize a new Git repository" +2 = "Create and modify files in your repository" +3 = "Stage changes for commit" +4 = "Create your first commit" +5 = "View your commit history" +[build] + render = 'never' + list = 'local' + publishResources = false ++++ + +A **commit** is a saved version of your project at a particular moment in time. Think of it like saving a document, but with a detailed message explaining what changed and why. + +## Understanding the Three States + +Git has three states for your files: + +1. **Modified** - You changed the file, but haven't saved the version yet +2. **Staged** - You've marked the file as ready to be saved +3. **Committed** - The file is now saved in Git history + +``` +Working Directory โ†’ Staging Area โ†’ Git Repository + (Modified) (Staged) (Committed) +``` + +## Step 1: Create a New Repository + +A repository is a folder where Git tracks all your files and their changes. + +1. Create a new folder for your project: + ``` + mkdir my-first-project + cd my-first-project + ``` + +2. Initialize Git in this folder: + ``` + git init + ``` + +You should see: "Initialized empty Git repository" + +{{}} +1. Open your terminal +2. Navigate to your Documents or Desktop folder +3. Run the commands above +4. You've created your first Git repository! ๐ŸŽ‰ +{{}} + +## Step 2: Create a File and Make Changes + +Let's create a simple text file: + +1. In VSCode, create a new file called `notes.txt` +2. Add some text: + ``` + My First Git Project + + Today I'm learning Git! + This is my first commit. + ``` +3. Save the file + +## Step 3: Check the Status of Your Repository + +Before making a commit, let's see what Git sees: + +``` +git status +``` + +You should see output like: +``` +On branch main + +No commits yet + +Untracked files: + (use "git add ..." to include in what will be committed) + notes.txt + +nothing added to commit but untracked files present +``` + +Git is saying: "I see a file called `notes.txt`, but you haven't told me to track it yet." + +## Step 4: Stage Your Changes + +Now we tell Git we want to save this file. This is called **staging**: + +``` +git add notes.txt +``` + +You can also stage all files at once: +``` +git add . +``` + +Check the status again: +``` +git status +``` + +Now you should see: +``` +Changes to be committed: + (use "git rm --cached ..." to unstage) + new file: notes.txt +``` + +Git is saying: "I'm ready to save this file. Are you sure?" + +## Step 5: Create Your First Commit + +Now we actually save the version: + +``` +git commit -m "Add initial project notes" +``` + +The `-m` flag means "message". The message describes what you changed. + +{{}} +Write messages that explain **what** you changed and **why**: +- โœ… Good: "Add login button to homepage" +- โœ… Good: "Fix bug where users can't save files" +- โŒ Avoid: "stuff", "changes", "update" + +Keep messages short but clear (under 50 characters is ideal). +{{}} + +## Step 6: View Your Commit History + +See all the commits in your repository: + +``` +git log +``` + +You should see your commit with: +- Your name and email +- The date and time +- Your commit message + +Press `q` to exit the log. + +## Workflow Summary + +Here's the complete workflow for making commits: + +1. **Modify files** in your editor +2. **Check status**: `git status` +3. **Stage changes**: `git add .` +4. **Create commit**: `git commit -m "Your message"` +5. **View history**: `git log` + +{{}} +1. Create a new file called `planning.txt` +2. Add some text to it +3. Save it +4. Run: `git add planning.txt` +5. Run: `git commit -m "Add project planning document"` +6. Run: `git log` to see both commits +{{}} + +## Common Commands + +| Command | What it does | +|---------|------------| +| `git status` | Shows which files have changed | +| `git add ` | Stages a specific file | +| `git add .` | Stages all changed files | +| `git commit -m "message"` | Creates a commit with a message | +| `git log` | Shows all commits in order | +| `git diff` | Shows exactly what changed in files | + +## Further Reading + +- [Atlassian - Git Commit](https://www.atlassian.com/git/tutorials/saving-changes/git-commit) +- [GitHub Docs - Recording Changes](https://docs.github.com/en/get-started/using-git/about-git) +``` \ No newline at end of file diff --git a/org-cyf/content/itp/welcome/backlog/index.md b/org-cyf/content/itp/welcome/backlog/index.md index cb46b25b9..aaf8dd5b0 100644 --- a/org-cyf/content/itp/welcome/backlog/index.md +++ b/org-cyf/content/itp/welcome/backlog/index.md @@ -6,4 +6,4 @@ menu_level = ["module"] weight = 2 backlog = "Module-Welcome" backlog_filter = "๐Ÿ“… Sprint 1" -+++ ++++ \ No newline at end of file diff --git a/org-cyf/content/itp/welcome/backlog/pushing-and-pulling/index.md b/org-cyf/content/itp/welcome/backlog/pushing-and-pulling/index.md new file mode 100644 index 000000000..5a5919662 --- /dev/null +++ b/org-cyf/content/itp/welcome/backlog/pushing-and-pulling/index.md @@ -0,0 +1,186 @@ ++++ +title = "Pushing & Pulling" +time = 25 +[tasks] +1 = "Push your commits to GitHub" +2 = "View your commits on GitHub" +3 = "Make changes and push again" +4 = "Understand pull and push workflow" +[build] + render = 'never' + list = 'local' + publishResources = false ++++ + +Now that your local and remote repositories are connected, you need to learn how to synchronize them. **Pushing** sends your local commits to GitHub, and **pulling** gets updates from GitHub. + +## The Git Workflow + +``` +1. Make changes locally + โ†“ +2. Commit changes + โ†“ +3. Push to GitHub + โ†“ +4. Your code is now on GitHub! +``` + +## Step 1: Push Your Commits to GitHub + +You have commits on your local machine, but they're not on GitHub yet. Let's send them: + +``` +git push -u origin main +``` + +What does this mean? +- `git push` - Send commits to a remote +- `-u` - Set up tracking (remember this remote/branch combo) +- `origin` - Push to the remote named "origin" (GitHub) +- `main` - Push to the "main" branch + +You might be asked to authenticate. Follow GitHub's instructions. + +{{}} +The `-u` flag is only needed the first time. After that, you can just type: `git push` +{{}} + +## Step 2: View Your Code on GitHub + +1. Go to your repository on GitHub (https://github.com/YOUR-USERNAME/my-first-project) +2. You should see your files! +3. Click on a file to view its contents +4. Click the "History" button (clock icon) to see commits + +Congratulations! Your code is now on GitHub and you have a portfolio piece! ๐ŸŽ‰ + +## Step 3: Make Changes and Push Again + +The workflow for subsequent changes is simpler: + +1. Modify a file (e.g., add more text to `notes.txt`) +2. Commit the change: + ``` + git add notes.txt + git commit -m "Update project notes" + ``` +3. Push to GitHub: + ``` + git push + ``` + +That's it! Your changes are now on GitHub. + +{{}} +1. Open `planning.txt` in VSCode +2. Add more content to it +3. Save the file +4. Run: `git add planning.txt` +5. Run: `git commit -m "Expand project planning"` +6. Run: `git push` +7. Go to GitHub and refresh to see your changes! +{{}} + +## Understanding Push and Pull + +### Push (Send to GitHub) + +``` +Your Computer (local) GitHub (remote) + Commits โ”€โ”€pushโ”€โ”€โ†’ Commits + (backup) +``` + +When you push, GitHub gets a copy of your commits. + +### Pull (Get from GitHub) + +``` +Your Computer (local) GitHub (remote) + Commits โ†โ”€pullโ”€โ”€โ”€โ”€ Commits + (updates) +``` + +When you pull, you get any commits that were made on GitHub (or by teammates). + +{{}} +In a team project, other developers might push commits to GitHub. You need to pull regularly to keep your local copy up to date. +{{}} + +## Complete Workflow Example + +Here's a day in the life of a developer: + +``` +Morning: +1. git pull (get latest from team) + +During the day (multiple times): +2. Make changes +3. git add . +4. git commit -m "description" +5. git push (share with team) + +Before leaving: +6. git push (make sure everything is saved) +``` + +## Troubleshooting + +**"Nothing to push"** +You have no new commits. This is fine! It means your local and remote are in sync. + +**"Rejected"** +This usually means someone else pushed changes. Run `git pull` first, then `git push`. + +**"Permission denied"** +Check that you're logged into the right GitHub account. + +## Common Commands + +| Command | What it does | +|---------|------------| +| `git push` | Send commits to GitHub | +| `git pull` | Get commits from GitHub | +| `git status` | Check if local and remote are in sync | +| `git log` | See all commits | +| `git fetch` | Check for updates without merging | + +## The Complete Git Journey + +You now know: +- โœ… How to configure Git +- โœ… How to make commits (save versions) +- โœ… How to connect to GitHub (remote) +- โœ… How to push commits to GitHub +- โœ… How to pull updates from GitHub + +**You're ready to:** +- Build projects and track changes +- Share code with others +- Build a portfolio on GitHub +- Work in teams + +## Common Mistakes to Avoid + +1. **Forgetting to push** - Your commits are local only, not on GitHub +2. **Forgetting to commit** - You made changes but didn't save the version +3. **Wrong branch** - Always check you're on "main" with `git branch` +4. **Large files** - Don't commit videos, databases, or node_modules +5. **Secrets** - Never commit passwords or API keys + +## What to Practice + +1. Create 3-5 small projects locally +2. Push each one to GitHub +3. Make changes and push again +4. Get comfortable with the push/pull workflow + +## Further Reading + +- [Atlassian - Git Push](https://www.atlassian.com/git/tutorials/syncing/git-push) +- [Atlassian - Git Pull](https://www.atlassian.com/git/tutorials/syncing/git-pull) +- [GitHub Docs - Pushing Commits](https://docs.github.com/en/get-started/using-git/pushing-commits-to-a-remote-repository) +- [GitHub Docs - Pulling Changes](https://docs.github.com/en/get-started/using-git/getting-changes-from-a-remote-repository) +``` \ No newline at end of file diff --git a/org-cyf/content/itp/welcome/backlog/remote-repositories/index.md b/org-cyf/content/itp/welcome/backlog/remote-repositories/index.md new file mode 100644 index 000000000..e108be663 --- /dev/null +++ b/org-cyf/content/itp/welcome/backlog/remote-repositories/index.md @@ -0,0 +1,135 @@ ++++ +title = "Remote Repositories" +time = 20 +[tasks] +1 = "Understand what a remote repository is" +2 = "Create a new repository on GitHub" +3 = "Connect your local repository to GitHub" +4 = "Verify the connection" +[build] + render = 'never' + list = 'local' + publishResources = false ++++ + +So far, your commits are saved on your computer. A **remote repository** is a copy of your project stored on a server (like GitHub), so others can access it and you have a backup. + +## Why Use Remote Repositories? + +1. **Backup** - Your code is safe on GitHub's servers +2. **Collaboration** - Other developers can access your code +3. **Portfolio** - Employers can see your work on your GitHub profile +4. **Team projects** - Work together on the same codebase + +## Local vs Remote + +``` +Your Computer GitHub Server +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ Local Repository โ”‚ โ”‚ Remote Repository โ”‚ +โ”‚ (your commits) โ”‚ โ† โ”‚ (backup) โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ†’ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + "pull" "push" +``` + +## Step 1: Create a Repository on GitHub + +1. Go to [https://github.com](https://github.com) +2. Click the **+** icon in the top right +3. Select **"New repository"** +4. Give it a name (e.g., `my-first-project`) +5. Add a description (optional) +6. Choose **"Public"** (so your portfolio is visible) +7. **Don't** initialize with README, .gitignore, or license +8. Click **"Create repository"** + +{{}} +If you initialize with files on GitHub, your local and remote repositories will be different, which causes conflicts. Since we already have commits locally, we'll connect them directly. +{{}} + +## Step 2: Add the Remote Connection + +GitHub will show you a page with instructions. You need to tell your local Git about this remote repository. + +In your terminal, run: + +``` +git remote add origin https://github.com/YOUR-USERNAME/my-first-project.git +``` + +Replace `YOUR-USERNAME` with your GitHub username and `my-first-project` with your repository name. + +**What does this do?** +- `git remote add` - Add a new remote +- `origin` - The name of the remote (default name) +- The URL - Where the remote repository lives + +## Step 3: Verify the Connection + +Check that the connection was made: + +``` +git remote -v +``` + +You should see: +``` +origin https://github.com/YOUR-USERNAME/my-first-project.git (fetch) +origin https://github.com/YOUR-USERNAME/my-first-project.git (push) +``` + +This means your local repository knows how to reach GitHub! + +## Step 4: Set Your Default Branch + +By default, Git uses "main" as the primary branch. Let's set this: + +``` +git branch -M main +``` + +## Understanding "origin" and "main" + +- **origin** - The name of your remote repository (GitHub) +- **main** - The name of your default branch (like the main storyline of your project) + +Think of it like: +- You have a story (your project) +- It lives in two places: Your notebook (local) and a backup server (origin/main) + +{{}} +A branch is like an alternative version of your project. Most projects have a "main" branch (the stable version) and feature branches (experimental versions). For now, you'll only use "main". +{{}} + +## Checking Your Remote + +If you ever want to see details about your remote: + +``` +git remote show origin +``` + +## What's Next? + +Now that your repositories are connected, you're ready to: +- **Push** - Send your local commits to GitHub +- **Pull** - Get updates from GitHub +- **Collaborate** - Work with other developers + +You'll learn these in the next module! + +## Common Commands + +| Command | What it does | +|---------|------------| +| `git remote add origin ` | Connect local repo to GitHub | +| `git remote -v` | Show all remote connections | +| `git remote show origin` | Show details about origin | +| `git branch -M main` | Set main as default branch | + +## Further Reading + +- [GitHub Docs - Adding a Repository](https://docs.github.com/en/migrations/importing-your-projects-to-github/importing-a-repository-with-github-importer) +- [Atlassian - Git Remote](https://www.atlassian.com/git/tutorials/syncing) +- [GitHub Docs - Managing Remote Repositories](https://docs.github.com/en/get-started/getting-started-with-git/managing-remote-repositories) +``` \ No newline at end of file diff --git a/org-cyf/content/itp/welcome/prep/index.md b/org-cyf/content/itp/welcome/prep/index.md index 5d7501df8..eb58491ab 100644 --- a/org-cyf/content/itp/welcome/prep/index.md +++ b/org-cyf/content/itp/welcome/prep/index.md @@ -32,4 +32,35 @@ src="module/induction/accounts" [[blocks]] name="House Rules" src="blocks/house-rules" +[[blocks]] +name="Create CYF Folder" +src="module/induction/cyf-folder" +[[blocks]] +name="Check Git Installation" +src="module/induction/check-git-installation" +time=5 +[[blocks]] +name="CYF Blog" +src="module/induction/cyf-blog" +[[blocks]] +name="Development Process" +src="module/induction/development-process" +[[blocks]] +name="Version Control" +src="module/induction/version-control" +[[blocks]] +name="Sharing History" +src="module/induction/sharing-history" +[[blocks]] +name="Configuring Git with VSCode" +src="module/onboarding/git/configuring-git-vscode" +[[blocks]] +name="Creating a Commit" +src="module/onboarding/git/creating-a-commit" +[[blocks]] +name="Remote Repositories" +src="module/onboarding/git/remote-repositories" +[[blocks]] +name="Pushing & Pulling" +src="module/onboarding/git/pushing-and-pulling" +++