diff --git a/.markdownlint.json b/.markdownlint.json deleted file mode 100644 index 9cdf4265..00000000 --- a/.markdownlint.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "markdownlint/style/prettier", - "ignore": "node_modules/" -} diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 00000000..647ea922 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,8 @@ +--- +$schema: https://raw.githubusercontent.com/DavidAnson/markdownlint/v0.37.4/schema/markdownlint-config-schema.json +extends: markdownlint/style/prettier +MD046: + style: fenced +MD033: + allowed_elements: + - nobr diff --git a/legacy/README.md b/legacy/README.md new file mode 100644 index 00000000..89abd97c --- /dev/null +++ b/legacy/README.md @@ -0,0 +1,28 @@ +# The legacy course + +(i.e. as it was at the start of 2025) + +## References + +- [Curriculum](https://github.com/HackYourFuture-CPH/curriculum/tree/77c128f9c45ad6cb49fedcd29c86ed13787e333a) +- plus the 'ref' links in the tables below + +## Before the course + +TODO, find the info about the stuff that happens _before_ the course, and add it here. + +## The course + +| Name | Reference | Weeks | +| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ----- | +| [HTML & CSS](./html-and-css/) | [ref](https://github.com/HackYourFuture-CPH/HTML-CSS/tree/5217f5807129ec894aa43e04d1f7dd5465966de2) | 1 | +| [Git (part 1)](./git/git1/) | [ref](https://github.com/HackYourFuture-CPH/Git/tree/b5499a64a7957e614ed92ab4545d6fd80ddd030c/Git1) | 1 | +| [JavaScript (in 3 parts)](./javascript/) | [ref](https://github.com/HackYourFuture-CPH/JavaScript/tree/675adba05e23ccf1b52d653e03f7d9b1f11c4e09) | 10 | +| [Databases](./databases/) | [ref](https://github.com/HackYourFuture-CPH/databases/tree/171a567db330f704d1f40ce35516cc41a84d1cdf) | 3 | +| [NodeJS](./nodejs/) | [ref](https://github.com/HackYourFuture-CPH/node.js/tree/063085194a02eb1610b614d7be20372b4797001b) | 3 | +| [React (in 2 parts)](./react/) | [ref](https://github.com/HackYourFuture-CPH/React/tree/0bdef59114ba678adf3b10ddedcb74f4f4b04781) | 6 | +| [Git (part 2)](./git/git2/) | [ref](https://github.com/HackYourFuture-CPH/Git/tree/b5499a64a7957e614ed92ab4545d6fd80ddd030c/Git2) | 1 | +| [Career training](./career-training/) | [ref](https://github.com/HackYourFuture-CPH/career-training/tree/0050e4be53cfb06cad2cbd764ef41385a5141f51) | 3 | +| [Final project](./final-project/) | [ref](https://github.com/HackYourFuture-CPH/finalproject/tree/5a9b0fee893816e9c994771e3146760f0f70b726) | 4–5 | + +Total weeks: 32–33 diff --git a/legacy/career-training/README.md b/legacy/career-training/README.md new file mode 100644 index 00000000..42eedc56 --- /dev/null +++ b/legacy/career-training/README.md @@ -0,0 +1,25 @@ +# JOB HUB - Career Training resources + +## Introduction + +This repository collects all the info and material used to support you & the community at large in finding a job in IT. The goal of this series of sessions is to optimally prepare you for the job hunt in Denmark's IT industry following your graduation from our bootcamp. + +## Contents + +| Week | Topic | Preparation | Learning Goals | Homework | +| ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | -------------------------------------- | -------------------------------- | +| 1. | **Danish job market, job search & general info**. Initial session where we introduce general info about the job market & prepare you for the job search. | [Preparation](./week-1/preparation.md) | [Lesson Plan](./week-1/lesson-plan.md) | [Homework](./week-1/homework.md) | +| 2. | **The Jobseeker Toolkit**. This session is used to provide each student with feedback on their CV, Linkedin page & GitHub page. | [Preparation](./week-2/preparation.md) | [Lesson Plan](./week-2/lesson-plan.md) | [Homework](./week-2/homework.md) | +| 3. | **Technical Mock Interview**. This session is for practicing technical interviews and receiving feedback from peers and technical volunteers. | [Preparation](./week-3/preparation.md) | [Lesson Plan](./week-3/lesson-plan.md) | [Homework](./week-3/homework.md) | + +## Learning Goals + +- Understand where to look for suitable jobs and internships. +- Understand what you should do in order to be an attractive candidate on the job market. +- Understand what HYF can do to support you on your job hunt. +- Know how to assemble an effective CV. +- Know how to write an effective Cover Letter. +- Know how to make your Linkedin page attractive to recruiters. +- Know how to make your GitHub page attractive to recruiters. +- Learn how to perform well in a technical interview. +- πŸš‘ How to handle Job Rejection and Job Anxiety diff --git a/legacy/career-training/week-1/README.md b/legacy/career-training/week-1/README.md new file mode 100644 index 00000000..939cf28f --- /dev/null +++ b/legacy/career-training/week-1/README.md @@ -0,0 +1,16 @@ +# Career Training - Week 1 + +The goal of this session is to prepare you for searching jobs in an effective manner, as well as making you understand what you need to do in order to get noticed by recruiters or be selected for interviews. We will also cover what kind of help HYF can provide, and what kind of help we cannot provide. + +## Materials + +- [Preparation](./preparation.md) +- [Lesson Plan](./lesson-plan.md) +- [Homework](./homework.md) + +## Learning goals + +- General info about the Danish Job Market +- What can HYF do for me? +- What do I need to do? +- How can I leverage my network? diff --git a/legacy/career-training/week-1/homework.md b/legacy/career-training/week-1/homework.md new file mode 100644 index 00000000..a815526a --- /dev/null +++ b/legacy/career-training/week-1/homework.md @@ -0,0 +1,46 @@ +# Homework Week 1 + +These articles, videos and tasks are not a suggestion, but **mandatory**. They require less time than your regular homeworks, but are just as important. We expect you to use the remainder of your 30 hours on finishing all the homework assignments you haven't yet completed. + +## Read + +- [How to write a short BIO text](https://business.tutsplus.com/tutorials/how-to-write-a-short-bio--cms-30643) + +## Watch + +- [How to polish your Linkedin & GitHub](https://www.youtube.com/watch?v=c_bPIFiWUpI) (50mins) + +## Do + +- Add your current email address, Linkedin profile and GitHub profile to your Slack profile +- Read the [CV Guide by HYF](https://github.com/HackYourFuture-CPH/yourpersonalbrand/blob/main/yourcurriculum.md) (20mins) +- Make a copy of, and fill your CV data into [HYF CV TEMPLATES](https://docs.google.com/presentation/d/1hcKvyIOLnXtDXqEu554_xaC7EzuRAPNTqYbIDMAvoQA/copy) (❗️ mandatory to use the HYF templates! We will _not_ review other formats.) +- Write a short BIO text about yourself - about 500-600 characters and add it to your CV +- Create a [CodeWars](https://www.codewars.com/) profile and complete [this list of katas](https://www.codewars.com/collections/hyf-js) +- Add the Codewars profile to your GitHub profile page in this format: ![Codewars](https://www.codewars.com/users/Sana-Shabeel/badges/micro) +- :octocat: Polish your GitHub - [good example](https://github.com/danJecu) | [example 2](https://github.com/Sana-Shabeel) +- :large_blue_diamond: Polish your Linkedin - [good example](https://www.linkedin.com/in/alex-sudar/) | [example 2](https://www.linkedin.com/in/remyamm/) | [example 3](https://www.linkedin.com/in/saloumehsarabi/) +- Take the personality test: ["The Four Tendencies" test](https://gretchenrubin.com/four-tendencies/) +- Take the personality test: ["The Saboteur Assessment" test](https://assessment.positiveintelligence.com/saboteur/overview) + +## Github homework + +Separate some of the homework projects and apps into their own repositories. Perform this as a combination of copy/pasting from your HW repo and git commands - so you practise handling git too. You will need to look into `git clone`, `git remote add` and some other commands. +Each should have a comprehensive title and a nice short description. As a minimum, you should have separate repositories for these: + +- Spirit Animal name generator +- hyfBay shop +- The movies filtering (add a simple UI at some point) +- Fastest Presser +- Weather App +- Giphy Search +- Git Search +- To Do app + +### How to submit the homework + +Please send the following to the Team Responsible on Slack: + +- The result of your two personality tests +- A link to your GitHub page +- A link to your CV with sharing rights set to "edit" diff --git a/legacy/career-training/week-1/lesson-plan.md b/legacy/career-training/week-1/lesson-plan.md new file mode 100644 index 00000000..54ed94b9 --- /dev/null +++ b/legacy/career-training/week-1/lesson-plan.md @@ -0,0 +1,12 @@ +# Job Hunting Info + +This session focuses on how to effectively search for tech jobs in Denmark. + +## Learning Goals + +- Understand how the Danish job market works +- Know where to look for jobs +- Know how to best prepare for the job hunt +- Be able to optimally use HYF and its network to your advantage + +> **Note for Lead Teacher** An extensive slideshow exists for this session [see example](https://docs.google.com/presentation/d/1dfqgw4TaDgQ4Z19EBryDU4lrkn5hPi9lF4Z00-f3_9g/edit?usp=drive_link). Ask the HYF to get access to a copy, if you don't have access yet. diff --git a/legacy/career-training/week-1/preparation.md b/legacy/career-training/week-1/preparation.md new file mode 100644 index 00000000..a632d26f --- /dev/null +++ b/legacy/career-training/week-1/preparation.md @@ -0,0 +1,12 @@ +# Preparation + +## Do + +- Fill out the **"Career Status" survey** posted in your class' Slack channel. + +## Read + +- Read about what [a Union is in Denmark](https://www.workindenmark.dk/working-in-denmark/terms-of-employment/trade-unions) +- Read about what an [A-Kasse](https://www.workindenmark.dk/working-in-denmark/terms-of-employment/unemployment-insurance) is (unemployment insurance in Denmark) +- Read about how [Pension works in Denmark](https://www.workindenmark.dk/working-in-denmark/terms-of-employment/pension) +- Read about what to expect from a [Employment contract in Denmark](https://www.workindenmark.dk/working-in-denmark/terms-of-employment/employment-contract) diff --git a/legacy/career-training/week-2/README.md b/legacy/career-training/week-2/README.md new file mode 100644 index 00000000..16250b51 --- /dev/null +++ b/legacy/career-training/week-2/README.md @@ -0,0 +1,16 @@ +# Career Training - Week 2 + +The goal of this session is to give every student feedback on their CV, Linkedin profiles and GitHub pages ("the Jobseeker Toolkit") in order to make them most attractive to recruiters. We will also cover the differences between what Startups, Medium-sized companies and larger Corporations look for in their screening processes, so you can best adapt your "Jobseeker Toolkit" to fit these individual preferences. + +## Materials + +- [Preparation](./preparation.md) +- [Lesson Plan](./lesson-plan.md) +- [Homework](./homework.md) + +## Learning goals + +- What does a standard recruitment process look like? +- How do CV, Linkedin & GitHub play together? +- How do recruiters look at it? What do they look for? +- Reviewing CV’s, Linkedin’s & GitHub pages in groups diff --git a/legacy/career-training/week-2/homework.md b/legacy/career-training/week-2/homework.md new file mode 100644 index 00000000..ba0e18d9 --- /dev/null +++ b/legacy/career-training/week-2/homework.md @@ -0,0 +1,31 @@ +# Homework Week 2 + +## Read + +- Read the [GitHub Guide by HYF](https://github.com/HackYourFuture-CPH/yourpersonalbrand/blob/main/yourgithub.md) +- Read the [Linkedin Guide by HYF](https://github.com/HackYourFuture-CPH/yourpersonalbrand/blob/main/yourlinkedin.md) +- [Freecodecamp React Interview Questions](https://www.freecodecamp.org/news/react-interview-questions-to-know/) +- Start taking a look at the [Week 3 Preparation materials](https://github.com/HackYourFuture-CPH/career-training/blob/main/week-3/preparation.md) + +## Do + +- Add a small [Frontendmentor.io](https://www.frontendmentor.io/) project to your GitHub profile: You can choose between [this](https://www.frontendmentor.io/challenges/advice-generator-app-QdUG-13db) or [this](https://www.frontendmentor.io/challenges/interactive-pricing-component-t0m8PIyY8). (but you can also do both - good practice πŸ™ƒ) +- Create an account on **Hackerrank** and take the [React Basics certifcation](https://www.hackerrank.com/skills-verification/react_basic) +- Add the certificate on Linkedin ;) +- Update the readme.md file of your **Mealsharing app**. Here's a good [example](https://github.com/DanJecu/meal-sharing-app) +- Be aware that your Mealsharing App must be deployed & working. This is a requirement to join the Final Project. + +- ⚠️ On the **Thursday** after this class you will also receive another assignment, which will be used for the **Technical Mock Interview** session ([Career Training Week 3](../week-3/README.md). The challenge will be posted in your Slack channel. ⚠️ + +## Optional + +We recommend looking through this YouTube channel of Eddie Jaoude. he has great advice on how to improve your GitHub profile. +[Start here, for example](https://www.youtube.com/watch?v=pSBs9sWw1Vk) + +### How to submit the homework + +Please send the following to the Team Responsible on Slack: + +- Add your Hackerrank certification on Linkedin. +- Send a link to your chosen Frontendmentor project repo +- Send a link to your Mealsharing App repo diff --git a/legacy/career-training/week-2/lesson-plan.md b/legacy/career-training/week-2/lesson-plan.md new file mode 100644 index 00000000..cee13082 --- /dev/null +++ b/legacy/career-training/week-2/lesson-plan.md @@ -0,0 +1,85 @@ +# Lesson plan + +## Session contents + +Based on previous iterations, we address a standard hiring process and look under the hood of a hiring process at a larger company. From there, we extrapolate to medium-sized and small companies and how their hiring processes might differ. In the second part of the session we focus on giving feedback on the trainees' CV, Linkedin & GitHub pages in small groups. + +> **Note for Lead Teacher** An extensive slideshow exists for this session [in this folder](https://drive.google.com/drive/folders/1pshCqFdkk2TI1R8Fz9WsQNP5qO6JXiu6?usp=drive_link). Ask the HYF to get access to a copy, if you don't have access yet. + +### The Corporate Hiring Process + +The corporate screening & hiring process (perfect world scenario) explained with the concrete example of a large Danish tech employer in Copenhagen. + +#### Hitting the apply button + +What happens at the hiring company after you hit "apply" on an a job ad? + +1. First 2 weeks - roughly 30-40 applications get looked at +2. Should I use "easy apply" on Linkedin? +3. Apply early! Managers are eager BUT expectations are high initially +4. (Seldom perfect matches exist) - revisions & compromises keep happening in the following weeks +5. Applicant Tracking Systems. ATS exist, but all applications are screened by a recruiter +6. It's an ongoing process + +#### First Interview + +Recruiter or Hiring Manager schedules or calls the candidate. +2 main things are screened for: relevant experience, salary, motivation. + +1. For HYF - why are you in DK? Long or short term? +2. Language (English or Danish too poor) +3. Big misalignment +4. 80% likelihood to proceed +5. Ability to learn fast +6. How to prepare: think of examples of this! +7. Personal story & family background +8. e.g. Pregnancy - if it shows, ideally mention it. (for startups this can be a bigger concern) + +#### Second Interview + +If the Hiring Manager is happy, there will be a technical assignment + +1. Can be a take home assignment, or standardized as Codinggame, Hackerrank or Coderbyte. +2. Do it as soon as you can (but familiarise yourself with the platform) +3. References! Know HYF mentors or alumni in the company? Mention them! +4. Evaluated by Hiring Manager & a Senior/ PO. +5. They deselect the less good candidates +6. Ask for feedback! + +#### Third Interview + +Interview about working preferences with team members + +1. Based on Personality type tests & working preference +2. No rejection is about you, but about a fit for the specific team +3. "What do you need to focus at work?" +4. Feedback preferences +5. Be honest + +#### Contract offer or rejection + +1. How to handle rejection +2. Use it as a learning process +3. Ask for honest feedback to improve + +#### What general tips for CV's are there? + +1. Must include Linkedin/GitHub +2. Must fit with CV/ consistent +3. chronological backwards +4. Picture = yes? +5. ChatGPT? Template resumΓ©s +6. Relevant experience first +7. Most recent experiences first +8. Use the top 1/3 of the CV & BIO text +9. No experience over 10yrs ago +10. 1-2 pages + +##### What is your most sought-after thing on any CV? + +1. Always looking at the Linkedin profile to get a full picture of the applicant's network & career +2. Portfolio websites & special projects can leave an impression + +#### The feedback in practice + +#### How to handle ongoing rejections? diff --git a/legacy/career-training/week-2/novoresume-interview.pdf b/legacy/career-training/week-2/novoresume-interview.pdf new file mode 100644 index 00000000..c66afb1e Binary files /dev/null and b/legacy/career-training/week-2/novoresume-interview.pdf differ diff --git a/legacy/career-training/week-2/preparation.md b/legacy/career-training/week-2/preparation.md new file mode 100644 index 00000000..ed0a40de --- /dev/null +++ b/legacy/career-training/week-2/preparation.md @@ -0,0 +1,15 @@ +# Preparation + +## Read + +- [How to write a short BIO text](https://business.tutsplus.com/tutorials/how-to-write-a-short-bio--cms-30643) + +## Watch + +- [How to polish your Linkedin & GitHub](https://www.youtube.com/watch?v=c_bPIFiWUpI) (50mins) + +## Do + +- Start working on your job application (the one you chose during the Sunday Session). Tailor your CV to this specific position. +- Write a motivation letter +- Adjust your CV so it highlights the most relevant experiences diff --git a/legacy/career-training/week-3/README.md b/legacy/career-training/week-3/README.md new file mode 100644 index 00000000..d98d742b --- /dev/null +++ b/legacy/career-training/week-3/README.md @@ -0,0 +1,18 @@ +# Career Training - Week 3 + +## Mock Technical Interviews + +This session is for practicing technical interviews and receiving feedback from peers and technical volunteers. + +### Materials + +- [Preparation](./preparation.md) +- [Lesson Plan](./lesson-plan.md) +- [Homework](./homework.md) + +### Learning goals + +- How to talk about a technical assignment during an interview +- How to prepare for a technical interview +- How to make a good first impression +- Gathering confidence for the first real-world technical interview diff --git a/legacy/career-training/week-3/homework.md b/legacy/career-training/week-3/homework.md new file mode 100644 index 00000000..f31c98d0 --- /dev/null +++ b/legacy/career-training/week-3/homework.md @@ -0,0 +1,21 @@ +# Homework Week 3 + +Now it's time to prepare for the Final Project πŸ” + +❗**Having your mealsharing app deployed & working is mandatory to join the Final Project.** ❗️ + +You should also do two more projects for your GitHub page and then it's time to get serious about your first, big collaborative project. + +## Do + +- Got to [Loom.com](https://www.loom.com/) and download the app or plugin. +- Using Loom, record a **short video** of yourself demo'ing your Mealsharing app. +- Update the readme.md file of your **Mealsharing app**. Here's a good [example](https://github.com/DanJecu/meal-sharing-app) +- Embed your Loom video in the Readme. +- Advanced project from Frontend Mentor: You can choose between: [this](https://www.frontendmentor.io/challenges/rest-countries-api-with-color-theme-switcher-5cacc469fec04111f7b848ca) and [this](https://www.frontendmentor.io/challenges/multistep-form-YVAnSdqQBJ) (try building it in React) +- In the coming days more info about the Final Project will be posted in your team channel :) + +## How to submit homework + +- Send a link to your Loom video to **Team Responsible** (via Slack) +- Send the link to your MealSharing App repo to **Team Responsible** (via Slack) diff --git a/legacy/career-training/week-3/lesson-plan.md b/legacy/career-training/week-3/lesson-plan.md new file mode 100644 index 00000000..b0034581 --- /dev/null +++ b/legacy/career-training/week-3/lesson-plan.md @@ -0,0 +1,33 @@ +# Lesson Plan + +## Interview + +- The host (usually a mentor) will explain the process and set the agenda for the in-person meeting or call +- The first interview will start with a small introduction round just like a real interview +- The interviewee will be asked to give a short demo of their submitted work +- The interviewers will start asking questions (both general questions and specific questions to the work) +- The interviewers should write down the feedback and share the feedback at the end +- At last, the interviewee will be asked how this process went, what their input could be +- If it’s not the last participant, the interviewee will now switch to the interviewer role and continue the process + +## General question catalog for the interviewers + +- What was the most difficult part of the challenge? + - talk about the problem and how you overcame the problem +- What was your proudest implementation? +- What have you learned in this challenge? +- Why did you use the tools you chose for the challenge? +- Which part did you spend the most time on and why? +- What surprised you the most when you were doing the challenge? +- If you have more time, which part would you improve and why? +- In your past developer experience, what is the achievement that you are most proud of? What did you do? +- What are the most important qualities to be an excellent developer, in your opinion? +- What do you want to improve the most? + +## General question catalog for interviewees + +- What is the tech stack of your company? +- What do the internal processes at your company look like? (workflow, growth, onboarding plan) +- What is the team composition? (the team you are interviewing for) +- What is the most important trait of the position? +- Questions that matter to you (depends on your personal circumstances, maybe you would like to work remotely, maybe you would like to have a mentor, etc) diff --git a/legacy/career-training/week-3/preparation.md b/legacy/career-training/week-3/preparation.md new file mode 100644 index 00000000..94dc6acb --- /dev/null +++ b/legacy/career-training/week-3/preparation.md @@ -0,0 +1,26 @@ +# Preparation + +## Week 3 + +In order to prepare for your Technical Mock-Interview, please take a look at the following resources. + +### Read + +- What is the ["STAR" answer format](https://www.amazon.jobs/en/landing_pages/in-person-interview)? +- Check out the [Developer Interview Training by Google](https://grow.google/certificates/interview-warmup/) +- If you haven't yet.. read the [Freecodecamp React Interview Questions](https://www.freecodecamp.org/news/react-interview-questions-to-know/) +- Check out the [NovoresumΓ©](https://novoresume.com/) book about the Interview process [here](./novoresume-interview.pdf) + +### General question catalog for interviewees + +- What is the tech stack of your company? +- What do the internal processes at your company look like? (workflow, growth plan, onboarding plan) +- What is the team composition? (the team you are interviewing for) +- What is the most important trait of the position? +- Questions that matter to you (depends on your personal circumstances, maybe you would like to work remotely, maybe you would like to have a mentor, etc) + +### Questions you can ask at the end of the interview + +- Based on our discussion, what value do you feel I could bring to the team? +- Are there any gaps in my experience that you are concerned about? +- What are the next steps and when should I be expecting to hear from you? diff --git a/legacy/databases/README.md b/legacy/databases/README.md new file mode 100644 index 00000000..3227f83a --- /dev/null +++ b/legacy/databases/README.md @@ -0,0 +1,39 @@ +# Databases + +## Relational and Non-Relational Data and Database Systems + +### About + +This three-week program aims to introduce the fundamental concepts of data entities and data storage. + +### Key Objectives + +By the end of this module, students should have a familiarity with and basic understanding of the following: + +- Entities +- The relational model +- The Structured Query Language (SQL) +- The construction of a database system +- MySQL as an example of a relational database system +- Non-relational data and NoSQL +- MongoDB as an example of a NoSQL database + +## Lesson Plan + +### [Lesson 1](lesson1/): Retrieving Data + +In this class, students will be introduced to retrieving data from a MySQL database using SELECT queries. + +Objective: Students should be able to retrieve data from a database table using SELECT statements that include WHERE, GROUP BY, ORDER BY, LIMIT, and JOIN. + +### [Lesson 2](lesson2/): Data Models, Relationships, and Schemas + +In this class, the students will learn how to use more complex SQL queries to retrieve information across tables, and interact with data including write operations. + +Objective: the students should be able to build CRUD functionality using SQL statements, including INSERT INTO, UPDATE and DELETE. The students should also be able to create an entity relationship diagram based on a qualitative description of data requirements, and translate that into a MySQL database schema. + +### [Lesson 3](lesson3/): Security and Non-Relational Databases + +In the final week, the students will be introduced to SQL injection and how to use MySQL permissions to avoid it. MongoDB, as an example of a non-relational database, will also be introduced, as well as the benefits and drawbacks of relational and non-relational models. + +Objective: the students should know how SQL injection happens, and how to define user permissions in MySQL to avoid part of it. The students should also be able to compare and contrast relational (like MySQL) and NoSQL databases (considering their benefits and drawbacks). diff --git a/legacy/databases/lesson1/README.md b/legacy/databases/lesson1/README.md new file mode 100644 index 00000000..5be8e7aa --- /dev/null +++ b/legacy/databases/lesson1/README.md @@ -0,0 +1,84 @@ +# Lesson 1: Retrieving Data + +In this class, students will be introduced to relational data terminology (row, column), the function of a primary key, and retrieving data from a MySQL database using SELECT queries. + +Objective: Students should be able to retrieve data from a database table using SELECT statements that include WHERE, GROUP BY, and ORDER BY. + +## Pre-Class Preparation + +Before the class you should Docker and MySQL VScode plugin on your computer. + +### Installing Docker and the MySQL VScode plugin + +- Install docker by following the instructions here: +- Install the MySQL VSCode plugin by following the instructions here: + +### To learn what Docker is, you can read these articles + +- +- + +Docker is widely used by software developers these days, i’d say it’s been a +game changer, so it’s good for you if you at least know what it is :slightly_smiling_face: + +## Main Topics + +- The relational model of data +- A 'database' vs. a 'DBMS' (database management system) +- The concept of a schema +- The properties of an 'entity' (or 'row') +- Basic entity relationship diagrams +- A basic SELECT statement +- Constructing more complex SELECT statements +- Pattern matching with LIKE +- Limiting and ordering results with LIMIT and ORDER BY +- Grouping results with GROUP BY +- Aggregate functions like AVG, COUNT, SUM, MIN and MAX +- JOIN + - Selecting composite data from multiple tables + - Compare JOIN WHERE with cartesian product +- Naming Conventions: UpperCamelCase/PascalCase, lowerCamelCase, snake_case, hnHungarianNotation/HNHungarianNotation +- Character Sets in Databases (hint: always use UTF-8 encoding, called 'utf8mb4' in MySQL) + +## Reference Material + +- [TutorialsPoint MySQL Introduction](http://www.tutorialspoint.com/mysql/mysql-introduction.htm) +- [w3schools tutorial (easy to find how specific commands work)](https://www.w3schools.com/sql/default.asp) +- [Official MySQL Documentation](https://dev.mysql.com/doc/refman/8.0/en/) +- [Official MySQL Tutorial (pretty dense)](https://dev.mysql.com/doc/refman/8.0/en/tutorial.html) +- [Joel Spolsky - Character Sets and Unicode](https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/) + +## Homework + +### Start the homework + +Need to brush up on the homework setup process? Check [this](https://github.com/HackYourFuture-CPH/Git/blob/main/homework-submission.md) out before you get into some git confusion! + +### The task + +Design queries that retrieve the following data sets. Compare with classmates to see if your answers are correct. + +1. Find out how many tasks are in the task table +2. Find out how many tasks in the task table do not have a valid due date +3. Find all the tasks that are marked as done +4. Find all the tasks that are not marked as done +5. Get all the tasks, sorted with the most recently created first +6. Get the single most recently created task +7. Get the title and due date of all tasks where the title or description contains **database** +8. Get the title and status (as text) of all tasks +9. Get the name of each status, along with a count of how many tasks have that status +10. Get the names of all statuses, sorted by the status with most tasks first + +Watch the previous session recorded on video here: + +Part 1 : + +Part 2 : + +Part 3 : + +### Hand in homework + +Need to brush up on the homework hand-in process? + +Check [this resource](https://github.com/HackYourFuture-CPH/Git/blob/main/homework-submission.md) to remember how to hand in the homework correctly! diff --git a/legacy/databases/lesson1/SQL Joins.pdf b/legacy/databases/lesson1/SQL Joins.pdf new file mode 100644 index 00000000..4671ee99 Binary files /dev/null and b/legacy/databases/lesson1/SQL Joins.pdf differ diff --git a/legacy/databases/lesson1/SQL-Joins.md b/legacy/databases/lesson1/SQL-Joins.md new file mode 100644 index 00000000..0838592d --- /dev/null +++ b/legacy/databases/lesson1/SQL-Joins.md @@ -0,0 +1,192 @@ +# SQL Joins + +> An SQL JOIN clause is used to combine rows from two or more tables, +> based on a common field between them. + +There are different types of joins available in SQL: + +**INNER JOIN**: returns rows when there is a match in both tables. + +**LEFT JOIN**: returns all rows from the left table, even if there are no matches in the right table. + +**RIGHT JOIN**: returns all rows from the right table, even if there are no matches in the left table. + +**FULL JOIN**: It combines the results of both left and right outer joins. + +The joined table will contain all records from both the tables and fill in NULLs for missing matches on either side. + +**SELF JOIN**: is used to join a table to itself as if the table were two tables, temporarily renaming at least one table in the SQL statement. + +**CARTESIAN JOIN**: returns the Cartesian product of the sets of records from the two or more joined tables. + +WE can take each first four joins in Details : + +## Our example data + +We have two tables with the following values. + +`TableA`: + +```text + id firstName lastName + ....................................... + 1 arun prasanth + 2 ann antony + 3 sruthy abc + 6 new abc +``` + +`TableB`: + +```text + id2 age Place + ................ + 1 24 kerala + 2 24 usa + 3 25 ekm + 5 24 chennai +``` + +## Details + +### INNER JOIN + +**Note** :it gives the intersection of the two tables, i.e. rows they have common in TableA and TableB + +Syntax + +```sql + SELECT table1.column1, table2.column2... + FROM table1 + INNER JOIN table2 + ON table1.common_field = table2.common_field; +``` + +Apply it in our sample table : + +```sql + SELECT TableA.firstName,TableA.lastName,TableB.age,TableB.Place + FROM TableA + INNER JOIN TableB + ON TableA.id = TableB.id2; +``` + +Result Will Be + +```text + firstName lastName age Place + .............................................. + arun prasanth 24 kerala + ann antony 24 usa + sruthy abc 25 ekm +``` + +### LEFT JOIN + +**Note** : will give all selected rows in TableA, plus any common selected rows in TableB. + +Syntax + +```sql + SELECT table1.column1, table2.column2... + FROM table1 + LEFT JOIN table2 + ON table1.common_field = table2.common_field; +``` + +Apply it in our sample table : + +```sql + SELECT TableA.firstName,TableA.lastName,TableB.age,TableB.Place + FROM TableA + LEFT JOIN TableB + ON TableA.id = TableB.id2; +``` + +Result + +```text + firstName lastName age Place + ............................................................................... + arun prasanth 24 kerala + ann antony 24 usa + sruthy abc 25 ekm + new abc NULL NULL +``` + +### RIGHT JOIN + +**Note** : will give all selected rows in TableB, plus any common selected rows in TableA. + +Syntax + +```sql + SELECT table1.column1, table2.column2... + FROM table1 + RIGHT JOIN table2 + ON table1.common_field = table2.common_field; +``` + +Apply it in our sample table : + +```sql + SELECT TableA.firstName,TableA.lastName,TableB.age,TableB.Place + FROM TableA + RIGHT JOIN TableB + ON TableA.id = TableB.id2; +``` + +Result + +```text + firstName lastName age Place + ............................................................................... + arun prasanth 24 kerala + ann antony 24 usa + sruthy abc 25 ekm + NULL NULL 24 chennai +``` + +### FULL JOIN + +**Note** :It will return all selected values from both tables. + +Syntax + +```sql + SELECT table1.column1, table2.column2... + FROM table1 + FULL JOIN table2 + ON table1.common_field = table2.common_field; +``` + +Apply it in our sample table : + +```sql + SELECT TableA.firstName,TableA.lastName,TableB.age,TableB.Place + FROM TableA + FULL JOIN TableB + ON TableA.id = TableB.id2; +``` + +Result + +```text + firstName lastName age Place + ............................................................................... + arun prasanth 24 kerala + ann antony 24 usa + sruthy abc 25 ekm + new abc NULL NULL + NULL NULL 24 chennai +``` + +## Interesting Fact + +For INNER joins the order doesn't matter + +For (LEFT, RIGHT or FULL) OUTER joins,the order matter + +Better to go check this **[Link][1]** it will give you interesting details about join order + +[1]: https://stackoverflow.com/questions/9614922/does-the-join-order-matter-in-sql diff --git a/legacy/databases/lesson1/class_exercises.md b/legacy/databases/lesson1/class_exercises.md new file mode 100644 index 00000000..6e9b1895 --- /dev/null +++ b/legacy/databases/lesson1/class_exercises.md @@ -0,0 +1,15 @@ +# Class exercises + +Implement the following queries: + +1. Select the names and phones of all users; +2. Select the name of the user with `id=10`; +3. Find how many users exist in the database; +4. Select the names of the first 5 users in the database; +5. Select the names of the last 3 users in the database; +6. Sum all the ids in the `user` table; +7. Select all users and order them alphabetically by name; +8. Find all tasks that include `SQL` either on the title or on the description; +9. Find the title of all tasks that the user `Maryrose` is responsible for; +10. Find how many tasks each user is responsible for; +11. Find how many tasks with a `status=Done` each user is responsible for; diff --git a/legacy/databases/lesson1/hyf_db_eer_diagram.png b/legacy/databases/lesson1/hyf_db_eer_diagram.png new file mode 100644 index 00000000..d509d105 Binary files /dev/null and b/legacy/databases/lesson1/hyf_db_eer_diagram.png differ diff --git a/legacy/databases/lesson1/lesson-data.sql b/legacy/databases/lesson1/lesson-data.sql new file mode 100644 index 00000000..68c3d164 --- /dev/null +++ b/legacy/databases/lesson1/lesson-data.sql @@ -0,0 +1,90 @@ +SET NAMES utf8mb4; + +CREATE TABLE `user` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `phone` varchar(255) NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `status` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `task` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `title` varchar(255) NOT NULL, + `description` text NULL DEFAULT NULL, + `created` DATETIME NOT NULL, + `updated` DATETIME NOT NULL, + `due_date` DATETIME NULL DEFAULT NULL, + `status_id` int(10) unsigned NOT NULL, + `user_id` int(10) unsigned, + PRIMARY KEY (`id`), + CONSTRAINT `fk_status` FOREIGN KEY (`status_id`) REFERENCES `status` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + + + +-- Users +insert into user (id, name, email, phone) values (1, 'Aarika Ellingworth', 'aellingworth0@harvard.edu', '483-396-8795'); +insert into user (id, name, email, phone) values (2, 'Pren Goldsworthy', 'pgoldsworthy1@spotify.com', '635-572-8467'); +insert into user (id, name, email, phone) values (3, 'Pablo Kisbee', 'pkisbee2@lulu.com', '790-962-8683'); +insert into user (id, name, email, phone) values (4, 'Rodie Duncan', 'rduncan3@quantcast.com', '646-743-6191'); +insert into user (id, name, email, phone) values (5, 'Aubry Polak', 'apolak4@indiatimes.com', '302-678-7931'); +insert into user (id, name, email, phone) values (6, 'Maryrose Meadows', 'mmeadows5@comcast.net', '251-524-6594'); +insert into user (id, name, email, phone) values (7, 'Pavel Brushneen', 'pbrushneen6@techcrunch.com', '316-170-3640'); +insert into user (id, name, email, phone) values (8, 'Hedy Gerault', 'hgerault7@nymag.com', '176-177-5579'); +insert into user (id, name, email, phone) values (9, 'ηŽ‹η§€θ‹±', 'wang.xiuying@weebly.com', '891-952-6749'); +insert into user (id, name, email, phone) values (10, 'Ψ₯Ω„ΩŠΨ§Ψ³', 'elias@github.com', '202-517-6983'); +insert into user (id, name, email, phone) values (11, 'Donald Duck', 'donald@duck.com', NULL); +insert into user (id, name, email, phone) values (12, 'Adam Smith', 'smith@bla.com', NULL); + +-- Statuses +insert into status (id, name) values (1, 'Not started'); +insert into status (id, name) values (2, 'In progress'); +insert into status (id, name) values (3, 'Done'); + + +-- Tasks +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (1, 'Wash clothes', 'Title says it all.', '2017-10-25 06:54:16', '2017-10-15 13:05:09', null, 2, 1); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (2, 'Become a billionaire', 'This should not take long, just invent a time machine, travel back to 2010 and buy bitcoin', '2017-09-26 03:06:46', '2017-10-08 06:14:31', '2017-12-22 20:58:03', 3, 6); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (3, 'Plan meeting with London office', 'We will probably use skype', '2017-10-04 18:07:37', '2017-10-14 16:01:31', '2017-12-05 19:42:15', 2, 8); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (4, 'Order groceries online', 'The fridge is almost empty, we need eggs and milk', '2017-09-20 19:34:43', '2017-10-15 23:35:45', '2017-12-24 16:00:46', 1, 1); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (5, 'Empty the mailbox', NULL, '2017-09-27 15:17:08', '2017-10-08 17:31:16', null, 2, 9); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (6, 'Fix the flat tire on the bike', 'Tools are in the garage', '2017-09-13 23:16:30', '2017-10-06 04:03:52', '2017-12-07 11:51:11', 2, 6); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (7, 'Wash the car', NULL, '2017-10-06 19:39:16', '2017-10-03 04:49:05', '2017-12-04 17:43:16', 2, 10); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (8, 'Walk the dog', NULL, '2017-09-03 02:47:17', '2017-10-12 18:40:08', null, 3, 2); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (9, 'Write a book', 'Maybe something about dragons?', '2017-10-11 06:14:01', '2017-10-17 12:19:08', '2017-12-21 20:18:05', 2, 6); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (10, 'Do HackYourFuture homework', NULL, '2017-10-04 13:55:16', '2017-10-10 00:18:05', '2017-12-19 17:01:10', 1, 3); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (11, 'Iron shirts', NULL, '2017-09-23 03:59:58', '2017-10-19 08:30:48', '2017-12-08 11:00:35', 3, 9); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (12, 'Water the potted plants', 'Maybe they need fertilizer as well', '2017-09-29 23:38:42', '2017-10-08 04:24:53', null, 2, 1); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (13, 'Buy wine for the birthday party', 'Both red and white wine', '2017-10-10 14:57:22', '2017-10-14 14:03:30', '2017-12-10 23:43:56', 2, 5); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (14, 'Buy gift for Paul', 'He could use a shirt or a tie and some socks', '2017-09-09 05:22:08', '2017-10-17 15:58:05', '2017-12-04 20:45:18', 3, 3); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (15, 'Change lightbulb in hallway', 'Should be an LED bulb', '2017-10-01 19:07:35', '2017-10-03 10:02:27', '2017-12-08 17:09:03', 3, 10); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (16, 'Wash windows', NULL, '2017-10-02 22:15:17', '2017-10-07 22:31:35', '2017-12-06 03:36:09', 2, 8); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (17, 'Setup salary databases for accounting', 'Use MySQL', '2017-10-25 05:35:33', '2017-10-10 23:22:33', '2017-12-05 00:19:08', 1, 9); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (18, 'Learn how databases work', NULL, '2017-09-06 03:16:47', '2017-10-10 16:56:58', '2017-12-18 05:08:05', 3, 5); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (19, 'Make the databases perform better', 'It should be possible to optimize the indexes', '2017-10-03 09:27:20', '2017-10-01 16:27:46', '2017-12-01 13:28:35', 2, 4); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (20, 'Buy beer for the company party', '2 or 3 cases should be enough', '2017-10-08 01:39:02', '2017-10-13 23:07:41', null, 3, 4); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (21, 'Knit sweater', NULL, '2017-09-22 17:14:55', '2017-10-08 09:01:35', '2017-12-15 20:33:57', 2, 9); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (22, 'Charge electric bicycle', 'It sucks to ride it without a battery!', '2017-10-10 12:25:07', '2017-10-07 21:45:01', '2017-12-10 19:02:17', 1, 7); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (23, 'Buy new phone', 'The battery in the current one only lasts 5 hours 😞', '2017-09-17 00:25:34', '2017-10-09 11:48:12', null, 3, NULL); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (24, 'Ride bike aroud SjΓ¦lland', 'Remember rainclothes and tire repair kit!', '2017-10-20 19:21:13', '2017-10-07 01:38:06', '2017-12-19 15:08:18', 2, 7); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (25, 'Look at apartments in Ørestad', '2 or 3 rooms', '2017-10-30 09:47:00', '2017-10-19 06:11:26', null, 1, 6); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (26, 'Empty Mr Fluffys litterbox', NULL, '2017-09-28 03:09:06', '2017-10-13 10:38:34', '2017-12-20 23:37:18', 2, 8); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (27, 'Buy new dining room table and chairs', 'Ikea has some on sale', '2017-09-21 12:02:34', '2017-10-02 02:05:11', '2017-12-06 00:14:30', 1, 3); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (28, 'Renew buscard', '3 zones', '2017-10-07 22:47:51', '2017-10-09 15:50:03', '2017-12-01 14:25:40', 2, 6); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (29, 'Sign up for linkedin', 'Make the CV awesome! πŸ˜„', '2017-09-04 00:57:47', '2017-10-18 18:07:48', '2017-12-07 23:04:38', 3, 2); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (30, 'Remove facebook from phone', 'To avoid interruptions when working', '2017-10-26 17:15:07', '2017-10-13 03:36:47', '2017-12-19 11:10:02', 3, 4); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (31, 'Backup databases to external disk', 'Remember to store the disk in another physical location', '2017-09-09 17:32:33', '2017-10-01 21:18:59', '2017-12-23 14:21:01', 1, 2); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (32, 'Put up the new lamp in the hallway', NULL, '2017-10-15 05:45:54', '2017-10-16 14:05:35', '2017-12-29 02:29:26', 3, 3); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (33, 'Hang up paintings in living room', NULL, '2017-09-10 05:36:11', '2017-10-09 17:40:42', null, 3, 4); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (34, 'Buy plane ticket to Auckland', 'Check prices online first!', '2017-09-05 09:07:22', '2017-10-15 09:36:06', '2017-12-07 11:10:05', 1, 9); +insert into task (id, title, description, created, updated, due_date, status_id, user_id) values (35, 'Learn about NoSQL databases', 'MongoDB, CouchDB, etc.', '2017-10-20 01:41:53', '2017-10-04 07:19:56', '2017-12-23 10:13:42', 2, NULL); + + diff --git a/legacy/databases/lesson1/preparation_flipped_classroom.md b/legacy/databases/lesson1/preparation_flipped_classroom.md new file mode 100644 index 00000000..18faf581 --- /dev/null +++ b/legacy/databases/lesson1/preparation_flipped_classroom.md @@ -0,0 +1,38 @@ +# Preparation for (semi) flipped classroom + +This is the preparation for the (semi) flipped classroom (vs. "old style" presential classes). + +We say (semi) flipped classroom, because part of the teaching is still done on the Sunday class. + +## Setting up MySQL and MySQL Workench + +Before the class you should install MySQL and MySQL on your computer: + +- Instructions for macOS: [click here](https://www.youtube.com/watch?v=7S_tz1z_5bA&t=290s) +- Instructions for Windows: [click here](https://www.youtube.com/watch?v=7S_tz1z_5bA&t=588s) +- Intructions for Linux: [click here](https://drive.google.com/file/d/1I4_iIxI3QZApVawOFbSEY89Cs4BMby5F/view?usp=sharing) + +## Class videos + +Since this is a semi flipped classroom, where you prepare the class during the week and then the teaching on Sunday will build on what you prepared, it is **_extremely important_** that you watch the following videos: + +- [introduction to databases, part 1](https://drive.google.com/file/d/1vrIOqad0fMVpbFgp1-9g1rvd7peMeu-e/view?usp=sharing); +- [introduction to databases, part 2](https://drive.google.com/file/d/17wvdTUgLB3KakjeKfr6rJn1T6KzpX9Uf/view?usp=sharing) ; +- [introduction to SELECT queries and small exercise](https://drive.google.com/file/d/1Km2knoXiZrR9TOwZZ2M7V_FLyb-X_FBA/view?usp=sharing). + +## Exercise before class + +Before Sunday also please do the following exercise, so that we can discuss it in the class: + +- write a `SELECT` query where you select the row in the `user` table, where the user `name` is `Pablo Kisbee`. + +## Checklist + +You are ready for Sunday's class if: + +- you have installed MySQL and MySQL Workbench; +- you have watched the `Class videos`; +- you have created the `hyf_lesson1` database on your computer (the data is [here](https://github.com/HackYourFuture-CPH/databases/blob/master/lesson1/lesson-data.sql)); +- you have done the `SELECT` exercise. + +If you run into trouble completing any of the above, please ask for help in the class channel :) diff --git a/legacy/databases/lesson2/Database_normalization.pdf b/legacy/databases/lesson2/Database_normalization.pdf new file mode 100644 index 00000000..85f0bead Binary files /dev/null and b/legacy/databases/lesson2/Database_normalization.pdf differ diff --git a/legacy/databases/lesson2/Database_normalization.pptx b/legacy/databases/lesson2/Database_normalization.pptx new file mode 100644 index 00000000..15cc33e7 Binary files /dev/null and b/legacy/databases/lesson2/Database_normalization.pptx differ diff --git a/legacy/databases/lesson2/README.md b/legacy/databases/lesson2/README.md new file mode 100644 index 00000000..05082d9f --- /dev/null +++ b/legacy/databases/lesson2/README.md @@ -0,0 +1,93 @@ +# Lesson 2: Data Models, Relationships, and Schemas + +In this class, the students will learn how to use more complex SQL queries to retrieve information across tables, and interact with data including write operations. + +Objective: the students should be able to build CRUD functionality using SQL statements, including INSERT INTO, UPDATE and DELETE. The students should also be able to create an entity relationship diagram based on a qualitative description of data requirements, and translate that into a MySQL database schema. + +## Pre-Class Readings + +- [Falsehoods Programmers Believe About Names](http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/) +- [What is a Database Foreign Key](https://www.educative.io/blog/what-is-foreign-key-database) +- [Example Entity Relationship Diagram (including associative entities)](http://users.csc.calpoly.edu/~jdalbey/308/Lectures/HOWTO-ERD.html) + +The students should watch this video before class: + +## Main Topics + +- Data definition language + - Creating tables + - Altering tables + - Indexes +- Foreign key constraints +- INSERT INTO +- UPDATE +- DELETE +- More complex entity relationship diagrams + - Associative entities from many-to-many relationships + - Introduction to normalisation +- Complicated values to store in MySQL + - Storing prices (floating point errors) + - Storing date and time (datetime vs. timestamp) + - Timezones when storing date and time +- Creating an ER model and a database from existing data + +## Reference Material + +- [Floating Point Inaccuracy](http://stackoverflow.com/questions/2100490/floating-point-inaccuracy-examples#2100502) +- [TutorialsPoint MySQL Introduction](http://www.tutorialspoint.com/mysql/mysql-introduction.htm) +- [w3schools tutorial (easy to find how specific commands work)](https://www.w3schools.com/sql/default.asp) +- [Official MySQL Documentation](https://dev.mysql.com/doc/refman/8.0/en/) + +## Homework + +### Start the homework + +Need to brush up on the homework setup process? Check [this](https://github.com/HackYourFuture-CPH/Git/blob/main/homework-submission.md) out before you get into some git confusion! + +### Part 1: Working with tasks + +Write the following sql queries: + +- Add a task with these attributes: `title, description, created, updated, due_date, status_id, user_id` +- Change the title of a task +- Change a task due date +- Change a task status +- Mark a task as complete +- Delete a task + +In all the above queries, you choose which is the task that you will modify/delete. + +### Part 2: School database + +- Create a new database containing the following tables: + - **Class**: with the columns: id, name, begins (date), ends (date) + - **Student**: with the columns: id, name, email, phone, class_id (foreign key) +- If you are done with the above tasks, you can continue with these advanced tasks: + - Create an index on the name column of the student table. + - Add a new column to the class table named **status** which can only have the following values: not-started, ongoing, finished (hint: enumerations). + +### Part 3: More queries + +You should do these queries on the database `hyf_lesson2`, which we created last class. +You can find the data [here](lesson2-data.sql) if you need to create the DB again. + +- Get all the tasks assigned to users whose email ends in `@spotify.com` +- Get all the tasks for 'Donald Duck' with status 'Not started' +- Get all the tasks for 'Maryrose Meadows' that were created in september (hint: `month(created)=month_number`) +- Find how many tasks where created in each month, e.g. how many tasks were created in october, how many tasks were created in november, etc. (hint: use group by) + +### Part 4: Creating a database + +Using an entity relationship diagram, design the data model for an application of your choice. This can be anything, previous students have used a small business (with staff, offices, and job titles), a library (with books, genres, racks, members, and a borrowing log), or a farm (with animals, barns, and farmers). + +Your application must include at least one many-to-many relationship and any supporting tables (linking tables) that are needed. The entity relationship diagram must describe what tables you will need, the columns in these tables, which column is the primary key, and the relationships between tables. + +Next, using the entity relationship diagram as a starting point, write all the necessary `CREATE TABLE` statements to create all tables and relationships (foreign key constraints) for this data model. + +Submit an image or PDF of your entity relationship diagram, and a `.sql` file with the `CREATE TABLE` statements. + +### Hand in homework + +Need to brush up on the homework hand-in process? + +Check [this resource](https://github.com/HackYourFuture-CPH/Git/blob/main/homework-submission.md) to remember how to hand in the homework correctly! diff --git a/legacy/databases/lesson2/articles_example.json b/legacy/databases/lesson2/articles_example.json new file mode 100644 index 00000000..31672a30 --- /dev/null +++ b/legacy/databases/lesson2/articles_example.json @@ -0,0 +1,50 @@ +[ + { + "id": 1, + "authors": [ + { + "id": 1, + "name": "James Smith" + }, + { + "id": 2, + "name": "Jane Jones" + } + ], + "title": "BREAKING NEWS: Water is wet!", + "content": "Scientists have discovered that water is wet, it's amazing what.... ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", + "tags": ["science", "breaking"] + }, + { + "id": 2, + "authors": [ + { + "id": 3, + "name": "Aliya Awad" + }, + { + "id": 4, + "name": "Igor Vladimir" + } + ], + "title": "Heavy Snowfall Expected this Weekend", + "content": "Lots of snow is expected... Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + "tags": ["weather", "winter"] + }, + { + "id": 3, + "authors": [ + { + "id": 2, + "name": "Jane Jones" + }, + { + "id": 5, + "name": "Kim Jensen" + } + ], + "title": "BREAKING NEWS: These 10 Clickbait Titles Are Bad for Your Health, Number 7 Will SHOCK You!", + "content": "Haha, you clicked! Minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat ", + "tags": ["clickbait", "breaking"] + } +] diff --git a/legacy/databases/lesson2/class_exercises.md b/legacy/databases/lesson2/class_exercises.md new file mode 100644 index 00000000..28c5ec1a --- /dev/null +++ b/legacy/databases/lesson2/class_exercises.md @@ -0,0 +1,11 @@ +# Class exercises + +## Queries + +1. Get all the tasks assigned to `Pavel`; +2. Find how many tasks each user is responsible for; +3. Find how many tasks with a `status=Done` each user is responsible for; + +## Design and implement a database for existing data + +Design an ER model and implement the respective database for the data in [this file](articles_example.json). diff --git a/legacy/databases/lesson2/hyf_db_mm_eer_diagram.png b/legacy/databases/lesson2/hyf_db_mm_eer_diagram.png new file mode 100644 index 00000000..94a4c093 Binary files /dev/null and b/legacy/databases/lesson2/hyf_db_mm_eer_diagram.png differ diff --git a/legacy/databases/lesson2/lesson2-data.sql b/legacy/databases/lesson2/lesson2-data.sql new file mode 100644 index 00000000..69e21ce3 --- /dev/null +++ b/legacy/databases/lesson2/lesson2-data.sql @@ -0,0 +1,140 @@ +SET NAMES utf8mb4; + +CREATE TABLE `user` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, + `name` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `phone` varchar(255) NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `status` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, + `name` varchar(255) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `task` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, + `title` varchar(255) NOT NULL, + `description` text NULL DEFAULT NULL, + `created` DATETIME NOT NULL, + `updated` DATETIME NOT NULL, + `due_date` DATETIME NULL DEFAULT NULL, + `status_id` int(10) unsigned NOT NULL, + CONSTRAINT `fk_status` FOREIGN KEY (`status_id`) REFERENCES `status` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + + +CREATE TABLE `user_task` ( + `user_id` int(10) unsigned NOT NULL, + `task_id` int(10) unsigned NOT NULL, + PRIMARY KEY(`user_id`, `task_id`), + CONSTRAINT `fk_user_task_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `fk_user_task_task` FOREIGN KEY (`task_id`) REFERENCES `task` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + + + +-- Users +insert into user (id, name, email, phone) values (1, 'Aarika Ellingworth', 'aellingworth0@harvard.edu', '483-396-8795'); +insert into user (id, name, email, phone) values (2, 'Pren Goldsworthy', 'pgoldsworthy1@spotify.com', '635-572-8467'); +insert into user (id, name, email, phone) values (3, 'Pablo Kisbee', 'pkisbee2@lulu.com', '790-962-8683'); +insert into user (id, name, email, phone) values (4, 'Rodie Duncan', 'rduncan3@quantcast.com', '646-743-6191'); +insert into user (id, name, email, phone) values (5, 'Aubry Polak', 'apolak4@indiatimes.com', '302-678-7931'); +insert into user (id, name, email, phone) values (6, 'Maryrose Meadows', 'mmeadows5@comcast.net', '251-524-6594'); +insert into user (id, name, email, phone) values (7, 'Pavel Brushneen', 'pbrushneen6@techcrunch.com', '316-170-3640'); +insert into user (id, name, email, phone) values (8, 'Hedy Gerault', 'hgerault7@nymag.com', '176-177-5579'); +insert into user (id, name, email, phone) values (9, 'ηŽ‹η§€θ‹±', 'wang.xiuying@weebly.com', '891-952-6749'); +insert into user (id, name, email, phone) values (10, 'Ψ₯Ω„ΩŠΨ§Ψ³', 'elias@github.com', '202-517-6983'); +insert into user (id, name, email, phone) values (11, 'Donald Duck', 'donald@duck.com', NULL); + +-- Statuses +insert into status (id, name) values (1, 'Not started'); +insert into status (id, name) values (2, 'In progress'); +insert into status (id, name) values (3, 'Done'); + + +-- Tasks +insert into task (id, title, description, created, updated, due_date, status_id) values (1, 'Wash clothes', 'Title says it all.', '2017-10-25 06:54:16', '2017-10-15 13:05:09', null, 2); +insert into task (id, title, description, created, updated, due_date, status_id) values (2, 'Become a billionaire', 'This should not take long, just invent a time machine, travel back to 2010 and buy bitcoin', '2017-09-26 03:06:46', '2017-10-08 06:14:31', '2017-12-22 20:58:03', 3); +insert into task (id, title, description, created, updated, due_date, status_id) values (3, 'Plan meeting with London office', 'We will probably use skype', '2017-10-04 18:07:37', '2017-10-14 16:01:31', '2017-12-05 19:42:15', 2); +insert into task (id, title, description, created, updated, due_date, status_id) values (4, 'Order groceries online', 'The fridge is almost empty, we need eggs and milk', '2017-09-20 19:34:43', '2017-10-15 23:35:45', '2017-12-24 16:00:46', 1); +insert into task (id, title, description, created, updated, due_date, status_id) values (5, 'Empty the mailbox', NULL, '2017-09-27 15:17:08', '2017-10-08 17:31:16', null, 2); +insert into task (id, title, description, created, updated, due_date, status_id) values (6, 'Fix the flat tire on the bike', 'Tools are in the garage', '2017-09-13 23:16:30', '2017-10-06 04:03:52', '2017-12-07 11:51:11', 2); +insert into task (id, title, description, created, updated, due_date, status_id) values (7, 'Wash the car', NULL, '2017-10-06 19:39:16', '2017-10-03 04:49:05', '2017-12-04 17:43:16', 2); +insert into task (id, title, description, created, updated, due_date, status_id) values (8, 'Walk the dog', NULL, '2017-09-03 02:47:17', '2017-10-12 18:40:08', null, 3); +insert into task (id, title, description, created, updated, due_date, status_id) values (9, 'Write a book', 'Maybe something about dragons?', '2017-10-11 06:14:01', '2017-10-17 12:19:08', '2017-12-21 20:18:05', 2); +insert into task (id, title, description, created, updated, due_date, status_id) values (10, 'Do HackYourFuture homework', NULL, '2017-10-04 13:55:16', '2017-10-10 00:18:05', '2017-12-19 17:01:10', 1); +insert into task (id, title, description, created, updated, due_date, status_id) values (11, 'Iron shirts', NULL, '2017-09-23 03:59:58', '2017-10-19 08:30:48', '2017-12-08 11:00:35', 3); +insert into task (id, title, description, created, updated, due_date, status_id) values (12, 'Water the potted plants', 'Maybe they need fertilizer as well', '2017-09-29 23:38:42', '2017-10-08 04:24:53', null, 2); +insert into task (id, title, description, created, updated, due_date, status_id) values (13, 'Buy wine for the birthday party', 'Both red and white wine', '2017-10-10 14:57:22', '2017-10-14 14:03:30', '2017-12-10 23:43:56', 2); +insert into task (id, title, description, created, updated, due_date, status_id) values (14, 'Buy gift for Paul', 'He could use a shirt or a tie and some socks', '2017-09-09 05:22:08', '2017-10-17 15:58:05', '2017-12-04 20:45:18', 3); +insert into task (id, title, description, created, updated, due_date, status_id) values (15, 'Change lightbulb in hallway', 'Should be an LED bulb', '2017-10-01 19:07:35', '2017-10-03 10:02:27', '2017-12-08 17:09:03', 3); +insert into task (id, title, description, created, updated, due_date, status_id) values (16, 'Wash windows', NULL, '2017-10-02 22:15:17', '2017-10-07 22:31:35', '2017-12-06 03:36:09', 2); +insert into task (id, title, description, created, updated, due_date, status_id) values (17, 'Setup salary databases for accounting', 'Use MySQL', '2017-10-25 05:35:33', '2017-10-10 23:22:33', '2017-12-05 00:19:08', 1); +insert into task (id, title, description, created, updated, due_date, status_id) values (18, 'Learn how databases work', NULL, '2017-09-06 03:16:47', '2017-10-10 16:56:58', '2017-12-18 05:08:05', 3); +insert into task (id, title, description, created, updated, due_date, status_id) values (19, 'Make the databases perform better', 'It should be possible to optimize the indexes', '2017-10-03 09:27:20', '2017-10-01 16:27:46', '2017-12-01 13:28:35', 2); +insert into task (id, title, description, created, updated, due_date, status_id) values (20, 'Buy beer for the company party', '2 or 3 cases should be enough', '2017-10-08 01:39:02', '2017-10-13 23:07:41', null, 3); +insert into task (id, title, description, created, updated, due_date, status_id) values (21, 'Knit sweater', NULL, '2017-09-22 17:14:55', '2017-10-08 09:01:35', '2017-12-15 20:33:57', 2); +insert into task (id, title, description, created, updated, due_date, status_id) values (22, 'Charge electric bicycle', 'It sucks to ride it without a battery!', '2017-10-10 12:25:07', '2017-10-07 21:45:01', '2017-12-10 19:02:17', 1); +insert into task (id, title, description, created, updated, due_date, status_id) values (23, 'Buy new phone', 'The battery in the current one only lasts 5 hours 😞', '2017-09-17 00:25:34', '2017-10-09 11:48:12', null, 3); +insert into task (id, title, description, created, updated, due_date, status_id) values (24, 'Ride bike aroud SjΓ¦lland', 'Remember rainclothes and tire repair kit!', '2017-10-20 19:21:13', '2017-10-07 01:38:06', '2017-12-19 15:08:18', 2); +insert into task (id, title, description, created, updated, due_date, status_id) values (25, 'Look at apartments in Ørestad', '2 or 3 rooms', '2017-10-30 09:47:00', '2017-10-19 06:11:26', null, 1); +insert into task (id, title, description, created, updated, due_date, status_id) values (26, 'Empty Mr Fluffy\'s litterbox', NULL, '2017-09-28 03:09:06', '2017-10-13 10:38:34', '2017-12-20 23:37:18', 2); +insert into task (id, title, description, created, updated, due_date, status_id) values (27, 'Buy new dining room table and chairs', 'Ikea has some on sale', '2017-09-21 12:02:34', '2017-10-02 02:05:11', '2017-12-06 00:14:30', 1); +insert into task (id, title, description, created, updated, due_date, status_id) values (28, 'Renew buscard', '3 zones', '2017-10-07 22:47:51', '2017-10-09 15:50:03', '2017-12-01 14:25:40', 2); +insert into task (id, title, description, created, updated, due_date, status_id) values (29, 'Sign up for linkedin', 'Make the CV awesome! πŸ˜„', '2017-09-04 00:57:47', '2017-10-18 18:07:48', '2017-12-07 23:04:38', 3); +insert into task (id, title, description, created, updated, due_date, status_id) values (30, 'Remove facebook from phone', 'To avoid interruptions when working', '2017-10-26 17:15:07', '2017-10-13 03:36:47', '2017-12-19 11:10:02', 3); +insert into task (id, title, description, created, updated, due_date, status_id) values (31, 'Backup databases to external disk', 'Remember to store the disk in another physical location', '2017-09-09 17:32:33', '2017-10-01 21:18:59', '2017-12-23 14:21:01', 1); +insert into task (id, title, description, created, updated, due_date, status_id) values (32, 'Put up the new lamp in the hallway', NULL, '2017-10-15 05:45:54', '2017-10-16 14:05:35', '2017-12-29 02:29:26', 3); +insert into task (id, title, description, created, updated, due_date, status_id) values (33, 'Hang up paintings in living room', NULL, '2017-09-10 05:36:11', '2017-10-09 17:40:42', null, 3); +insert into task (id, title, description, created, updated, due_date, status_id) values (34, 'Buy plane ticket to Auckland', 'Check prices online first!', '2017-09-05 09:07:22', '2017-10-15 09:36:06', '2017-12-07 11:10:05', 1); +insert into task (id, title, description, created, updated, due_date, status_id) values (35, 'Learn about NoSQL databases', 'MongoDB, CouchDB, etc.', '2017-10-20 01:41:53', '2017-10-04 07:19:56', '2017-12-23 10:13:42', 2); + + + + +-- Users-tasks +insert into user_task (user_id, task_id) values(1, 5); +insert into user_task (user_id, task_id) values(1, 35); +insert into user_task (user_id, task_id) values(1, 11); +insert into user_task (user_id, task_id) values(2, 4); +insert into user_task (user_id, task_id) values(2, 26); +insert into user_task (user_id, task_id) values(2, 29); +insert into user_task (user_id, task_id) values(3, 22); +insert into user_task (user_id, task_id) values(3, 13); +insert into user_task (user_id, task_id) values(3, 19); +insert into user_task (user_id, task_id) values(4, 24); +insert into user_task (user_id, task_id) values(4, 20); +insert into user_task (user_id, task_id) values(5, 20); +insert into user_task (user_id, task_id) values(5, 18); +insert into user_task (user_id, task_id) values(5, 15); +insert into user_task (user_id, task_id) values(6, 10); +insert into user_task (user_id, task_id) values(6, 7); +insert into user_task (user_id, task_id) values(6, 27); +insert into user_task (user_id, task_id) values(7, 33); +insert into user_task (user_id, task_id) values(7, 18); +insert into user_task (user_id, task_id) values(7, 23); +insert into user_task (user_id, task_id) values(8, 26); +insert into user_task (user_id, task_id) values(8, 30); +insert into user_task (user_id, task_id) values(8, 11); +insert into user_task (user_id, task_id) values(9, 34); +insert into user_task (user_id, task_id) values(9, 15); +insert into user_task (user_id, task_id) values(9, 1); +insert into user_task (user_id, task_id) values(10, 29); +insert into user_task (user_id, task_id) values(10, 16); +insert into user_task (user_id, task_id) values(10, 1); +insert into user_task (user_id, task_id) values(11, 26); +insert into user_task (user_id, task_id) values(11, 27); +insert into user_task (user_id, task_id) values(11, 17); +insert into user_task (user_id, task_id) values(11, 2); +insert into user_task (user_id, task_id) values(1, 3); +insert into user_task (user_id, task_id) values(2, 6); +insert into user_task (user_id, task_id) values(3, 8); +insert into user_task (user_id, task_id) values(4, 9); +insert into user_task (user_id, task_id) values(5, 12); +insert into user_task (user_id, task_id) values(6, 14); +insert into user_task (user_id, task_id) values(7, 21); +insert into user_task (user_id, task_id) values(8, 25); +insert into user_task (user_id, task_id) values(9, 28); +insert into user_task (user_id, task_id) values(10, 31); +insert into user_task (user_id, task_id) values(11, 32); diff --git a/legacy/databases/lesson2/preparation_flipped_classroom.md b/legacy/databases/lesson2/preparation_flipped_classroom.md new file mode 100644 index 00000000..186a4941 --- /dev/null +++ b/legacy/databases/lesson2/preparation_flipped_classroom.md @@ -0,0 +1,45 @@ +# Preparation for (semi) flipped classroom + +This is the preparation for the (semi) flipped classroom (vs. "old style" presential classes). + +We say (semi) flipped classroom, because part of the teaching is still done on the Sunday class. + +## Class videos + +Since this is a semi flipped classroom, where you prepare the class during the week and then the teaching on Sunday will build on what you prepared, it is **extremely important** that you watch the following videos: + +- [Creating and manipulating tables](https://drive.google.com/file/d/1v3p_fE1JqST9sSEOJxhWNRBmZRCN1lEU/view?usp=sharing); +- [Manipulating table entries](https://drive.google.com/file/d/1wcx16QxuG5mbDHZYLbA88E2zjEsu460t/view?usp=sharing). + +## Readings + +- [Falsehoods Programmers Believe About Names](http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/) +- [What is a Database Foreign Key](http://databases.about.com/cs/specificproducts/g/foreignkey.htm) + +## Exercise before class + +In lesson 1 we used a database where each user was responsible for many tasks, but each task was only assigned to one user. +This is called a many-to-one relationship, many tasks are assigned to one user (**or** one-to-many, as in, one user can be responsible for many tasks). + +Each task also had one status, and one status could be attributed to many tasks. +So, again we had a one-to-many relationship: one status is assigned to many tasks (**or** many-to-one, as in, many tasks can have the same one status assigned). + +In lesson 2 things are going to get more interesting, as different users can be assigned to the same task. +So we'll have a many-to-many relationship, i.e., one task can be assigned to many users and one user can be assigned to many tasks. +For instance: + +- Donald Duck and Wonderwoman will do the task "Fix Donald's bike", and +- Donald Duck will do the tasks "Fix Donald's bike" and "Cook Dinner". + +The exercise for this week is for you (in groups to be defined in the class channel) to find out what needs to change in the database to support this many-to-many relationship. +Maybe we need to add a table(s) or column(s). Who knows? + +We'll start the class on Sunday by discussing your proposals :) + +## Checklist + +You are ready for Sunday's class if: + +- you have watched the `Class videos`; +- you have read the articles under `Readings`; +- you are ready to present your conclusions about many-to-many relationships. diff --git a/legacy/databases/lesson3/MongoDB/.gitignore b/legacy/databases/lesson3/MongoDB/.gitignore new file mode 100644 index 00000000..d6ff244f --- /dev/null +++ b/legacy/databases/lesson3/MongoDB/.gitignore @@ -0,0 +1,2 @@ +**/.idea/workspace.xml +**/.idea/tasks.xml \ No newline at end of file diff --git a/legacy/databases/lesson3/MongoDB/README.md b/legacy/databases/lesson3/MongoDB/README.md new file mode 100644 index 00000000..40a2caf7 --- /dev/null +++ b/legacy/databases/lesson3/MongoDB/README.md @@ -0,0 +1,136 @@ +# MongoDB - Introduction + +ManogoDB Lesson 1 for Hack Your Future **_Class12_** + +## MongoDB not RDBMS + +## Not a Transactional DB (You can not be sure that the data is not changed from other sources while you update it) + +## Data is saved in JSON format but in Binary not Text, BSON (Bee-SON) + +```json +{ + "firstname": "Peter", + "lastname": "Membrey", + "numbers": [ + { + "phone": "+852 1234 5678" + }, + { + "fax": "+44 1234 565 555" + } + ] +} +``` + +## There are no tables vs. RDBMS which has a static design + +## Installing MongoDB on Mincrosoft Windows Windows + +[Download] () + +1. Select the zip version +2. Unpack to c:\MongoDB +3. Open a command prompt +4. Create c:\data\db with mkdir c:\data, mkdir c:\data\db +5. Starting the server Run c:\MongoDb\bin\mongod.exe +6. Open a command prompt +7. Run c:\MongoDB\bin\mongo.exe + +## Installing MongoDB on Mac + +### Install Homebrew + +`/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"` + +Then: + +1. Install Homebrew: **/usr/bin/ruby -e β€œ$(curl -fsSL ** +2. Tap the MongoDB Homebrew Tap: **brew tap mongodb/brew** +3. Install MongoDB: **brew install mongodb-community@4.2** +4. Run MongoDB: **mongod --config /usr/local/etc/mongod.conf OR brew services start mongodb-community@4.2** +5. Connect and Use MongoDB: **mongo** + +## Basic commands + +Table 2-2: Basic Commands within the MongoDB Shell +Open table as spreadsheet + +| Command | Function | +| ---------------- | ----------------------------------------------------- | +| show dbs | Shows the names of the available databases. | +| show collections | Shows the collections in the current database. | +| show users | Shows the users in the current database. | +| use "db name" | Sets the current database to "db name" or creates it. | + +**_collection is a commonly used term in MongoDB. You can think of a collection as a container that stores your documents (that is, your data)_** + +## Datatypes + +- **_String_**: This commonly used datatype contains a string of text (or any other kind of characters). This datatype is used mostly for storing text values (for example, "Country" : "Japan"}. +- **_Integer_** (32b and 64b): This type is used to store a numerical value (for example, { "Rank" : 1 }). Note that there are no quotes placed before or after the integer. +- **_Boolean_**: This datatype can be set to either TRUE or FALSE. +- **_Double_**: This datatype is used to store floating-point values. +- **_Min /Max key_**s: This datatype is used to compare a value against the lowest and highest BSON elements, respectively. +- **_Arrays_**: This datatype is used to store arrays (for example, ["Membrey, Peter","Plugge, Eelco","Hows, David"]). +- **_Timestamp_**: This datatype is used to store a timestamp. This can be handy for recording when a document has been modified or added. +- **_Object_**: This datatype is used for embedded documents. +- **_Null_**: This datatype is used for a Null value. +- **_Symbol_**: This datatype is used identically to a string; however, it's generally reserved for languages that use a specific symbol type. +- **_Date_** \* : This datatype is used to store the current date or time in Unix time format (POSIX time). +- **_Object ID_** \*: This datatype is used to store the document's ID. +- **_Binary data_** \*: This datatype is used to store binary data. +- **_Regular expression_** \*: This datatype is used for regular expressions. All options are represented by specific characters provided in alphabetical order. You will learn more about regular expressions in Chapter 4. +- **_JavaScript Code_** \*: This datatype is used for JavaScript code. + +The **_asterisks_** mean that the last five datatypes (date, object ID, binary data, regex, and JavaScript code) are non-JSON types; specifically, they are special datatypes that BSON allows you to use. In Chapter 4, you will learn how to identify your datatypes by using the $type operator. + +In the relational approach, your data structure might look something like this: + +```text +|_media + |_cds + |_id, artist, title, genre, releasedate + |_ cd_tracklists + |_cd_id, songtitle, length +``` + +In the nonrelational approach, your data structure might look something like this: + +```text +|_media + |_items + |_ +``` + +In the nonrelational approach, the document might look something like the following: + +```json +{ + "Type": "CD", + "Artist": "Nirvana", + "Title": "Nevermind", + "Genre": "Grunge", + "Releasedate": "1991.09.24", + "Tracklist": [ + { + "Track": "1", + "Title": "Smells Like Teen Spirit", + "Length": "5:02" + }, + { + "Track": "2", + "Title": "In Bloom", + "Length": "4:15" + } + ] +} +``` + +## Creating the \_id Field + +Every object within the MongoDB database contains a unique identifier to distinguish that object from every other object. This identifier is called the **_\_id_** key, and it is added automatically to every document you create in a collection + +The **_\_id_** key is the first attribute added in each new document you create. This remains true even if you do not tell MongoDB to create the key. For example, none of the code in the preceding examples used the **_\_id_** key. Nevertheless, MongoDB created an \_id key for you automatically in each document. It did so because_id key is a mandatory element for each document in the collection. + +The **_\_id_** key consists of 12 bytes (12\*8=96 bits, 2^96=7.9228163e+28 combinations), it is almost Unique. 4-byte timestamp (seconds since epoch, or January 1st, 1970), a 3-byte machine ID, a 2-byte process ID, and a 3-byte counter diff --git a/legacy/databases/lesson3/MongoDB/execise_1.md b/legacy/databases/lesson3/MongoDB/execise_1.md new file mode 100644 index 00000000..6ba1bee3 --- /dev/null +++ b/legacy/databases/lesson3/MongoDB/execise_1.md @@ -0,0 +1,24 @@ +# MongoDB Exercise one + +We are using the database from the lesson 1: + + +Export the tables into JSON files using MySQL Workbench + +Please use the following guide to export your tables' data into respected JSON files: + + +**Avoid exporting the primary keys and foreign keys fields**. + +## Start your MongoDB server: "mongod.exe" + +## Start your MongoDB shell: "mongo.exe" + +Please post the following operations in your PR (Pull Request) + +1. Create a database **"Todo"** +2. Insert the exported data into the related collections +3. Find the length of each collection using db."collection_name".find().length() +4. Return the first document of tasks collection using .limit() +5. Return the third document of the task collection using .skip() and .limit() +6. Find the documents which "description" is "learning Danish during physical working" using .find({_condition_}) diff --git a/legacy/databases/lesson3/MongoDB/lesson_1.md b/legacy/databases/lesson3/MongoDB/lesson_1.md new file mode 100644 index 00000000..317c63c4 --- /dev/null +++ b/legacy/databases/lesson3/MongoDB/lesson_1.md @@ -0,0 +1,188 @@ +# Lesson 1 + +## Collection is a Table + +In this example we create a database called "school" + +```text +use school +``` + +Now we create a class in the school + +```text +db.classes.insert({"name": "class 12", "studens":[], "teachers": []}) +``` + +See the created class + +```text +db.classes.find() + +{ "_id" : ObjectId("5e31778441832c965c0d270c"), "name" : "class 12", "studens" : [ ], "teachers" : [ ] } +``` + +In the above example the "**classes**" is a **collection** and the inserted object is a "**document**" + +Another way to create a collection is: + +```text +db.createCollection("classes") +``` + +### Multiple insert + +```text +db.classes.insert([ + {"name": "class 10", "studens":[], "teachers": []}, + {"name": "class 11", "studens":[], "teachers": []}, + {"name": "class 12", "studens":[], "teachers": []}, + {"name": "class 13", "studens":[], "teachers": []}, +]) +``` + +### Controlling the \_id manually + +```text +db.classes.insert({_id:1, "name": "class 12", "studens":[], "teachers": []}) +``` + +Duplicate \_id would result in write error + +Alternative syntax for insertion + +```text +db.classes.insert({_id:11, name: "class 12", studens:[], teachers: []}) +``` + +### Querying the Collection + +```text +db.classes.find() //returns all the documents +``` + +#### Querying with filter + +```text +db.classes.find({name: "class 12"}) +``` + +##### Filter with AND condition + +```text +db.classes.find({name: "class 12", _id:10}) +//returns +{"_id" : 10, "name" : "class 12", "studens" : [ ], "teachers" : [ ]} +``` + +##### Filter with OR condition + +```text +db.classes.find({$or:[{name: "class 12"}, {name: "class 13"}]}).pretty() +//returns +{ + "_id" : ObjectId("5e31778441832c965c0d270c"), + "name" : "class 12", + "studens" : [ ], + "teachers" : [ ] +} +{ + "_id" : 10, + "name" : "class 12", + "studens" : [ ], + "teachers" : [ ] +} +``` + +#### Updating a Document + +```text +db.classes.update( + {_id:10}, + {$set:{ + teachers:[ + {name:"Marta", age:20}, + {name:"Kalpana", age:25}, + {name:"Dan", age:30}, + {name:"Babak", age:50} + ] + } + } +) + +db.classes.update( + {_id:11}, + {$set:{ + teachers:[ + {name:"Sokrates", age:2500}, + {name:"Platon", age:2495}, + {name:"Aristotle", age:2400} + ] + } + } +) +``` + +#### Querying a Nested Document + +```text +db.classes.find({teachers: {name:"Marta", age:25}}).pretty() +``` + +In the above case the condition `teachers` must match both in the **number** of attribute names and the **order** of the attributes + +##### Querying a Nested document based on the value of a single attribute + +```text +db.classes.find({'teachers.name': "Marta"}).pretty() +``` + +##### Querying a Nested document based on the value of a single attribute using operators + +```text +db.classes.find({'teachers.age': {$lt:30}}).pretty() //less than +db.classes.find({'teachers.age': {$gt:1000}}).pretty() //greater than +db.classes.find({'teachers.age': {$lte:30}}).pretty() //less than or equal to +db.classes.find({'teachers.age': {$gte:30}}).pretty() //greater than or equal to +db.classes.find({'teachers.age': 30}).pretty() //equal to +db.classes.find({'teachers.age': {$lt: 30, $gt: 20}}).pretty() //Interval +``` + +##### Querying a Nested document based on the values of multiple attributes + +```text +db.classes.find({'teachers.age': 30, 'students.age': 20}}).pretty() +``` + +#### Manually Traversing the Documents in a Collection + +```text +var myCursor = db.classes.find() +while(myCursor.hasNext()) { + print(tojson(myCursor.next())) +} +//or +var myCursor = db.classes.find() +while(myCursor.hasNext()) { + printjson(myCursor.next()) +} +//or +var myCursor = db.classes.find(); +myCursor.forEach(printjson); +``` + +#### Query for Null or Missing Fields + +```text +db.classes.insert({"name": null}) +``` + +`{$type: 10}` is BSON equivalent of binary null which is used in the queries + +```text +// Finding documents with attributes equal null +db.classes.find({name: {$type: 10}}) + +// Finding documents with missing attributes +db.classes.find({teachers: {$exists: false}}) +``` diff --git a/legacy/databases/lesson3/MongoDB/operations.js b/legacy/databases/lesson3/MongoDB/operations.js new file mode 100644 index 00000000..907dd05a --- /dev/null +++ b/legacy/databases/lesson3/MongoDB/operations.js @@ -0,0 +1,1009 @@ +let students = [ + { + first_name: "Wilmar", + last_name: "Labb", + email: "wlabb0@amazon.com", + gender: "Male", + birthday: "1/15/1986", + }, + { + first_name: "Ely", + last_name: "Leetham", + email: "eleetham1@globo.com", + gender: "Male", + birthday: "11/18/1985", + }, + { + first_name: "Cinda", + last_name: "Luesley", + email: "cluesley2@vk.com", + gender: "Female", + birthday: "1/1/2007", + }, + { + first_name: "Aretha", + last_name: "Killbey", + email: "akillbey3@discovery.com", + gender: "Female", + birthday: "3/18/1995", + }, + { + first_name: "Janeczka", + last_name: "Mansel", + email: "jmansel4@spiegel.de", + gender: "Female", + birthday: "6/7/1987", + }, + { + first_name: "Nicolette", + last_name: "Havoc", + email: "nhavoc5@artisteer.com", + gender: "Female", + birthday: "10/27/1993", + }, + { + first_name: "Rhoda", + last_name: "Creffield", + email: "rcreffield6@xinhuanet.com", + gender: "Female", + birthday: "5/17/2013", + }, + { + first_name: "King", + last_name: "Stanyer", + email: "kstanyer7@jigsy.com", + gender: "Male", + birthday: "6/30/2000", + }, + { + first_name: "Alia", + last_name: "Scally", + email: "ascally8@tinyurl.com", + gender: "Female", + birthday: "12/25/1989", + }, + { + first_name: "Tandi", + last_name: "Lathleiffure", + email: "tlathleiffure9@ebay.com", + gender: "Female", + birthday: "8/14/1986", + }, + { + first_name: "Anny", + last_name: "Hencke", + email: "ahenckea@naver.com", + gender: "Female", + birthday: "1/6/1991", + }, + { + first_name: "Bink", + last_name: "Goneau", + email: "bgoneaub@infoseek.co.jp", + gender: "Male", + birthday: "11/11/2007", + }, + { + first_name: "Marianne", + last_name: "Pidgeley", + email: "mpidgeleyc@buzzfeed.com", + gender: "Female", + birthday: "3/24/2005", + }, + { + first_name: "Boone", + last_name: "Drover", + email: "bdroverd@ed.gov", + gender: "Male", + birthday: "7/7/1981", + }, + { + first_name: "Karolina", + last_name: "Newey", + email: "kneweye@statcounter.com", + gender: "Female", + birthday: "1/7/1999", + }, + { + first_name: "Tarrance", + last_name: "Siemons", + email: "tsiemonsf@uol.com.br", + gender: "Male", + birthday: "4/19/2015", + }, + { + first_name: "Panchito", + last_name: "Lee", + email: "pleeg@ustream.tv", + gender: "Male", + birthday: "1/4/1992", + }, + { + first_name: "Rodie", + last_name: "Muffin", + email: "rmuffinh@delicious.com", + gender: "Female", + birthday: "8/8/2001", + }, + { + first_name: "Orran", + last_name: "Baggalley", + email: "obaggalleyi@wikipedia.org", + gender: "Male", + birthday: "7/5/1986", + }, + { + first_name: "Rickie", + last_name: "Tezure", + email: "rtezurej@geocities.com", + gender: "Male", + birthday: "4/3/2001", + }, + { + first_name: "Kassi", + last_name: "Donner", + email: "kdonnerk@europa.eu", + gender: "Female", + birthday: "4/23/1998", + }, + { + first_name: "Tawnya", + last_name: "Timpany", + email: "ttimpanyl@netscape.com", + gender: "Female", + birthday: "1/11/2003", + }, + { + first_name: "Lyman", + last_name: "Crenshaw", + email: "lcrenshawm@yolasite.com", + gender: "Male", + birthday: "5/31/2018", + }, + { + first_name: "Bibby", + last_name: "Bowyer", + email: "bbowyern@bravesites.com", + gender: "Female", + birthday: "3/26/1987", + }, + { + first_name: "Abbey", + last_name: "Batrip", + email: "abatripo@webs.com", + gender: "Male", + birthday: "11/17/2006", + }, + { + first_name: "Micheline", + last_name: "Aldersea", + email: "malderseap@imdb.com", + gender: "Female", + birthday: "2/12/1986", + }, + { + first_name: "Bennie", + last_name: "Cremen", + email: "bcremenq@acquirethisname.com", + gender: "Male", + birthday: "7/6/2009", + }, + { + first_name: "Riki", + last_name: "Itzik", + email: "ritzikr@posterous.com", + gender: "Female", + birthday: "10/14/2010", + }, + { + first_name: "Normand", + last_name: "De la Harpe", + email: "ndelaharpes@virginia.edu", + gender: "Male", + birthday: "9/2/1980", + }, + { + first_name: "Elton", + last_name: "Frohock", + email: "efrohockt@google.com", + gender: "Male", + birthday: "10/6/1998", + }, + { + first_name: "Jacqui", + last_name: "Jentin", + email: "jjentinu@phpbb.com", + gender: "Female", + birthday: "3/17/1998", + }, + { + first_name: "Milicent", + last_name: "Cowtherd", + email: "mcowtherdv@gizmodo.com", + gender: "Female", + birthday: "5/18/1993", + }, + { + first_name: "Benjamen", + last_name: "Batrim", + email: "bbatrimw@army.mil", + gender: "Male", + birthday: "7/2/2010", + }, + { + first_name: "Vivian", + last_name: "Grime", + email: "vgrimex@fda.gov", + gender: "Female", + birthday: "9/27/1990", + }, + { + first_name: "Theresita", + last_name: "Foss", + email: "tfossy@dmoz.org", + gender: "Female", + birthday: "11/28/2005", + }, + { + first_name: "Caressa", + last_name: "Odgers", + email: "codgersz@163.com", + gender: "Female", + birthday: "12/6/1986", + }, + { + first_name: "Alvan", + last_name: "Coogan", + email: "acoogan10@state.tx.us", + gender: "Male", + birthday: "11/3/1998", + }, + { + first_name: "Rafaellle", + last_name: "Hapgood", + email: "rhapgood11@angelfire.com", + gender: "Male", + birthday: "6/19/2010", + }, + { + first_name: "Cirilo", + last_name: "Chelnam", + email: "cchelnam12@addtoany.com", + gender: "Male", + birthday: "6/8/2014", + }, + { + first_name: "Gabie", + last_name: "Tomadoni", + email: "gtomadoni13@ibm.com", + gender: "Male", + birthday: "1/25/2018", + }, + { + first_name: "Alta", + last_name: "Thompstone", + email: "athompstone14@nbcnews.com", + gender: "Female", + birthday: "2/7/1997", + }, + { + first_name: "Leo", + last_name: "Flewin", + email: "lflewin15@skype.com", + gender: "Male", + birthday: "10/26/2007", + }, + { + first_name: "Minor", + last_name: "Marven", + email: "mmarven16@marketwatch.com", + gender: "Male", + birthday: "10/23/1993", + }, + { + first_name: "Janek", + last_name: "Darrigone", + email: "jdarrigone17@noaa.gov", + gender: "Male", + birthday: "11/4/2017", + }, + { + first_name: "Ardis", + last_name: "Fibbens", + email: "afibbens18@msu.edu", + gender: "Female", + birthday: "3/30/2008", + }, + { + first_name: "Pete", + last_name: "Ipgrave", + email: "pipgrave19@go.com", + gender: "Male", + birthday: "2/2/2004", + }, + { + first_name: "Mitchell", + last_name: "Radmore", + email: "mradmore1a@sbwire.com", + gender: "Male", + birthday: "7/29/2006", + }, + { + first_name: "Ardene", + last_name: "Cheyenne", + email: "acheyenne1b@altervista.org", + gender: "Female", + birthday: "1/4/2009", + }, + { + first_name: "Dona", + last_name: "Grieg", + email: "dgrieg1c@whitehouse.gov", + gender: "Female", + birthday: "11/25/2005", + }, + { + first_name: "Rogerio", + last_name: "Bellworthy", + email: "rbellworthy1d@freewebs.com", + gender: "Male", + birthday: "7/1/2009", + }, + { + first_name: "Dwayne", + last_name: "Cypler", + email: "dcypler1e@rakuten.co.jp", + gender: "Male", + birthday: "4/2/2007", + }, + { + first_name: "Andres", + last_name: "Joy", + email: "ajoy1f@slashdot.org", + gender: "Male", + birthday: "7/16/1999", + }, + { + first_name: "Roxanne", + last_name: "Alflatt", + email: "ralflatt1g@google.com.hk", + gender: "Female", + birthday: "8/6/2003", + }, + { + first_name: "Pearla", + last_name: "Heggs", + email: "pheggs1h@nifty.com", + gender: "Female", + birthday: "1/9/1999", + }, + { + first_name: "Gillie", + last_name: "Khristoforov", + email: "gkhristoforov1i@cloudflare.com", + gender: "Female", + birthday: "3/30/1991", + }, + { + first_name: "Kelly", + last_name: "Millions", + email: "kmillions1j@springer.com", + gender: "Male", + birthday: "1/28/2007", + }, + { + first_name: "Wenda", + last_name: "Duxbarry", + email: "wduxbarry1k@netvibes.com", + gender: "Female", + birthday: "5/9/2017", + }, + { + first_name: "Madelyn", + last_name: "Blowen", + email: "mblowen1l@virginia.edu", + gender: "Female", + birthday: "8/6/1983", + }, + { + first_name: "Glen", + last_name: "MacCheyne", + email: "gmaccheyne1m@amazon.de", + gender: "Male", + birthday: "6/20/1995", + }, + { + first_name: "Sheilah", + last_name: "Middleton", + email: "smiddleton1n@ifeng.com", + gender: "Female", + birthday: "10/15/1983", + }, + { + first_name: "Sergei", + last_name: "L'oiseau", + email: "sloiseau1o@ebay.co.uk", + gender: "Male", + birthday: "5/6/1993", + }, + { + first_name: "Stearne", + last_name: "Bulfield", + email: "sbulfield1p@yale.edu", + gender: "Male", + birthday: "8/23/2014", + }, + { + first_name: "Eudora", + last_name: "Scurman", + email: "escurman1q@fastcompany.com", + gender: "Female", + birthday: "6/15/1991", + }, + { + first_name: "Devon", + last_name: "Blades", + email: "dblades1r@example.com", + gender: "Female", + birthday: "2/27/1990", + }, + { + first_name: "Any", + last_name: "Oppery", + email: "aoppery1s@github.com", + gender: "Male", + birthday: "7/1/2019", + }, + { + first_name: "Peg", + last_name: "Kuna", + email: "pkuna1t@gov.uk", + gender: "Female", + birthday: "2/10/2011", + }, + { + first_name: "Livy", + last_name: "Dunbar", + email: "ldunbar1u@so-net.ne.jp", + gender: "Female", + birthday: "7/27/2000", + }, + { + first_name: "Nico", + last_name: "Zeal", + email: "nzeal1v@shutterfly.com", + gender: "Male", + birthday: "4/16/2012", + }, + { + first_name: "Thain", + last_name: "Wilfinger", + email: "twilfinger1w@csmonitor.com", + gender: "Male", + birthday: "7/13/2011", + }, + { + first_name: "Michaelina", + last_name: "Itzakovitz", + email: "mitzakovitz1x@privacy.gov.au", + gender: "Female", + birthday: "1/1/2003", + }, + { + first_name: "Regina", + last_name: "Govini", + email: "rgovini1y@skyrock.com", + gender: "Female", + birthday: "12/15/2001", + }, + { + first_name: "Granny", + last_name: "Clewarth", + email: "gclewarth1z@uiuc.edu", + gender: "Male", + birthday: "4/28/1984", + }, + { + first_name: "Maynord", + last_name: "Syce", + email: "msyce20@mac.com", + gender: "Male", + birthday: "4/14/1990", + }, + { + first_name: "Lamont", + last_name: "Bardell", + email: "lbardell21@typepad.com", + gender: "Male", + birthday: "12/12/1991", + }, + { + first_name: "Micky", + last_name: "Huckerbe", + email: "mhuckerbe22@princeton.edu", + gender: "Female", + birthday: "10/9/2013", + }, + { + first_name: "Noe", + last_name: "McDowall", + email: "nmcdowall23@netvibes.com", + gender: "Male", + birthday: "8/14/1996", + }, + { + first_name: "Shelby", + last_name: "Tenbrug", + email: "stenbrug24@diigo.com", + gender: "Male", + birthday: "12/2/1983", + }, + { + first_name: "Pauline", + last_name: "Satyford", + email: "psatyford25@theatlantic.com", + gender: "Female", + birthday: "11/4/2001", + }, + { + first_name: "Beckie", + last_name: "Edinburough", + email: "bedinburough26@mozilla.com", + gender: "Female", + birthday: "6/13/2013", + }, + { + first_name: "Brandie", + last_name: "Geraudel", + email: "bgeraudel27@admin.ch", + gender: "Female", + birthday: "7/31/1997", + }, + { + first_name: "Joshia", + last_name: "Marini", + email: "jmarini28@oakley.com", + gender: "Male", + birthday: "10/10/2003", + }, + { + first_name: "Hallsy", + last_name: "Labes", + email: "hlabes29@clickbank.net", + gender: "Male", + birthday: "8/4/1982", + }, + { + first_name: "Sara-ann", + last_name: "Melia", + email: "smelia2a@globo.com", + gender: "Female", + birthday: "3/7/2018", + }, + { + first_name: "Auguste", + last_name: "Levane", + email: "alevane2b@unblog.fr", + gender: "Female", + birthday: "5/25/1980", + }, + { + first_name: "Bink", + last_name: "Dablin", + email: "bdablin2c@hp.com", + gender: "Male", + birthday: "11/19/1994", + }, + { + first_name: "Paulie", + last_name: "Burkill", + email: "pburkill2d@imdb.com", + gender: "Female", + birthday: "1/29/2002", + }, + { + first_name: "Esma", + last_name: "Ramsey", + email: "eramsey2e@wikia.com", + gender: "Female", + birthday: "3/19/2011", + }, + { + first_name: "Rosamond", + last_name: "Harower", + email: "rharower2f@de.vu", + gender: "Female", + birthday: "5/19/1992", + }, + { + first_name: "Ileana", + last_name: "Krebs", + email: "ikrebs2g@technorati.com", + gender: "Female", + birthday: "4/2/1982", + }, + { + first_name: "Bradney", + last_name: "Hardern", + email: "bhardern2h@pagesperso-orange.fr", + gender: "Male", + birthday: "9/5/1995", + }, + { + first_name: "Taylor", + last_name: "Woodcock", + email: "twoodcock2i@wiley.com", + gender: "Male", + birthday: "6/27/1995", + }, + { + first_name: "Rudyard", + last_name: "Lamba", + email: "rlamba2j@un.org", + gender: "Male", + birthday: "2/6/1989", + }, + { + first_name: "Tobit", + last_name: "Pogue", + email: "tpogue2k@blogtalkradio.com", + gender: "Male", + birthday: "12/26/1998", + }, + { + first_name: "Matilde", + last_name: "Picopp", + email: "mpicopp2l@posterous.com", + gender: "Female", + birthday: "2/4/2010", + }, + { + first_name: "Ilaire", + last_name: "Calken", + email: "icalken2m@time.com", + gender: "Male", + birthday: "6/10/2014", + }, + { + first_name: "Reuben", + last_name: "Thebes", + email: "rthebes2n@sourceforge.net", + gender: "Male", + birthday: "1/23/1998", + }, + { + first_name: "Orland", + last_name: "Koubek", + email: "okoubek2o@jiathis.com", + gender: "Male", + birthday: "2/18/1998", + }, + { + first_name: "Killie", + last_name: "McIlmorow", + email: "kmcilmorow2p@cdc.gov", + gender: "Male", + birthday: "7/8/2017", + }, + { + first_name: "Blaire", + last_name: "Harbin", + email: "bharbin2q@sbwire.com", + gender: "Female", + birthday: "12/14/2012", + }, + { + first_name: "Babb", + last_name: "Baily", + email: "bbaily2r@jalbum.net", + gender: "Female", + birthday: "4/23/1981", + }, +]; + +students; + +students.map((student) => { + student.birthday = new Date(student.birthday); + return student; +}); + +// students + +db.students.insertMany(students); + +let teachers = [ + { + first_name: "Michal", + last_name: "Ledger", + email: "mledger0@harvard.edu", + gender: "Female", + birthday: "5/24/2011", + }, + { + first_name: "Krystal", + last_name: "Goadbie", + email: "kgoadbie1@yandex.ru", + gender: "Female", + birthday: "6/28/1987", + }, + { + first_name: "Bili", + last_name: "Ridsdale", + email: "bridsdale2@bizjournals.com", + gender: "Female", + birthday: "11/17/1992", + }, + { + first_name: "Ula", + last_name: "Belcham", + email: "ubelcham3@aboutads.info", + gender: "Female", + birthday: "10/8/1980", + }, + { + first_name: "Thorsten", + last_name: "Kingsman", + email: "tkingsman4@clickbank.net", + gender: "Male", + birthday: "4/22/2012", + }, + { + first_name: "Bryan", + last_name: "Stennett", + email: "bstennett5@usgs.gov", + gender: "Male", + birthday: "1/25/1986", + }, + { + first_name: "Charley", + last_name: "Sallarie", + email: "csallarie6@usnews.com", + gender: "Male", + birthday: "11/15/1981", + }, + { + first_name: "Grady", + last_name: "Robertelli", + email: "grobertelli7@sourceforge.net", + gender: "Male", + birthday: "6/25/2017", + }, + { + first_name: "Merrily", + last_name: "McDermot", + email: "mmcdermot8@latimes.com", + gender: "Female", + birthday: "1/3/1997", + }, + { + first_name: "Mendie", + last_name: "Sinclar", + email: "msinclar9@businessinsider.com", + gender: "Male", + birthday: "12/12/2006", + }, +]; + +teachers; +db.teachers.insertMany(teachers); + +let subjects = [ + { name: "SQL" }, + { name: "NoSQL" }, + { name: "JavaScript" }, + { name: "NODE.JS" }, + { name: "GIT" }, + { name: ".NET" }, + { name: "HTML" }, + { name: "CSS3" }, + { name: "PHP" }, + { name: "Python" }, +]; + +subjects; +db.subjects.insertMany(subjects); + +db.students.find({}); + +db.students.find({}).limit(3); + +db.students.find({}).limit(3).skip(3); + +db.students.find({}).limit(3).pretty(); + +db.students.find({}).limit(3).sort({ birthday: -1 }).pretty(); + +db.students.find({}).sort({ birthday: -1 }).limit(3).pretty(); + +db.students.find({ first_name: "Wilmar" }).pretty(); + +db.students + .find({ + $or: [{ first_name: "Wilmar" }, { first_name: "Aretha" }], + }) + .pretty(); + +var cursor = db.students.find({ + $or: [{ first_name: "Wilmar" }, { first_name: "Aretha" }], +}); + +while (cursor.hasNext()) { + printjson(cursor.next()); +} + +var cursor = db.students.find({ + $or: [{ first_name: "Wilmar" }, { first_name: "Aretha" }], +}); + +while (cursor.hasNext()) { + var student = cursor.next(); + printjson(student); +} + +var cursor = db.students.find({ + $or: [{ first_name: "Wilmar" }, { first_name: "Aretha" }], +}); + +while (cursor.hasNext()) { + var student = cursor.next(); + printjson(student.birthday); +} + +var cursor = db.students.find({ + $or: [{ first_name: "Wilmar" }, { first_name: "Aretha" }], +}); + +while (cursor.hasNext()) { + var student = cursor.next(); + var birthday = new Date(student.birthday); + student.birthday = + birthday.getFullYear() + + "-" + + birthday.getMonth() + + "-" + + birthday.getDate(); + printjson(student); +} + +var cursor = db.students.find({ + $or: [{ first_name: "Wilmar" }, { first_name: "Aretha" }], +}); + +while (cursor.hasNext()) { + var student = cursor.next(); + var birthday = new Date(student.birthday); + student.birthday = + birthday.getFullYear() + + "-" + + (birthday.getMonth() + 1) + + "-" + + birthday.getDate(); + printjson(student); +} + +var cursor = db.students + .find({ + $or: [{ first_name: "Wilmar" }, { first_name: "Aretha" }], + }) + .sort({ birthday: -1 }); + +while (cursor.hasNext()) { + var student = cursor.next(); + var birthday = new Date(student.birthday); + student.birthday = + birthday.getFullYear() + + "-" + + (birthday.getMonth() + 1) + + "-" + + birthday.getDate(); + printjson(student); +} + +var cursor = db.students.find(); +while (cursor.hasNext()) { + var student = cursor.next(); + print(new Date(student.birthday)); +} + +db.students.find({ + $and: [ + { $or: [{ first_name: "Wilmar" }, { first_name: "Aretha" }] }, + { gender: "Male" }, + ], +}); + +db.students.find({ + $and: [ + { $or: [{ first_name: "Wilmar" }, { first_name: "Aretha" }] }, + { $or: [{ gender: "Male" }] }, + ], +}); + +db.students.find({ + gender: { $not: { $eq: "Male" } }, +}); + +db.students.find({ + $nor: [{ first_name: "Wilmar" }, { gender: "Male" }], +}); + +db.students.find({ + first_name: { $in: ["Wilmar", "Aretha"] }, +}); + +db.students.find({ + first_name: { + $exists: true, + $nin: ["Wilmar", "Aretha"], + }, +}); + +db.students.stats(); + +db.students.stats().count; + +var cursor = db.students.find({ + birthday: { + $gt: new Date("1980-01-01"), + $lt: new Date("1990-01-01"), + }, +}); +cursor.length(); + +db.students.update( + { first_name: "Wilmar" }, + { $set: { Address: "Enhavevej 81C, 4. th." } }, + { multi: true }, +); + +db.students.find({ first_name: "Wilmar" }); + +db.students.remove({ first_name: "Aretha" }); + +db.students.find({ first_name: "Aretha" }); + +db.students.remove({}); + +db.students.find(); + +db.students.insertMany(students); + +//relations +db.classes.insert({ teacher_ids: [], student_ids: [], subject_ids: [] }); +db.classes.find(); +db.classes.find({ teacher_ids: { $size: 0 } }); +// { "_id" : ObjectId("5e3f2d103820343c8cf9737f"), "teacher_ids" : [ ], "student_ids" : [ ], "subject_ids" : [ ] } +db.teachers.find(); +// { "_id" : ObjectId("5e3d4887e23e7698f4364d48"), "first_name" : "Michal", "last_name" : "Ledger", "email" : "mledger0@harvard.edu", "gender" : "Female", "birthday" : "5/24/2011" } +// { "_id" : ObjectId("5e3d4887e23e7698f4364d49"), "first_name" : "Krystal", "last_name" : "Goadbie", "email" : "kgoadbie1@yandex.ru", "gender" : "Female", "birthday" : "6/28/1987" } +// { "_id" : ObjectId("5e3d4887e23e7698f4364d4a"), "first_name" : "Bili", "last_name" : "Ridsdale", "email" : "bridsdale2@bizjournals.com", "gender" : "Female", "birthday" : "11/17/1992" } +// { "_id" : ObjectId("5e3d4887e23e7698f4364d4b"), "first_name" : "Ula", "last_name" : "Belcham", "email" : "ubelcham3@aboutads.info", "gender" : "Female", "birthday" : "10/8/1980" } +// { "_id" : ObjectId("5e3d4887e23e7698f4364d4c"), "first_name" : "Thorsten", "last_name" : "Kingsman", "email" : "tkingsman4@clickbank.net", "gender" : "Male", "birthday" : "4/22/2012" } +// { "_id" : ObjectId("5e3d4887e23e7698f4364d4d"), "first_name" : "Bryan", "last_name" : "Stennett", "email" : "bstennett5@usgs.gov", "gender" : "Male", "birthday" : "1/25/1986" } +// { "_id" : ObjectId("5e3d4887e23e7698f4364d4e"), "first_name" : "Charley", "last_name" : "Sallarie", "email" : "csallarie6@usnews.com", "gender" : "Male", "birthday" : "11/15/1981" } +// { "_id" : ObjectId("5e3d4887e23e7698f4364d4f"), "first_name" : "Grady", "last_name" : "Robertelli", "email" : "grobertelli7@sourceforge.net", "gender" : "Male", "birthday" : "6/25/2017" } +// { "_id" : ObjectId("5e3d4887e23e7698f4364d50"), "first_name" : "Merrily", "last_name" : "McDermot", "email" : "mmcdermot8@latimes.com", "gender" : "Female", "birthday" : "1/3/1997" } +// { "_id" : ObjectId("5e3d4887e23e7698f4364d51"), "first_name" : "Mendie", "last_name" : "Sinclar", "email" : "msinclar9@businessinsider.com", "gender" : "Male", "birthday" : "12/12/2006" } +db.classes.update( + { _id: ObjectId("5e3f2d103820343c8cf9737f") }, + { $addToSet: { teacher_ids: ObjectId("5e3d4887e23e7698f4364d48") } }, +); + +db.classes.find(); +// { "_id" : ObjectId("5e3f2d103820343c8cf9737f"), "teacher_ids" : [ ObjectId("5e3d4887e23e7698f4364d48") ], "student_ids" : [ ], "subject_ids" : [ ] } + +var result = db.classes.findOne(); +result; +// { +// "_id" : ObjectId("5e3f2d103820343c8cf9737f"), +// "teacher_ids" : [ +// ObjectId("5e3d4887e23e7698f4364d48") +// ], +// "student_ids" : [ ], +// "subject_ids" : [ ] +// } + +var teacher = db.teachers.find({ _id: { $in: result["teacher_ids"] } }); +teacher; +// { "_id" : ObjectId("5e3d4887e23e7698f4364d48"), "first_name" : "Michal", "last_name" : "Ledger", "email" : "mledger0@harvard.edu", "gender" : "Female", "birthday" : "5/24/2011" } diff --git a/legacy/databases/lesson3/MongoDB/students.json b/legacy/databases/lesson3/MongoDB/students.json new file mode 100644 index 00000000..cd90839d --- /dev/null +++ b/legacy/databases/lesson3/MongoDB/students.json @@ -0,0 +1,702 @@ +[ + { + "first_name": "Wilmar", + "last_name": "Labb", + "email": "wlabb0@amazon.com", + "gender": "Male", + "birthday": "1/15/1986" + }, + { + "first_name": "Ely", + "last_name": "Leetham", + "email": "eleetham1@globo.com", + "gender": "Male", + "birthday": "11/18/1985" + }, + { + "first_name": "Cinda", + "last_name": "Luesley", + "email": "cluesley2@vk.com", + "gender": "Female", + "birthday": "1/1/2007" + }, + { + "first_name": "Aretha", + "last_name": "Killbey", + "email": "akillbey3@discovery.com", + "gender": "Female", + "birthday": "3/18/1995" + }, + { + "first_name": "Janeczka", + "last_name": "Mansel", + "email": "jmansel4@spiegel.de", + "gender": "Female", + "birthday": "6/7/1987" + }, + { + "first_name": "Nicolette", + "last_name": "Havoc", + "email": "nhavoc5@artisteer.com", + "gender": "Female", + "birthday": "10/27/1993" + }, + { + "first_name": "Rhoda", + "last_name": "Creffield", + "email": "rcreffield6@xinhuanet.com", + "gender": "Female", + "birthday": "5/17/2013" + }, + { + "first_name": "King", + "last_name": "Stanyer", + "email": "kstanyer7@jigsy.com", + "gender": "Male", + "birthday": "6/30/2000" + }, + { + "first_name": "Alia", + "last_name": "Scally", + "email": "ascally8@tinyurl.com", + "gender": "Female", + "birthday": "12/25/1989" + }, + { + "first_name": "Tandi", + "last_name": "Lathleiffure", + "email": "tlathleiffure9@ebay.com", + "gender": "Female", + "birthday": "8/14/1986" + }, + { + "first_name": "Anny", + "last_name": "Hencke", + "email": "ahenckea@naver.com", + "gender": "Female", + "birthday": "1/6/1991" + }, + { + "first_name": "Bink", + "last_name": "Goneau", + "email": "bgoneaub@infoseek.co.jp", + "gender": "Male", + "birthday": "11/11/2007" + }, + { + "first_name": "Marianne", + "last_name": "Pidgeley", + "email": "mpidgeleyc@buzzfeed.com", + "gender": "Female", + "birthday": "3/24/2005" + }, + { + "first_name": "Boone", + "last_name": "Drover", + "email": "bdroverd@ed.gov", + "gender": "Male", + "birthday": "7/7/1981" + }, + { + "first_name": "Karolina", + "last_name": "Newey", + "email": "kneweye@statcounter.com", + "gender": "Female", + "birthday": "1/7/1999" + }, + { + "first_name": "Tarrance", + "last_name": "Siemons", + "email": "tsiemonsf@uol.com.br", + "gender": "Male", + "birthday": "4/19/2015" + }, + { + "first_name": "Panchito", + "last_name": "Lee", + "email": "pleeg@ustream.tv", + "gender": "Male", + "birthday": "1/4/1992" + }, + { + "first_name": "Rodie", + "last_name": "Muffin", + "email": "rmuffinh@delicious.com", + "gender": "Female", + "birthday": "8/8/2001" + }, + { + "first_name": "Orran", + "last_name": "Baggalley", + "email": "obaggalleyi@wikipedia.org", + "gender": "Male", + "birthday": "7/5/1986" + }, + { + "first_name": "Rickie", + "last_name": "Tezure", + "email": "rtezurej@geocities.com", + "gender": "Male", + "birthday": "4/3/2001" + }, + { + "first_name": "Kassi", + "last_name": "Donner", + "email": "kdonnerk@europa.eu", + "gender": "Female", + "birthday": "4/23/1998" + }, + { + "first_name": "Tawnya", + "last_name": "Timpany", + "email": "ttimpanyl@netscape.com", + "gender": "Female", + "birthday": "1/11/2003" + }, + { + "first_name": "Lyman", + "last_name": "Crenshaw", + "email": "lcrenshawm@yolasite.com", + "gender": "Male", + "birthday": "5/31/2018" + }, + { + "first_name": "Bibby", + "last_name": "Bowyer", + "email": "bbowyern@bravesites.com", + "gender": "Female", + "birthday": "3/26/1987" + }, + { + "first_name": "Abbey", + "last_name": "Batrip", + "email": "abatripo@webs.com", + "gender": "Male", + "birthday": "11/17/2006" + }, + { + "first_name": "Micheline", + "last_name": "Aldersea", + "email": "malderseap@imdb.com", + "gender": "Female", + "birthday": "2/12/1986" + }, + { + "first_name": "Bennie", + "last_name": "Cremen", + "email": "bcremenq@acquirethisname.com", + "gender": "Male", + "birthday": "7/6/2009" + }, + { + "first_name": "Riki", + "last_name": "Itzik", + "email": "ritzikr@posterous.com", + "gender": "Female", + "birthday": "10/14/2010" + }, + { + "first_name": "Normand", + "last_name": "De la Harpe", + "email": "ndelaharpes@virginia.edu", + "gender": "Male", + "birthday": "9/2/1980" + }, + { + "first_name": "Elton", + "last_name": "Frohock", + "email": "efrohockt@google.com", + "gender": "Male", + "birthday": "10/6/1998" + }, + { + "first_name": "Jacqui", + "last_name": "Jentin", + "email": "jjentinu@phpbb.com", + "gender": "Female", + "birthday": "3/17/1998" + }, + { + "first_name": "Milicent", + "last_name": "Cowtherd", + "email": "mcowtherdv@gizmodo.com", + "gender": "Female", + "birthday": "5/18/1993" + }, + { + "first_name": "Benjamen", + "last_name": "Batrim", + "email": "bbatrimw@army.mil", + "gender": "Male", + "birthday": "7/2/2010" + }, + { + "first_name": "Vivian", + "last_name": "Grime", + "email": "vgrimex@fda.gov", + "gender": "Female", + "birthday": "9/27/1990" + }, + { + "first_name": "Theresita", + "last_name": "Foss", + "email": "tfossy@dmoz.org", + "gender": "Female", + "birthday": "11/28/2005" + }, + { + "first_name": "Caressa", + "last_name": "Odgers", + "email": "codgersz@163.com", + "gender": "Female", + "birthday": "12/6/1986" + }, + { + "first_name": "Alvan", + "last_name": "Coogan", + "email": "acoogan10@state.tx.us", + "gender": "Male", + "birthday": "11/3/1998" + }, + { + "first_name": "Rafaellle", + "last_name": "Hapgood", + "email": "rhapgood11@angelfire.com", + "gender": "Male", + "birthday": "6/19/2010" + }, + { + "first_name": "Cirilo", + "last_name": "Chelnam", + "email": "cchelnam12@addtoany.com", + "gender": "Male", + "birthday": "6/8/2014" + }, + { + "first_name": "Gabie", + "last_name": "Tomadoni", + "email": "gtomadoni13@ibm.com", + "gender": "Male", + "birthday": "1/25/2018" + }, + { + "first_name": "Alta", + "last_name": "Thompstone", + "email": "athompstone14@nbcnews.com", + "gender": "Female", + "birthday": "2/7/1997" + }, + { + "first_name": "Leo", + "last_name": "Flewin", + "email": "lflewin15@skype.com", + "gender": "Male", + "birthday": "10/26/2007" + }, + { + "first_name": "Minor", + "last_name": "Marven", + "email": "mmarven16@marketwatch.com", + "gender": "Male", + "birthday": "10/23/1993" + }, + { + "first_name": "Janek", + "last_name": "Darrigone", + "email": "jdarrigone17@noaa.gov", + "gender": "Male", + "birthday": "11/4/2017" + }, + { + "first_name": "Ardis", + "last_name": "Fibbens", + "email": "afibbens18@msu.edu", + "gender": "Female", + "birthday": "3/30/2008" + }, + { + "first_name": "Pete", + "last_name": "Ipgrave", + "email": "pipgrave19@go.com", + "gender": "Male", + "birthday": "2/2/2004" + }, + { + "first_name": "Mitchell", + "last_name": "Radmore", + "email": "mradmore1a@sbwire.com", + "gender": "Male", + "birthday": "7/29/2006" + }, + { + "first_name": "Ardene", + "last_name": "Cheyenne", + "email": "acheyenne1b@altervista.org", + "gender": "Female", + "birthday": "1/4/2009" + }, + { + "first_name": "Dona", + "last_name": "Grieg", + "email": "dgrieg1c@whitehouse.gov", + "gender": "Female", + "birthday": "11/25/2005" + }, + { + "first_name": "Rogerio", + "last_name": "Bellworthy", + "email": "rbellworthy1d@freewebs.com", + "gender": "Male", + "birthday": "7/1/2009" + }, + { + "first_name": "Dwayne", + "last_name": "Cypler", + "email": "dcypler1e@rakuten.co.jp", + "gender": "Male", + "birthday": "4/2/2007" + }, + { + "first_name": "Andres", + "last_name": "Joy", + "email": "ajoy1f@slashdot.org", + "gender": "Male", + "birthday": "7/16/1999" + }, + { + "first_name": "Roxanne", + "last_name": "Alflatt", + "email": "ralflatt1g@google.com.hk", + "gender": "Female", + "birthday": "8/6/2003" + }, + { + "first_name": "Pearla", + "last_name": "Heggs", + "email": "pheggs1h@nifty.com", + "gender": "Female", + "birthday": "1/9/1999" + }, + { + "first_name": "Gillie", + "last_name": "Khristoforov", + "email": "gkhristoforov1i@cloudflare.com", + "gender": "Female", + "birthday": "3/30/1991" + }, + { + "first_name": "Kelly", + "last_name": "Millions", + "email": "kmillions1j@springer.com", + "gender": "Male", + "birthday": "1/28/2007" + }, + { + "first_name": "Wenda", + "last_name": "Duxbarry", + "email": "wduxbarry1k@netvibes.com", + "gender": "Female", + "birthday": "5/9/2017" + }, + { + "first_name": "Madelyn", + "last_name": "Blowen", + "email": "mblowen1l@virginia.edu", + "gender": "Female", + "birthday": "8/6/1983" + }, + { + "first_name": "Glen", + "last_name": "MacCheyne", + "email": "gmaccheyne1m@amazon.de", + "gender": "Male", + "birthday": "6/20/1995" + }, + { + "first_name": "Sheilah", + "last_name": "Middleton", + "email": "smiddleton1n@ifeng.com", + "gender": "Female", + "birthday": "10/15/1983" + }, + { + "first_name": "Sergei", + "last_name": "L'oiseau", + "email": "sloiseau1o@ebay.co.uk", + "gender": "Male", + "birthday": "5/6/1993" + }, + { + "first_name": "Stearne", + "last_name": "Bulfield", + "email": "sbulfield1p@yale.edu", + "gender": "Male", + "birthday": "8/23/2014" + }, + { + "first_name": "Eudora", + "last_name": "Scurman", + "email": "escurman1q@fastcompany.com", + "gender": "Female", + "birthday": "6/15/1991" + }, + { + "first_name": "Devon", + "last_name": "Blades", + "email": "dblades1r@example.com", + "gender": "Female", + "birthday": "2/27/1990" + }, + { + "first_name": "Any", + "last_name": "Oppery", + "email": "aoppery1s@github.com", + "gender": "Male", + "birthday": "7/1/2019" + }, + { + "first_name": "Peg", + "last_name": "Kuna", + "email": "pkuna1t@gov.uk", + "gender": "Female", + "birthday": "2/10/2011" + }, + { + "first_name": "Livy", + "last_name": "Dunbar", + "email": "ldunbar1u@so-net.ne.jp", + "gender": "Female", + "birthday": "7/27/2000" + }, + { + "first_name": "Nico", + "last_name": "Zeal", + "email": "nzeal1v@shutterfly.com", + "gender": "Male", + "birthday": "4/16/2012" + }, + { + "first_name": "Thain", + "last_name": "Wilfinger", + "email": "twilfinger1w@csmonitor.com", + "gender": "Male", + "birthday": "7/13/2011" + }, + { + "first_name": "Michaelina", + "last_name": "Itzakovitz", + "email": "mitzakovitz1x@privacy.gov.au", + "gender": "Female", + "birthday": "1/1/2003" + }, + { + "first_name": "Regina", + "last_name": "Govini", + "email": "rgovini1y@skyrock.com", + "gender": "Female", + "birthday": "12/15/2001" + }, + { + "first_name": "Granny", + "last_name": "Clewarth", + "email": "gclewarth1z@uiuc.edu", + "gender": "Male", + "birthday": "4/28/1984" + }, + { + "first_name": "Maynord", + "last_name": "Syce", + "email": "msyce20@mac.com", + "gender": "Male", + "birthday": "4/14/1990" + }, + { + "first_name": "Lamont", + "last_name": "Bardell", + "email": "lbardell21@typepad.com", + "gender": "Male", + "birthday": "12/12/1991" + }, + { + "first_name": "Micky", + "last_name": "Huckerbe", + "email": "mhuckerbe22@princeton.edu", + "gender": "Female", + "birthday": "10/9/2013" + }, + { + "first_name": "Noe", + "last_name": "McDowall", + "email": "nmcdowall23@netvibes.com", + "gender": "Male", + "birthday": "8/14/1996" + }, + { + "first_name": "Shelby", + "last_name": "Tenbrug", + "email": "stenbrug24@diigo.com", + "gender": "Male", + "birthday": "12/2/1983" + }, + { + "first_name": "Pauline", + "last_name": "Satyford", + "email": "psatyford25@theatlantic.com", + "gender": "Female", + "birthday": "11/4/2001" + }, + { + "first_name": "Beckie", + "last_name": "Edinburough", + "email": "bedinburough26@mozilla.com", + "gender": "Female", + "birthday": "6/13/2013" + }, + { + "first_name": "Brandie", + "last_name": "Geraudel", + "email": "bgeraudel27@admin.ch", + "gender": "Female", + "birthday": "7/31/1997" + }, + { + "first_name": "Joshia", + "last_name": "Marini", + "email": "jmarini28@oakley.com", + "gender": "Male", + "birthday": "10/10/2003" + }, + { + "first_name": "Hallsy", + "last_name": "Labes", + "email": "hlabes29@clickbank.net", + "gender": "Male", + "birthday": "8/4/1982" + }, + { + "first_name": "Sara-ann", + "last_name": "Melia", + "email": "smelia2a@globo.com", + "gender": "Female", + "birthday": "3/7/2018" + }, + { + "first_name": "Auguste", + "last_name": "Levane", + "email": "alevane2b@unblog.fr", + "gender": "Female", + "birthday": "5/25/1980" + }, + { + "first_name": "Bink", + "last_name": "Dablin", + "email": "bdablin2c@hp.com", + "gender": "Male", + "birthday": "11/19/1994" + }, + { + "first_name": "Paulie", + "last_name": "Burkill", + "email": "pburkill2d@imdb.com", + "gender": "Female", + "birthday": "1/29/2002" + }, + { + "first_name": "Esma", + "last_name": "Ramsey", + "email": "eramsey2e@wikia.com", + "gender": "Female", + "birthday": "3/19/2011" + }, + { + "first_name": "Rosamond", + "last_name": "Harower", + "email": "rharower2f@de.vu", + "gender": "Female", + "birthday": "5/19/1992" + }, + { + "first_name": "Ileana", + "last_name": "Krebs", + "email": "ikrebs2g@technorati.com", + "gender": "Female", + "birthday": "4/2/1982" + }, + { + "first_name": "Bradney", + "last_name": "Hardern", + "email": "bhardern2h@pagesperso-orange.fr", + "gender": "Male", + "birthday": "9/5/1995" + }, + { + "first_name": "Taylor", + "last_name": "Woodcock", + "email": "twoodcock2i@wiley.com", + "gender": "Male", + "birthday": "6/27/1995" + }, + { + "first_name": "Rudyard", + "last_name": "Lamba", + "email": "rlamba2j@un.org", + "gender": "Male", + "birthday": "2/6/1989" + }, + { + "first_name": "Tobit", + "last_name": "Pogue", + "email": "tpogue2k@blogtalkradio.com", + "gender": "Male", + "birthday": "12/26/1998" + }, + { + "first_name": "Matilde", + "last_name": "Picopp", + "email": "mpicopp2l@posterous.com", + "gender": "Female", + "birthday": "2/4/2010" + }, + { + "first_name": "Ilaire", + "last_name": "Calken", + "email": "icalken2m@time.com", + "gender": "Male", + "birthday": "6/10/2014" + }, + { + "first_name": "Reuben", + "last_name": "Thebes", + "email": "rthebes2n@sourceforge.net", + "gender": "Male", + "birthday": "1/23/1998" + }, + { + "first_name": "Orland", + "last_name": "Koubek", + "email": "okoubek2o@jiathis.com", + "gender": "Male", + "birthday": "2/18/1998" + }, + { + "first_name": "Killie", + "last_name": "McIlmorow", + "email": "kmcilmorow2p@cdc.gov", + "gender": "Male", + "birthday": "7/8/2017" + }, + { + "first_name": "Blaire", + "last_name": "Harbin", + "email": "bharbin2q@sbwire.com", + "gender": "Female", + "birthday": "12/14/2012" + }, + { + "first_name": "Babb", + "last_name": "Baily", + "email": "bbaily2r@jalbum.net", + "gender": "Female", + "birthday": "4/23/1981" + } +] diff --git a/legacy/databases/lesson3/MongoDB/subjects.json b/legacy/databases/lesson3/MongoDB/subjects.json new file mode 100644 index 00000000..f8788296 --- /dev/null +++ b/legacy/databases/lesson3/MongoDB/subjects.json @@ -0,0 +1,12 @@ +[ + { "name": "SQL" }, + { "name": "NoSQL" }, + { "name": "JavaScript" }, + { "name": "NODE.JS" }, + { "name": "GIT" }, + { "name": ".NET" }, + { "name": "HTML" }, + { "name": "CSS3" }, + { "name": "PHP" }, + { "name": "Python" } +] diff --git a/legacy/databases/lesson3/MongoDB/teachers.json b/legacy/databases/lesson3/MongoDB/teachers.json new file mode 100644 index 00000000..377c70cd --- /dev/null +++ b/legacy/databases/lesson3/MongoDB/teachers.json @@ -0,0 +1,72 @@ +[ + { + "first_name": "Michal", + "last_name": "Ledger", + "email": "mledger0@harvard.edu", + "gender": "Female", + "birthday": "5/24/2011" + }, + { + "first_name": "Krystal", + "last_name": "Goadbie", + "email": "kgoadbie1@yandex.ru", + "gender": "Female", + "birthday": "6/28/1987" + }, + { + "first_name": "Bili", + "last_name": "Ridsdale", + "email": "bridsdale2@bizjournals.com", + "gender": "Female", + "birthday": "11/17/1992" + }, + { + "first_name": "Ula", + "last_name": "Belcham", + "email": "ubelcham3@aboutads.info", + "gender": "Female", + "birthday": "10/8/1980" + }, + { + "first_name": "Thorsten", + "last_name": "Kingsman", + "email": "tkingsman4@clickbank.net", + "gender": "Male", + "birthday": "4/22/2012" + }, + { + "first_name": "Bryan", + "last_name": "Stennett", + "email": "bstennett5@usgs.gov", + "gender": "Male", + "birthday": "1/25/1986" + }, + { + "first_name": "Charley", + "last_name": "Sallarie", + "email": "csallarie6@usnews.com", + "gender": "Male", + "birthday": "11/15/1981" + }, + { + "first_name": "Grady", + "last_name": "Robertelli", + "email": "grobertelli7@sourceforge.net", + "gender": "Male", + "birthday": "6/25/2017" + }, + { + "first_name": "Merrily", + "last_name": "McDermot", + "email": "mmcdermot8@latimes.com", + "gender": "Female", + "birthday": "1/3/1997" + }, + { + "first_name": "Mendie", + "last_name": "Sinclar", + "email": "msinclar9@businessinsider.com", + "gender": "Male", + "birthday": "12/12/2006" + } +] diff --git a/legacy/databases/lesson3/README.md b/legacy/databases/lesson3/README.md new file mode 100644 index 00000000..fd4c9f4b --- /dev/null +++ b/legacy/databases/lesson3/README.md @@ -0,0 +1,123 @@ +# Lesson 3: Security and Non-Relational Databases + +In the final week, the students will be introduced to SQL injections and common security practices around MySQL permissions. MongoDB, as an example of a non-relational database, will also be introduced, as well as the benefits and drawbacks of relational and non-relational models. + +Objective: the students should know how SQL injections happen, and how to define user permissions in MySQL to limit the potential damage that can be done with a SQL injection. The students should also be able to compare and contrast relational (like MySQL) and NoSQL databases (considering their benefits and drawbacks). + +## Pre-Class Readings + +Please read the following pages that explains the ACID database model: + +- [ACID Properties with real life examples](https://medium.com/%40tushar.rooks/acid-properties-with-real-life-examples-b83a37667338) +- [Why you should never use MongoDB](http://www.sarahmei.com/blog/2013/11/11/why-you-should-never-use-mongodb) + +Also the students should watch this video: + +## Main Topics + +- Security + - SQL Injection + - User GRANTS +- Introduction to non-relational data with MongoDB + - MongoDB vs. SQL + - Create/Drop database + - Insert/Update/Delete data + - Query data + - Relationships: embedded vs. referenced + - Replication and sharding + - Atomicity +- [Advanced database schema exercise](social_media_exercise.md) + +## Reference Material + +- [OWASP on SQL Injection](https://owasp.org/www-community/attacks/SQL_Injection) +- [Parameter Validation on Wikipedia](https://en.wikipedia.org/wiki/Parameter_validation) +- [Node MySQL Escaping Query Values](https://github.com/mysqljs/mysql#escaping-query-values) +- [Node MySQL Preparing Queries (automatic escaping)](https://github.com/mysqljs/mysql#preparing-queries) +- [MySQL SHOW GRANTS](https://dev.mysql.com/doc/refman/8.0/en/show-grants.html) + +## Homework + +### Start the homework + +Need to brush up on the homework setup process? Check [this](https://github.com/HackYourFuture-CPH/Git/blob/main/homework-submission.md) out before you get into some git confusion! + +### The task + +For the homework this week we will create the database and queries for an application we will continue working on in the [node js class](https://github.com/HackYourFuture-CPH/node.js). + +For those who haven't finished this part of the homework last week, now it's the time to finish :) + +The application will be a meal sharing website, where users can book a reservation at a meal another user has created. + +So as a user you can both + +- Create a new meal for people to join +- Book a reservation at a meal + +It will be kind of similar to this website: + +#### Data model + +Lets first start with creating the data model. + +Create all the sql for creating this data model: + +#### Queries + +Create these queries + +#### Meal + +| Queries to write | +| ----------------------------------------------------------------------------------------- | +| Get all meals | +| Add a new meal | +| Get a meal with any id, fx 1 | +| Update a meal with any id, fx 1. Update any attribute fx the title or multiple attributes | +| Delete a meal with any id, fx 1 | + +#### Reservation + +| Queries to write | +| ------------------------------------------------------------------------------------------------ | +| Get all reservations | +| Add a new reservation | +| Get a reservation with any id, fx 1 | +| Update a reservation with any id, fx 1. Update any attribute fx the title or multiple attributes | +| Delete a reservation with any id, fx 1 | + +#### Review + +| Queries to write | +| ------------------------------------------------------------------------------------------- | +| Get all reviews | +| Add a new review | +| Get a review with any id, fx 1 | +| Update a review with any id, fx 1. Update any attribute fx the title or multiple attributes | +| Delete a review with any id, fx 1 | + +#### Additional queries + +Now add a couple of different meals, reservations and reviews with different attributes. With those meals create the following queries + +| Functionality | +| -------------------------------------------------------------------------------------------------------------- | +| Get meals that has a price smaller than a specific price fx 90 | +| Get meals that still has available reservations | +| Get meals that partially match a title. `RΓΈd grΓΈd med` will match the meal with the title `RΓΈd grΓΈd med flΓΈde` | +| Get meals that has been created between two dates | +| Get only specific number of meals fx return only 5 meals | +| Get the meals that have good reviews | +| Get reservations for a specific meal sorted by created_date | +| Sort all meals by average number of stars in the reviews | + +### Hand in homework + +Need to brush up on the homework hand-in process? + +Check [this resource](https://github.com/HackYourFuture-CPH/Git/blob/main/homework-submission.md) to remember how to hand in the homework correctly! + +### Feedback + +And finally, please take two minutes to answer the survey [here](https://forms.gle/rDdPxPGW4piDuktLA) to give feedback to the staff and mentors. diff --git a/legacy/databases/lesson3/node_sql_injection_example/.gitignore b/legacy/databases/lesson3/node_sql_injection_example/.gitignore new file mode 100644 index 00000000..b8bb0097 --- /dev/null +++ b/legacy/databases/lesson3/node_sql_injection_example/.gitignore @@ -0,0 +1,3 @@ +!.gitignore +node_modules/ +config-secret.json diff --git a/legacy/databases/lesson3/node_sql_injection_example/README.md b/legacy/databases/lesson3/node_sql_injection_example/README.md new file mode 100644 index 00000000..9acb4d78 --- /dev/null +++ b/legacy/databases/lesson3/node_sql_injection_example/README.md @@ -0,0 +1,29 @@ +# SQL Injection Example App + +## How to run it + +- Run the SQL in `injection_db_schema.sql`. +- Install dependencies using `npm install` or `yarn install`. +- Copy `config-secret.json.dist` to `config-secret.json`. +- Run the server using `node server.js`, `npm start` or `yarn start`. +- Visit in your browser. + +## Try it out + +The DB has one user with email `foo@example.com` and password `password`. +Try logging in with this user to see that it works as expected. + +Now try injecting some SQL by writing something like this in the email field: + +```text +foo@example.com' OR 1 = 1; -- +``` + +**Note**: It is important to end the input with a space after the two dashes! +For the password you can just put in a random string. + +Will result in this query: + +```sql +SELECT * FROM users WHERE email = 'foo@example.com' OR 1 = 1; -- ' AND password = '' +``` diff --git a/legacy/databases/lesson3/node_sql_injection_example/config-secret.json.dist b/legacy/databases/lesson3/node_sql_injection_example/config-secret.json.dist new file mode 100644 index 00000000..b387c935 --- /dev/null +++ b/legacy/databases/lesson3/node_sql_injection_example/config-secret.json.dist @@ -0,0 +1,7 @@ +{ + "host": "localhost", + "port": 3306, + "database": "injection_app", + "user": "injection_app", + "password": "injection123" +} diff --git a/legacy/databases/lesson3/node_sql_injection_example/injection_db_schema.sql b/legacy/databases/lesson3/node_sql_injection_example/injection_db_schema.sql new file mode 100644 index 00000000..0525a4cb --- /dev/null +++ b/legacy/databases/lesson3/node_sql_injection_example/injection_db_schema.sql @@ -0,0 +1,18 @@ +SET NAMES utf8mb4; + +CREATE DATABASE `injection_app` COLLATE utf8mb4_unicode_ci; + +CREATE USER 'injection_app'@'%' IDENTIFIED BY 'injection123'; +GRANT ALL PRIVILEGES ON `injection_app`.* TO 'injection_app'@'%'; +FLUSH PRIVILEGES; + +USE `injection_app`; + +CREATE TABLE `users` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + `name` VARCHAR(255) NOT NULL, + `email` VARCHAR(255) NOT NULL UNIQUE KEY, + `password` VARCHAR(255) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +INSERT INTO `users` (`name`, `email`, `password`) VALUES ('John Doe', 'foo@example.com', 'password'); diff --git a/legacy/databases/lesson3/node_sql_injection_example/package-lock.json b/legacy/databases/lesson3/node_sql_injection_example/package-lock.json new file mode 100644 index 00000000..5d9b6a7d --- /dev/null +++ b/legacy/databases/lesson3/node_sql_injection_example/package-lock.json @@ -0,0 +1,443 @@ +{ + "name": "node_sql_injection_example", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "bignumber.js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz", + "integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA==" + }, + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.1", + "http-errors": "~1.6.2", + "iconv-lite": "0.4.19", + "on-finished": "~2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "~1.6.15" + } + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.16.3", + "resolved": "http://registry.npmjs.org/express/-/express-4.16.3.tgz", + "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.2", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.3", + "qs": "6.5.1", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.1", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + } + } + }, + "finalhandler": { + "version": "1.1.1", + "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "http-errors": { + "version": "1.6.3", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipaddr.js": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", + "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "mime-db": { + "version": "1.36.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", + "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==" + }, + "mime-types": { + "version": "2.1.20", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", + "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", + "requires": { + "mime-db": "~1.36.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mysql": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.16.0.tgz", + "integrity": "sha512-dPbN2LHonQp7D5ja5DJXNbCLe/HRdu+f3v61aguzNRQIrmZLOeRoymBYyeThrR6ug+FqzDL95Gc9maqZUJS+Gw==", + "requires": { + "bignumber.js": "4.1.0", + "readable-stream": "2.3.6", + "safe-buffer": "5.1.2", + "sqlstring": "2.3.1" + } + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "proxy-addr": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", + "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.8.0" + } + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": ">= 1.3.1 < 2" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + } + } +} diff --git a/legacy/databases/lesson3/node_sql_injection_example/package.json b/legacy/databases/lesson3/node_sql_injection_example/package.json new file mode 100644 index 00000000..5c6a891e --- /dev/null +++ b/legacy/databases/lesson3/node_sql_injection_example/package.json @@ -0,0 +1,16 @@ +{ + "name": "node_sql_injection_example", + "version": "1.0.0", + "description": "", + "main": "server.js", + "scripts": { + "start": "node server.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "express": "^4.16.3", + "mysql": "^2.16.0" + } +} diff --git a/legacy/databases/lesson3/node_sql_injection_example/public/index.html b/legacy/databases/lesson3/node_sql_injection_example/public/index.html new file mode 100644 index 00000000..7c319d26 --- /dev/null +++ b/legacy/databases/lesson3/node_sql_injection_example/public/index.html @@ -0,0 +1,92 @@ + + + + + + + + + + + Login + + + + + + + diff --git a/legacy/databases/lesson3/node_sql_injection_example/public/secret.html b/legacy/databases/lesson3/node_sql_injection_example/public/secret.html new file mode 100644 index 00000000..31f457ff --- /dev/null +++ b/legacy/databases/lesson3/node_sql_injection_example/public/secret.html @@ -0,0 +1,47 @@ + + + + + + + + + + + Login + + + + +
+

You're now logged in

+ +

+ Go back +

+
+ + diff --git a/legacy/databases/lesson3/node_sql_injection_example/public/wrong.html b/legacy/databases/lesson3/node_sql_injection_example/public/wrong.html new file mode 100644 index 00000000..59407661 --- /dev/null +++ b/legacy/databases/lesson3/node_sql_injection_example/public/wrong.html @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + Login + + + + +
+

The email or password was incorrect

+
+ + diff --git a/legacy/databases/lesson3/node_sql_injection_example/server.js b/legacy/databases/lesson3/node_sql_injection_example/server.js new file mode 100644 index 00000000..692d6afe --- /dev/null +++ b/legacy/databases/lesson3/node_sql_injection_example/server.js @@ -0,0 +1,69 @@ +const path = require("path"); +const express = require("express"); +const bodyParser = require("body-parser"); +const fs = require("fs"); +const mysql = require("mysql"); + +const app = express(); +const port = 3000; + +const config = JSON.parse(fs.readFileSync("config-secret.json")); + +const connection = mysql.createConnection({ + host: config.host, + user: config.user, + password: config.password, + port: config.port, + database: config.database, +}); + +connection.connect((err) => { + if (err) throw err; +}); + +app.use(bodyParser.urlencoded({ extended: false })); +app.use(express.static(path.join(__dirname, "public"))); + +app.post("/login", (req, res, next) => { + console.log(req.body); + + // Bad (vulnerable to injection) + // Try this in the email field: "foo@example.com' OR 1 = 1; -- " + // Will result in this query: "SELECT * FROM users WHERE email = 'foo@example.com' OR 1 = 1; -- ' AND password = ''" + connection.query( + `SELECT * FROM users WHERE email = '${req.body.email}' AND password = '${req.body.password}'`, + (err, result, fields) => { + if (err) { + next(err); + return; + } + + if (result && result.length == 1) { + console.log(result[0]); + res.redirect("/secret.html"); + return; + } + res.redirect("/wrong.html"); + }, + ); + + // Good (uses implicit escaping to avoid SQL injections) + // connection.query('SELECT * FROM users WHERE email = ? AND password = ?', [ + // req.body.email, + // req.body.password, + // ], (err, result, fields) => { + // if (err) { + // next(err); + // return; + // } + + // if (result && result.length == 1) { + // console.log(result[0]); + // res.redirect('/secret.html'); + // return; + // } + // res.redirect('/wrong.html'); + // }); +}); + +app.listen(port, () => console.log(`Example app listening on port ${port}!`)); diff --git a/legacy/databases/lesson3/node_sql_injection_example/troubleshooting.md b/legacy/databases/lesson3/node_sql_injection_example/troubleshooting.md new file mode 100644 index 00000000..61c456e9 --- /dev/null +++ b/legacy/databases/lesson3/node_sql_injection_example/troubleshooting.md @@ -0,0 +1,21 @@ +# Troubleshooting + +If the server does not start and gives authentication errors as below: + +```text +Error: 1251 - Client does not support authentication protocol requested by server; consider upgrading MySQL client +``` + +Then, you need to update the user using the following SQL commands: + +```sql +DROP USER 'injection_app'@'localhost'; +// OR +DROP USER 'injection_app'@'%'; + +// Re-create user with different authentication plugin +CREATE USER 'injection_app'@'localhost' IDENTIFIED WITH mysql_native_password BY 'injection123'; + +// Re-grant permissions +GRANT ALL PRIVILEGES ON injection_app.* TO 'injection_app'@'localhost'; +``` diff --git a/legacy/databases/lesson3/preparation_flipped_classroom.md b/legacy/databases/lesson3/preparation_flipped_classroom.md new file mode 100644 index 00000000..6ec12c3a --- /dev/null +++ b/legacy/databases/lesson3/preparation_flipped_classroom.md @@ -0,0 +1,35 @@ +# Preparation for (semi) flipped classroom + +This is the preparation for the (semi) flipped classroom (vs. "old style" presential classes). + +We say (semi) flipped classroom, because part of the teaching is still done on the Sunday class. + +## Class videos + +Since this is a semi flipped classroom, where you prepare the class during the week and then the teaching on Sunday will build on what you prepared, it is important that you watch the following videos: + +- [SQL vs NoSQL or MySQL vs MongoDB](https://www.youtube.com/watch?v=ZS_kXvOeQ5Y) +- [MongoDB Complete Introduction & Summary](https://www.youtube.com/watch?v=VELru-FCWDM) (up to minute 32) + +The last video is not totally up to date, the configuration of the mongo atlas looks a bit different, but it should work fine still. And the good part is that it no longer requires a credit card at all to use mongo atlas. + +And if you want to experiment more with mongoDB commands, you can check [these tutorials](https://www.tutorialspoint.com/mongodb/index.htm). + +## Readings + +- [ACID Properties with real life examples](https://medium.com/%40tushar.rooks/acid-properties-with-real-life-examples-b83a37667338) +- [Why you should never use MongoDB](http://www.sarahmei.com/blog/2013/11/11/why-you-should-never-use-mongodb) + +## Exercise before class + +There is no real exercise this time, just come ready to discuss what are the pros and cons of noSQL and SQL, and when to use SQL vs. noSQL. + +## Checklist + +You are ready for Sunday's class if: + +- you have watched the `Class videos`; +- you have read the articles under `Readings`; +- you know when to use SQL and when to use noSQL. + +If you run into trouble completing any of the above, please ask for help in the class channel :) diff --git a/legacy/databases/lesson3/social_media_exercise.md b/legacy/databases/lesson3/social_media_exercise.md new file mode 100644 index 00000000..b7d3849e --- /dev/null +++ b/legacy/databases/lesson3/social_media_exercise.md @@ -0,0 +1,58 @@ +# HackYourFuture Social Media Website + +## The task + +You have to design a database schema for a social media website for HackYourFuture. + +You should create the database schema (a SQL file with `CREATE TABLE` statements) and an ER diagram (pdf or png). + +Think carefully about the types of relations and keys you will need. + +It's a good idea to also provide some example data (`INSERT INTO` statements) in order to verify that the schema works like you expect. + +If you have extra time you can expand on the list of entities. What else could be stored in a social media database? + +## List of entities + +### User + +- Name +- Email +- Password +- Registration datetime + +### Post + +- Title +- Content +- Creation datetime +- Update datetime +- Relation to author + +### Comment + +- Content +- Creation datetime +- Update datetime +- Relation to author +- Relation to post +- Relation to optional parent comment + +### Reaction + +Types of reactions: + +- like +- highfive +- laugh +- cry + +It should be possible to react to posts and comments. + +It should be possible for a user to react to the same thing with multiple reaction types, eg. "like" and "laugh" on the same post. + +It should however **not** be possible for a user to react to something with the same reaction type more than once. + +### Friendship + +Fx: User 1 is friends with user 2 diff --git a/legacy/databases/lesson3/sql_injection_js_example/sql-injection.js b/legacy/databases/lesson3/sql_injection_js_example/sql-injection.js new file mode 100644 index 00000000..7110cb14 --- /dev/null +++ b/legacy/databases/lesson3/sql_injection_js_example/sql-injection.js @@ -0,0 +1,52 @@ +var prompt = require("prompt"); +var mysql = require("mysql"); +const util = require("util"); + +// Make sure that the DB 'company' is created with the following credentials +// Make sure that the employees table is created with employee_id as one of the columns +// Uncomment the lines followed by the comments that start with numbers +// 1, 2 and 3 to demonstrate the naive way of passing parameters and +// escaping of parameters +// Run this file with node sql-injection.js on the (VScode) terminal. + +const connection = mysql.createConnection({ + host: "localhost", + user: "hyfuser", + password: "hyfpassword", + database: "company", + multipleStatements: false, +}); + +const execQuery = util.promisify(connection.query.bind(connection)); +const input = util.promisify(prompt.get.bind(this)); + +async function queryDatabase() { + var input_number = ""; + prompt.start(); + try { + const result = await input(["employee_number"]); + input_number = result.employee_number; + + // 1. Naive way of passing the parameter to the query + //const select_query = `select * from employees WHERE employee_id = ${input_number};` + + // 2. Escaping the parameter ( replacing the unwanted characters) + //const select_query = `select * from employees WHERE employee_id =` + connection.escape(input_number); + + // 3. Using a question mark syntax to do the escaping + //const select_query = `select * from employees WHERE employee_id = ?` + + connection.connect(); + console.log(select_query); + const results = await execQuery(select_query, input_number); + for (r of results) { + console.log(r); + } + } catch (error) { + console.error(error); + } + + connection.end(); +} + +queryDatabase(); diff --git a/legacy/final-project/Example projects/Team 26 (Copenhagen)/HyF final project, team 26.pdf b/legacy/final-project/Example projects/Team 26 (Copenhagen)/HyF final project, team 26.pdf new file mode 100644 index 00000000..25905170 Binary files /dev/null and b/legacy/final-project/Example projects/Team 26 (Copenhagen)/HyF final project, team 26.pdf differ diff --git a/legacy/final-project/Example projects/Team 27 (Aarhus)/Atomic Learning Systems Company Document.pdf b/legacy/final-project/Example projects/Team 27 (Aarhus)/Atomic Learning Systems Company Document.pdf new file mode 100644 index 00000000..f3809c24 Binary files /dev/null and b/legacy/final-project/Example projects/Team 27 (Aarhus)/Atomic Learning Systems Company Document.pdf differ diff --git a/legacy/final-project/Example projects/Team 27 (Aarhus)/Final project guide Atomic Learning.pdf b/legacy/final-project/Example projects/Team 27 (Aarhus)/Final project guide Atomic Learning.pdf new file mode 100644 index 00000000..010d3abd Binary files /dev/null and b/legacy/final-project/Example projects/Team 27 (Aarhus)/Final project guide Atomic Learning.pdf differ diff --git a/legacy/final-project/Example projects/Team 27 (Aarhus)/Final project guide Kazboo.pdf b/legacy/final-project/Example projects/Team 27 (Aarhus)/Final project guide Kazboo.pdf new file mode 100644 index 00000000..ea496618 Binary files /dev/null and b/legacy/final-project/Example projects/Team 27 (Aarhus)/Final project guide Kazboo.pdf differ diff --git a/legacy/final-project/Example projects/Team 27 (Aarhus)/Kazboo Company Document.pdf b/legacy/final-project/Example projects/Team 27 (Aarhus)/Kazboo Company Document.pdf new file mode 100644 index 00000000..61cc7fde Binary files /dev/null and b/legacy/final-project/Example projects/Team 27 (Aarhus)/Kazboo Company Document.pdf differ diff --git a/legacy/final-project/README.md b/legacy/final-project/README.md new file mode 100644 index 00000000..a180cf3f --- /dev/null +++ b/legacy/final-project/README.md @@ -0,0 +1,75 @@ +# Final Project + +This repository contains information about the final module of the program, where you will take everything you have learned so far and work together as a team to build a final project together. + +This module usually runs for 4-5 weeks. + +The final project is organised differently for each team, depending on the team responsible, mentors and the opportunities available at the time. The options could include: + +1. Mentor-designed projects and built using [HYF Project Template](https://github.com/HackYourFuture-CPH/hyf-project-template) +2. Trainee-proposed projects (e.g. [example project proposal](https://docs.google.com/document/d/11my-sb4T3UziIhjJlYOi60Afxq2dUncE8WYZ8yA-HCY/edit?tab=t.0#heading=h.ik8don4y6sav)) and built using [HYF Project Template](https://github.com/HackYourFuture-CPH/hyf-project-template) +3. Client-driven projects designed in collaboration with a real client partner, built using their own template. + +## Learning Goals + +- [ ] Collaboration in a team setting + - [ ] Learn to read and extend or improve other peoples code + - [ ] Learn to give/receive PR feedback + - [ ] Learn to plan and communicate technical solutions upfront before implementing +- [ ] Develop self-guided learning skills (e.g. learn to read documetation for a framework or API) +- [ ] Interpreting wireframes/prototypes into requirements +- [ ] Breaking bigger problems into smaller written tasks +- [ ] Working in sprints with deadlines +- [ ] Asking for help effectively and at the right time (e.g. describing problems to mentors, asking online, and the power _and_ limitations of ChatGPT) +- [ ] Deploying a completed project you are proud to showcase on your portfolio + +## Technical Requirements + +### Authentication & Authorization + +- Team code generation and validation +- Basic access control _- Permissions to restrict user access depending on who they are_ +- Session management _- Maintain user state during their use of the app_ + +### Data Validation + +- Input sanitization _- Ensure all user input is cleaned to prevent security vulnerabilities_ +- Form validation _- Validate user inputs to make sure they fit any specific criteria you have (e.g. strong passwords)_ +- Error handling _- Provide feedback on inputs if something isn't right_ + +### API Development + +- RESTful endpoints _- Implement endpoints that adhere to REST principles_ +- Request/response handling _- Handle both making requests and handling their responses sufficiently_ +- Error responses _- Handle errors from the API (e.g. informing the client, updating the UI appropriately)_ + +### Database Operations + +- CRUD operations _- Create, Read, Update and Delete functions to manage your data_ +- Relationship handling _- Define and manage appropriate relationships between your data objects_ +- Data integrity _- Ensure accuracy and consistency of your data (e.g. constraints, validation)_ + +### UI/UX Requirements + +- Responsive design _- A layout that adapts to different screen sizes_ +- Form handling _- User friendly user input and submission flows_ +- Loading states _- Visual indicators when content is not fully loaded_ +- Error states _- User friendly, actionable feedback when something goes wrong_ +- Success feedback _- Positive feedback when things are going to plan_ + +## Examples of previous final projects + +### Team 27 (Aarhus) + +They had the opportunity to work with two real clients. So the team was split into two 7 person teams, and worked together on these proposals: + +1. Atomic Learning Systems - [Intro](), [Proposal](), [Live demo](https://atomic-learning-systems-hackyourfuture.onrender.com/), [Final code](https://github.com/Atomic-learning-systems/HackYourFuture) +2. Kazboo - [Intro](), [Proposal](), [Live demo](https://class27-kazboo.onrender.com/), [Final code](https://github.com/HackYourFuture-CPH/class27-kazboo) + +### Team 26 (Copenhagen) + +They had three teams & projects to choose from, all within the theme of "Team Health" ([Intro]()) + +1. Project Time Off - [Proposal](https://docs.google.com/document/d/1tUi1yoeFimWNUutzhFSSY4ikA48b9nqoC4SZK3_CDU4/edit?pli=1#heading=h.wnv93ls3sa69), [Live demo](https://time-off-nu.vercel.app/), [Final code](https://github.com/HackYourFuture-CPH/team26-TimeOff_App) +2. Project Check-In - [Proposal](https://docs.google.com/document/d/1tUi1yoeFimWNUutzhFSSY4ikA48b9nqoC4SZK3_CDU4/edit?pli=1#heading=h.rzut036l9gqb), ~~Live demo~~, [Final code](https://github.com/HackYourFuture-CPH/team26-checkin) +3. Project Retro - [Proposal](https://docs.google.com/document/d/1tUi1yoeFimWNUutzhFSSY4ikA48b9nqoC4SZK3_CDU4/edit?pli=1#heading=h.6t89f52sg6x), ~~Live demo~~, [Final code](https://github.com/HackYourFuture-CPH/team26-RetroRealm) diff --git a/legacy/git/README.md b/legacy/git/README.md new file mode 100644 index 00000000..617c6702 --- /dev/null +++ b/legacy/git/README.md @@ -0,0 +1,16 @@ +# Git + +This repository contains the course material for the Git modules :octocat:. + +Git course was first introduced in the Hack Your Future (HYF henceforth) in September 2016. We think that learning Git is one of the useful skills to become a successful and efficient software engineer. The aim of this course is to learn the basics of Git and not to be an expert. Both Git1 and Git2 are designed to be run as one session each. + +We want to use this repository as an archive of course material (slides/tutorials), useful resources, teaching ideas etc. + +Also check out our Git [playlist](https://www.youtube.com/playlist?list=PLVYDhqbgYpYUGxRdtQdYVE5Q8h3bt6SIA) for tutorials + +| Module | Learning goals | Preparation | Lesson Plan | Homework | +| ------ | -------------------------------------------------------------------- | ------------------------------------ | ------------------------------------ | ------------------------------ | +| 1. | Introduction to Git; Git vs GitHub; Pull Requests; Commits; Branches | [Preparation](./git1/preparation.md) | [Lesson Plan](./git1/lesson_plan.md) | [Homework](./git1/homework.md) | +| 2. | Advanced Git and Preparation for the Final Project | [Preparation](./git2/preparation.md) | [Lesson Plan](./git2/lesson_plan.md) | [Homework](./git2/homework.md) | + +Please check the material shared on Preparation, Lesson Plan and Homework ⬆️ diff --git a/legacy/git/git1/GIt_branches.pdf b/legacy/git/git1/GIt_branches.pdf new file mode 100644 index 00000000..169c55d5 Binary files /dev/null and b/legacy/git/git1/GIt_branches.pdf differ diff --git a/legacy/git/git1/Git_basics.pdf b/legacy/git/git1/Git_basics.pdf new file mode 100644 index 00000000..aa8f200c Binary files /dev/null and b/legacy/git/git1/Git_basics.pdf differ diff --git a/legacy/git/git1/cheatsheet.md b/legacy/git/git1/cheatsheet.md new file mode 100644 index 00000000..9539461c --- /dev/null +++ b/legacy/git/git1/cheatsheet.md @@ -0,0 +1,54 @@ +# Cheat sheet + +Here are the commands we used in the class (and a few more) and their meaning. + +## Command line + +- `pwd` - stands for 'print working directory' and you use it to know in which directory you are. +- `cd ` - stands for 'change directory', and you use it to go inside `folder_name`. +- `cd ..` - to go to the parent folder of your current folder. +- `mkdir ` - stands for 'make directory' and you use it to create a new folder with `folder name`. +- `ls` - stands for 'list' and you use it list all the folder contents. +- `ls .*` - list all the folder contents, also invisible folders/files (e.g. the .git folder). +- `rm ` - THIS IS DANGEROUS!!! It removes the file named `file_name` FOREVER, you can NEVER recover it. + +To remove a git repository but still keep your files do `rm -rf .git` in the folder where you have the repository. All the git information is lost when you do this. + +## Git + +### Part 1 + +We used these commands in the first part of the class to work with a local git repository on our own computers. + +- `git add ` - tells git to start tracking a file or to update what will be commited. Always do that before `git commit`. +- `git commit -m "commit_message"` - commit your changes. +- `git push origin ` - push (upload) your changes in your current branch to your github repository into the branch named ``. +- `git status` - shows you which files are ready to be commited, or not tracked by git. Often tells you what to do as well. It is your best friend when using git :) +- `git log` - shows the history of commits in the current branch. +- `git log --oneline` - shows the history of commits in the current branch in a single line per commit. +- `git diff ` - to see the difference between the file contents now and in the latest commit. + +Note: if you do `git add .` instead of `git add ` you will add all files in your current folder. + +### Part 2 + +We used these commands in the second part of the class to create a branch, go to it, commit our changes on that branch, and then push it to Github. + +- `git branch ` - create a new branch ``. +- `git checkout ` - go to branch ``. +- `git branch` - check which local branches you have and where you are (in green). +- `git push origin ` - push (upload) your local changes in your current branch into the branch named `branch_name` in your github repository. + +### Extras + +Commands we didn't use in class but that might be useful for you: + +- `git pull origin ` - pull (download) your changes from your github repository in the branch named ``, into your current local branch. +- `git checkout --file ` - use if you changed the file named `file_name` and want to revert the changes, i.e. to get back the version you had in the last commit +- git + + **_Notes_** + + For the sake of consistency (and to avoid mistakes), make sure that when you push you do it to a branch with the same name as the branch where you are, e.g. if you are on a branch named `my_homework` then push to a branch named `my_homework` by typing `git push origin my_homework`. + + When pulling, if you want to pull from a branch named, for instance `git_homework`, make sure that you are in a branch with the same name (`git_homework`) on your computer as well, and only then do `git pull origin `. diff --git a/legacy/git/git1/class_exercises.md b/legacy/git/git1/class_exercises.md new file mode 100644 index 00000000..8c4d778b --- /dev/null +++ b/legacy/git/git1/class_exercises.md @@ -0,0 +1,106 @@ +# Class exercises + +## Exercise 1 + +We will use the homework repository and the branch `main`. + +It will be your own individual repository or the central homework repository of your class - depending on which approach you are using in your class. + +1. clone the homework repository into your computer. +2. when you are on `main` branch, create a branch named `git-week1/exercise_1/`\* and move to it; +3. create a folder named `class_playground` in the `git` folder, under `/week1`; +4. create the following files inside the `class_playground` folder: `apples_file.txt`, `bananas_file.txt`, `oranges_file.txt`; +5. add some text to each of the files; +6. add and commit the `apples_file.txt`; +7. add and commit both the `oranges_file.txt` and the `bananas_file.txt`; +8. add more text to the `apples_file.txt`; +9. add and commit the changes in the `apples_file.txt`; +10. push your changes to Github. +11. go to the branch on github and look at the commits, analyze and discuss how it looks and how it connects with what you just did. + +`*` `` should be replace by your actual name, f.x. `git/week1/exercise_1/maria` + +## Exercise 2 + +The goal of this exercise is to practice the homework workflow. +It will basically follow the second part of the class videos. + +1. when you are on `main` branch, create a branch named `git-week1/exercise_2/`\* and move to it; +2. create a file named `my_homework.txt` in the `git` folder, under `/week1/class_playground`; +3. add some text to the `my_homework.txt` file; +4. add and commit the changes in the `my_homework.txt` file; +5. add more text to the `my_homework.txt` file; +6. add and commit the changes in the `my_homework.txt` file; +7. push your changes to github; +8. on github, create a pull request from the exercis branch to `main`; +9. on your computer add some more text to the `my_homework.txt` file; +10. on your computer, add and commit the changes in the `my_homework.txt` file; +11. push the changes to github; +12. on github, check what happened to the pull request you created in step 8. +13. if you are on an individual homework repository approach, merge the PR and proceed to the next step. If you are on a central homework repository approach, DO NOT merge the PR, and skip the next step. +14. go to the `main` branch and update `main` by "downloading" the new commits from github: `git pull origin main`. + +`*` `` should be replace by your actual name, f.x. `git/week1/exercise_2/maria` + +## Exercise 3 + +In this exercise, you will get an error when pushing to github and you will have to solve it. + +1. on your homework repo go to the branch `main`, create a branch `git-week1/exercise_3/`\* and move to it; +2. in the `git` folder, under `/week1/class_playground`, create a file named `colors.txt`; +3. add two colors to the file `colors.txt`, one per line; +4. add and commit the changes in the `colors.txt` file; +5. push the branch `git_exercise_3` to github. +6. **on github**, go to the branch `git_exercise_3` and add a color in the last line of the file `colors.txt`, commit your changes; +7. **on your computer**, add a color in the first line of the file `colors.txt`, add and commit your changes; +8. push the branch `git_exercise_3` to github. Discuss what is happening and how to solve it. + +`*` `` should be replace by your actual name, f.x. `git/week1/exercise_3/maria` + +## Exercise 4 + +In this exercise you will get in trouble by checking out from the wrong branch you will have to solve it. + +1. on your homework repo **DON'T** go to the main branch, make sure to stay on the branch from the previous exercise. +2. create a branch `git/week1/exercise_4/`\* and move to it; +3. in the `git` folder, under `/week1/class_playground`, create a file named `movies.txt`; +4. add two movie names to the file `movies.txt`, one per line; +5. add and commit the changes in the `movies.txt` file; +6. push the branch `git_exercise_4` to github. +7. on github, create a pull request from your new branch to `main`. +8. see what commits you have there - do you only have commits from this exercise? Do you have commits that should not be here? Discuss why it happened and how to solve this situation. + +`*` `` should be replace by your actual name, f.x. `git/week1/exercise_4/maria` + +## Exercise 5 + +The goal of this exercise is to get more familiar with branches. + +Take notes of the answers to the questions in points 14, 15, 16, 17, 18, 19, 22, 23, 25, and 26. Discuss the answers in your breakout room. + +1. create a new folder in your Desktop called `branch_exercise`; +2. using the command line go to that folder and create a new repository there (`git init`); +3. create a new file in that folder called `countries.txt`; +4. add two country names (one per line) to the `countries.txt` file; +5. commit your changes; +6. create a new branch named `add_countries`, move to that branch; +7. add two more country names (one per line) to the `countries.txt` file; +8. commit your changes; +9. go back to `main`; +10. create a new branch named `add_cities`, move to that branch; +11. create a new file named `cities.txt`; +12. add two city names (one per line) to the `cities.txt` file; +13. commit your changes; +14. go back to `main` and take a look around your folder. Which files do you see? What are their contents? +15. do `git log --oneline`. Which commits do you see? +16. go to the `add_countries` branch and take a look around your folder. Which files do you see? What are their contents? +17. do `git log --oneline`. Which commits do you see? +18. go to the `add_cities` branch and again take a look around your folder. Which files do you see? What are their contents? +19. do git `log --oneline`. Which commits do you see? +20. now go to `main`; +21. merge the branch `add_countries` with main (`git merge add_countries`); +22. take a look at your folder, which files do you see? What are their contents? +23. do `git log --oneline`. Which commits do you see? +24. now merge the branch `add_cities` with main (`git merge add_cities`) +25. take a look at your folder, which files do you see? What are their contents? +26. do `git log --oneline`. Which commits do you see? diff --git a/legacy/git/git1/homework.md b/legacy/git/git1/homework.md new file mode 100644 index 00000000..b0f9374e --- /dev/null +++ b/legacy/git/git1/homework.md @@ -0,0 +1,69 @@ +# Homework + +## Exercise 1 + +In this exercise you will get some practice submitting your homework by pushing it to Github and then creating a pull request. +You will be using this workflow every week to submit your homeworks, so it's important that you get comfortable with it. +You will also practice adding/commiting files one by one. + +You will use the your class homework repository on your computer to do the exercise. Here are the instructions: + +1. Go to your class homework repo on your computer (you would have already cloned it in preparation or in class exercises) +2. Go to branch `main` +3. Pull the latest changes to make sure your local `main` is up to date +4. Create a branch for your homework, named `git-week1/yourname`, and move to that branch +5. Inside the folder `git/week1` create 3 new files: + - a file named `my_favorite_food.txt`, inside the file write your favorite food recipe (you can just find a random recipe on google and paste it in the file ;) + - a file named `my_second_favorite_food.txt`, inside the file write the recipe for your second favorite food + - a file named `countries.txt`, where you list three countries that you have visited (this doesn't need to be true, you can just write the names of three random countries) +6. Add and commit the file `my_favorite_food.txt`; +7. Add and commit the file `my_second_favorite_food.txt`; +8. Add and commit the file `countries.txt`; +9. Push your changes into your class homework repository on Github. +10. Go to Github and create a pull request (PR) from the branch `git-week1/yourname` to `main` + +## Exercise 2 + +You have hopefully recieved a review on your last week html-css homework. +If you submitted it later into the week, you might not have a review yet, in that case - wait. Be faster next time :). +If you submitted the homework too late, you are not entitled to a review, but you can still try and ask for one. + +1. go to your local copy of the class homework repo, `main` branch; +2. update the `main` branch with the latest changes in the origin; +3. checkout to your `html-css` homework branch; +4. merge `main` into this branch; +5. make changes to your `html-css` homework as adviced by mentors in your homework review and/or make any other changes or improvements; +6. commit and push the changes to the branch in origin; +7. close the `html-css` homework PR. + +## Cheat sheet / tips + +Commands that you will need: + +- `git branch ` - to create a new branch named `` +- `git checkout ` - to move to a branch named `` +- `git add ` - tell git to start tracking a file and to update what will be commited +- `git commit -m "commit_message"` - commit (save) your changes +- `git push origin ` - push (upload) your changes in your current branch to your github repository into the branch named ``. + +**_Note_** +For the sake of consistency (and to avoid mistakes), make sure that when you push you do it to a branch with the same name as the branch where you are, e.g. if you are on a branch named `git-week1` then push to a branch named `git-week1` by typing `git push origin git-week1`. + +When pulling, if you want to pull from a branch named, for instance `main`, make sure that you are in a branch with the same name (`main`) on your computer as well, and only then do `git pull origin `. + +Other useful git commands: + +- `git status` - remember, it is your best friend, it tells you what is the state of your repository and sometimes what you should do. +- `git branch` - this is your second best friend, it tells you in which branch you are (you can also see where you are when you do `git status`) +- `git log` +- `git log --oneline` +- `git pull origin ` - pull (download) your changes from your github repository in the branch named ``, into your current local branch. + +Command line commands that might be useful: + +- `pwd`- print working directory, to know where you are +- `cd ` - to go inside a folder named `` +- `cd ..`- to go to the parent folder of your current folder +- `mkdir ` - to create a new folder +- `ls`- list all the folder contents +- `ls .*` - list all the folder contents, also invisible folders/files (e.g. the git folder) diff --git a/legacy/git/git1/lesson_plan.md b/legacy/git/git1/lesson_plan.md new file mode 100644 index 00000000..095dcfc8 --- /dev/null +++ b/legacy/git/git1/lesson_plan.md @@ -0,0 +1,95 @@ +# Lesson plan + +## Lesson materials + +These are some examples of previously created materials by mentors that you can use yourself, or for inspiration. + +- [Introduction to Git](https://radical-somersault-80b.notion.site/Introduction-to-Git-184dc1cafb9480ffad0de16e6ea8b379) (by [@aina21](https://www.github.com/aina21), Team 31) + +## Lesson outline + +This lesson plan is meant for a traditional class (vs. flipped classroom) where the mentor teaches the contents with breaks for exercises. +The material to be taught is the same as in the flipped classroom though. +The exercises suggested for the flipped classroom can be found [here](./class_exercises.md). + +1. What is Git + + - git is a version control software, widely used by software developers (and not only) + +2. What is version control + + - show example with google docs + - git does the same but for all files in a given folder/repository + - show repository for vscode as an example of a software built using Git to manage all the code + - also git allows you to have branches and work on multiple tasks at the same time, a bit like copying folders + +3. Install git/git bash + +4. Configure git + + - `git config --global user.name "name"` + - `git config --global user.email "email"` + - `git config --global core.editor "code -w"` (without `-w` the commit is aborted with empty message) + +5. Command line basics + + - `pwd`, and explain how paths work + - `ls` + - `cd` + - `mkdir` + - do a little exercise + +6. Git vs. github + + - slide 2 + +7. What is a repository and how to create one + + - kind of a folder, but not all files in the folder have to be in the repository + - slide 3 + +8. The commit + + - slide 4 + +9. How to save/commit changes in your repository + + - slide 5 + +10. What is a commit (technical side) + + - slide 6 + +11. Explain/show what happens after each git add and git commit + + - slides 7-16 + - also show a lot of git status and git log + +12. Explain/show what happens after git push + - slide 17 +13. Do a little exercise where the students: + + - have them clone their class homweork repo into their computer (this is to get everyone on the same page, otherwise it is a mess) + - create a folder named `class_playground` under `git/week1` + - add some files + - commit the changes + - push current changes + +14. Branches + - go trough the homework workflow [have slides showing each step]: + a) create a branch + b) do commits + c) push to github + d) create pull request + e) update local master + - do an exercise where the students do parts a) to d) + +## Other material and links + +Here you can find all the materials used to teach the first Git class ✨: + +- **[Review](review.md)** - contains a short review over the materials taught in class; +- **[FAQ](frequently_asked_questions.md)** - contains a compilation of the frequently asked questions; +- **[Cheatsheet](cheatsheet.md)** - contains a cheatsheet with the commands used during the class (and a few extra); +- **[Resources](resources.md)** - contains some resources about Git that might be useful; +- **[Git Basics](Git_basics.pdf)** - the slides used to teach some concepts during class. diff --git a/legacy/git/git1/preparation.md b/legacy/git/git1/preparation.md new file mode 100644 index 00000000..c9178407 --- /dev/null +++ b/legacy/git/git1/preparation.md @@ -0,0 +1,49 @@ +# Preparation + +This is the preparation for the "old style" presential classes (vs. flipped classroom). + +Readings: + +- What is version control: (5 min) +- What is git: (6 min) + +Github: + +- if you haven't created an account on [github.com](www.github.com) yet, please create it now :) + +Git: + +- please install git before Sunday: + +- for mac users: running `brew install git` on the command line should work; +- for ubuntu people (or any debian based linux): run `sudo apt-get install git` on the command line +- for windows people: download Git for Windows [here](https://gitforwindows.org/) and install. Step by step instructions: + + 1. execute the file you downloaded; + 2. on the `Information` screen, click next; + 3. on the `Select Destination Location` screen, click next; + 4. on the `Select Components` screen, click next without changing anything; + 5. on the `Select Start Menu Folder` screen, click next; + 6. `Choosing the default editor used by Git`, select `Use Vim` and click next; + 7. `Adjusting the name of the initial branch in new git repositories`, select `Let Git decide` + 8. `Adjusting your path environment`, select `Use Git from Git Bash only` and click next; + 9. `Choosing HTTPS transport backend`, select `Use the OpenSSL library` and click next; + 10. `Configuring the line ending conversions`, select `Checkout Windows-style, commit Unix-style line endings` and click next; + 11. `Configuring the terminal emulator to use with Git Bash`, select `Use MinTTY` and click next; + 12. `Choose the default behavior of "git pull"`, choose `Default (fast-forward or merge)` + 13. `Choose a credential helper`, choose `Git Credential Manager Core` + 14. `Configuring extra options`, select `Enable file system caching` and `Enable Git Credential manager`, click next; + 15. `Configuring experimental options`, do not select any of them, and click install; + 16. and you should be pretty much done :) + +- it is **\*very important** that you do the following as well: + - configure git by following the instructions [here](https://drive.google.com/file/d/1nS-IvE7iJtUiUzxJdukXBFgt8OoAjuiY/view?usp=sharing); + - set up your ssh keys by following [this video](https://drive.google.com/file/d/1qDA4g3WcaHI_qbvOgB4cVLoVsi8HCcC2/view?usp=sharing). The instructions on Github can be found [here](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent). + +Optionally, if you are using Windows and want to use git bash on VSCode, check the instructions in the first answer [here](https://stackoverflow.com/questions/42606837/how-do-i-use-bash-on-windows-from-the-visual-studio-code-integrated-terminal) on how to do that. If you are using linux or macOS, it works right out of the box. + +We'll be roughly following the [materials here](./review.md), in case you want to take a look. + +## Flipped classroom material + +Check the flipped classroom material [here](./preparation_flipped_classroom.md) diff --git a/legacy/git/git1/preparation_flipped_classroom.md b/legacy/git/git1/preparation_flipped_classroom.md new file mode 100644 index 00000000..cea87044 --- /dev/null +++ b/legacy/git/git1/preparation_flipped_classroom.md @@ -0,0 +1,63 @@ +# Preparation for flipped classroom + +This is the preparation for the flipped classroom (vs. "old style" presential classes). + +## Setting up Git/Github + +Github: + +- if you haven't created an account on [github.com](www.github.com) yet, please create it now :) + +Git: + +- please install git before Sunday: + +- for mac users: running `brew install git` on the command line should work; +- for ubuntu people (or any debian based linux): run `sudo apt-get install git` on the command line +- for windows people: download Git for Windows [here](https://gitforwindows.org/) and install. Step by step instructions: + + 1. execute the file you downloaded; + 2. on the `Information` screen, click next; + 3. on the `Select Destination Location` screen, click next; + 4. on the `Select Components` screen, click next without changing anything; + 5. on the `Select Start Menu Folder` screen, click next; + 6. `Choosing the default editor used by Git`, select `Use Vim` and click next; + 7. `Adjusting the name of the initial branch in new git repositories`, select `Let Git decide` + 8. `Adjusting your path environment`, select `Use Git from Git Bash only` and click next; + 9. `Choosing HTTPS transport backend`, select `Use the OpenSSL library` and click next; + 10. `Configuring the line ending conversions`, select `Checkout Windows-style, commit Unix-style line endings` and click next; + 11. `Configuring the terminal emulator to use with Git Bash`, select `Use MinTTY` and click next; + 12. `Choose the default behavior of "git pull"`, choose `Default (fast-forward or merge)` + 13. `Choose a credential helper`, choose `Git Credential Manager Core` + 14. `Configuring extra options`, select `Enable file system caching` and `Enable Git Credential manager`, click next; + 15. `Configuring experimental options`, do not select any of them, and click install; + 16. and you should be pretty much done :) + +- it is **\*very important** that you do the following as well: + - configure git by following the instructions [here](https://drive.google.com/file/d/1nS-IvE7iJtUiUzxJdukXBFgt8OoAjuiY/view?usp=sharing); + - set up your ssh keys by following [this video](https://drive.google.com/file/d/1qDA4g3WcaHI_qbvOgB4cVLoVsi8HCcC2/view?usp=sharing). The instructions on Github can be found [here](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent). + +Optionally, if you are using Windows and want to use git bash on VSCode, check the instructions in the first answer [here](https://stackoverflow.com/questions/42606837/how-do-i-use-bash-on-windows-from-the-visual-studio-code-integrated-terminal) on how to do that. If you are using linux or macOS, it works right out of the box. + +## Class videos + +Since this is a flipped classroom, where you prepare the class during the week and then the Sunday +session is focused on exercises and answering your questions, it is **_extremely important_** that you watch the following videos (you do not need to reproduce all the steps steps, just focus on trying to understand what's happening): + +- [introduction to version control and git](https://drive.google.com/file/d/1lHO7AjtuADB7taS7HrukKL0PLhKUjJUj/view?usp=sharing); +- [introduction to the command line](https://drive.google.com/file/d/1DT6jkB-VFemyKZYhpAzXtNKC4Fm2soNy/view?usp=sharing) ; +- [git basics, part 1](https://drive.google.com/file/d/1ZVExfsf1W21aprmVVk8swQy9lk0iEw06/view?usp=sharing); +- [git basics, part 2](https://drive.google.com/file/d/1arPYP_lh91xoDn1SYTKnq1PuejI8hWNQ/view?usp=sharing); +- [git branches](https://drive.google.com/file/d/1znEHlVDwBXFZZnZdLOyd3zMEF7N9kagw/view?usp=sharing); +- [git branches extra](https://drive.google.com/file/d/11m_is5nD3Wb5R1zr6cGlAfhZWDILqXNp/view?usp=sharing); +- [how to solve merge conflicts](https://drive.google.com/file/d/1-7Evus2Fh7KDRlmD48eY9ZTQ9FVT0D6_/view?usp=sharing). + +## Extra readings + +And if you have a some extra time, you can read the following articles: + +- What is version control: (5 min) +- What is git: (6 min) +- Git and Github in Plain English: + +We'll be roughly following the [materials here](./review.md), in case you want to take a look. diff --git a/legacy/git/git1/readme.md b/legacy/git/git1/readme.md new file mode 100644 index 00000000..eac3c1d8 --- /dev/null +++ b/legacy/git/git1/readme.md @@ -0,0 +1,9 @@ +# Git1 + +The main goal of this class is to introduce you to Git and how to work with Pull Requests, Commits and Branches + +| Week | Topic | Preparation | Lesson Plan | Homework | +| ---- | -------------------------------------------------------------------- | ------------------------------- | ------------------------------- | ------------------------- | +| 1. | Introduction to Git; Git vs GitHub; Pull Requests; Commits; Branches | [Preparation](./preparation.md) | [Lesson Plan](./lesson_plan.md) | [Homework](./homework.md) | + +Please check the material shared on Preparation, Lesson Plan and Homework ⬆️ diff --git a/legacy/git/git1/resources.md b/legacy/git/git1/resources.md new file mode 100644 index 00000000..700fddf6 --- /dev/null +++ b/legacy/git/git1/resources.md @@ -0,0 +1,23 @@ +# Resources + +Here are a few resources that might be useful: + +- Git and Github in Plain English, super nice to understand the concepts: +- a quick overview of git: ; +- a beginner's tutorial: ; +- a simple git guide: ; +- an interactive tutorial: . The relevant parts for you are in the "Main" section, introduction sequence, parts 1-3, and in the "Remote" section, the full "Push & Pull" sequence. Feel free to do the other parts if you want :). You can also go to if you want to just play around; +- the Pro Git book: , you'll find pretty much everything about git there, but might be tedious :); +- a list of some graphical interfaces for git: ; +- for when things really go wrong: (be careful using this!). + +A couple of videos recommended by class10 student Lilla KΕ‘rΓΆsi: + +- [https://youtu.be/BCQHnlnPusY](https://youtu.be/BCQHnlnPusY) +- [https://youtu.be/oPpnCh7InLY](https://youtu.be/oPpnCh7InLY) + +Video about submitting your homework using Pull Requests: + +- [https://www.youtube.com/watch?v=JcT4wmK1VcA](https://www.youtube.com/watch?v=JcT4wmK1VcA) + +And finally, atlassian (the company that makes BitBucket) has really nice tutorials as well. Check them out [here](https://www.atlassian.com/git/tutorials/what-is-version-control) and explore the stuff in the side bar :). diff --git a/legacy/git/git1/review.md b/legacy/git/git1/review.md new file mode 100644 index 00000000..b9a98958 --- /dev/null +++ b/legacy/git/git1/review.md @@ -0,0 +1,286 @@ +# Review + +Tutorial for HackYourFuture Git basics :octocat: + +This tutorial has 6 sections: + +1. Command line interface (bash) +2. Git +3. Branches +4. Github +5. Pull requests +6. Checkout + +Also you can watch the class recordings [here](https://drive.google.com/open?id=1eT5xWxG2GQHLAxMRNp2Bnb4VcSnJpb7s). + +And the slides used in the class can be found [here](https://drive.google.com/open?id=1sR3er7alG-LXNadByoiNHlTiwhxrDgzlJaTt_GdTImY). + +## 1. Command line (bash) + +We used the command line a lot, a few basic commands we need are: + +- `pwd` to find where we are, in which folder/directory. +- `ls` to list all the contents in the current directory. +- `cd ` to change directory to `folder_name`. +- `mkdir ` to create a new folder/directory named `folder_name`. + +Marco has also made a cool video with 10 important commands, which you can see [here](https://www.youtube.com/watch?v=kN1-tseJnt0&). + +## 2. Git + +### 2.1 What is Git + +- [ ] Version Control (aka Revision control, source control) +- [ ] Distributed version control system, Linus Torvalds, 2005 +- [ ] GIT: Global Information Tracker + +Bottom line: it is a program used to track changes in your files (in particular code). + +If you need, you can read more here: + +- what is version control: (5 min) +- what is git: (6 min) + +### 2.2. Configuring Git + +On your local machine, in the command line type: + +```shell +git config --global user.email "email@email.com" +git config --global user.name "username" +``` + +Make sure that the email is the same you used for the github account. +You can run these commands again whenever you want to change the email or the user name. + +To set the default text editor used by Git to vscode, you can run: + +```shell +git config --global core.editor "code -w" +``` + +This command assumes you can start vscode from the command line by just typing `code`. On macOS this doesn't seem to work right out of the box, and you might want to check the top answer [here](https://stackoverflow.com/questions/29971053/how-to-open-visual-studio-code-from-the-command-line-on-osx) and follow the instructions there, or just ask your mentor to help you :) + +### 2.3 Creating a repository on your computer + +Create a new directory in your home directory or any other suitable location using: + +```shell +mkdir git_example +``` + +Enter the directory: + +```shell +cd git_example +``` + +and create a new git repository using: + +```shell +git init +``` + +You can also create a repository on your local machine by cloning a remote repository with `git clone ` command. This copies the repository from a remote machine (typically github) and initializes it on your machine. You can try to clone some public repositories on [github.com](www.github.com). + +Before creating any repository make sure you are not inside a git repository already. This is very important!!! To do so type `git status`, if you get an error it means you are not inside a git repository and you can safely create a new one. + +### 2.4 Workflow + +Working Directory -> Index -> Local +Your local repository consists of three "trees" maintained by git. The first one is your Working Directory (workspace) which holds the actual files. The second one is the Index which acts as a staging area, and finally the local repository itself which actually contains your commit history. + +#### 2.3.1 add and commit + +The basic Git workflow consists of two steps. +First, you add files/changes (to the index/staging area) to be committed. + +```shell +git add +``` + +Second, you actually commit (save) your changes by doing: + +```shell +git commit -m "Commit message" +``` + +## 3 Branches + +### 3.1 Why Branches ? + +To expand. +Trees need branches to expand. +Banks needs (office) branches to expand. +Company needs (code) branches to expand. +E.g. Branches for Bugs, testing, featuers, production, staging etc. + +#### 3.2 Working with branches + +To view a list of all the local branches on your machine, run: + +```shell +git branch +``` + +To create a new branch run: + +```shell +git branch +``` + +To move to a branch run: + +```shell +git checkout +``` + +Always check in which branch you are before creating a new one. +For instance, for your homework you should always be in the main branch when you create your homework branch. + +## 4. GitHub + +### 4.1 What is GitHub + +GitHub is a code hosting platform for version control and collaboration. It lets you and others work together on projects from anywhere. There are other platforms like Gitlab and Bitbucket. + +### 4.2 Creating a repository + +Using your GitHub account, you can create a repository to which you can add files. +Name the repository `git_example`. Create a public repository and **do not** check the box to create a README file. +After you create the repository, the URL of your web page would be something like . Replace `martamatos` with your username. If you append `.git` to this URL, you will get the name of your GitHub repository: + +### 4.3 Connecting your local repository to the remote repository on Github + +When you have an existing local repository (in your computer) that you want to connect to the repository you just created on Github, you need to run: + +```shell +git remote add origin +``` + +Here you are basically adding the connection to a remote repository named `origin`, where `origin` stands for the link to the github respository, for instance `https://github.com/marta_matos/git_example.git`. +To check if your local repository is connected to a remote repository (e.g. on Github) and what is the address of that repository you can always run: + +```shell +git remote -v +``` + +### 4.4 Pushing changes + +To send (upload) the contents of a given branch on your local repository to your remote repository (on github), run + +```shell +git push origin +``` + +However, this command will fail if there are changes in the remote repository that you do not have on your local machine yet. In that case you first need to get (download) the changes from the remote repository to your local machine. To do so you do: + +```shell +git pull origin +``` + +For the sake of consistency (and to avoid mistakes), make sure that when you push you do it to a branch with the same name as the branch where you are, e.g. if you are on a branch named `my_homework` then push to a branch named `my_homework` by typing `git push origin my_homework`. + +When pulling, if you want to pull from a branch named, for instance `git_homework`, make sure that you are in a branch with the same name (`git_homework`) on your computer as well, and only then do `git pull origin `. + +### 4.5 Troubleshooting + +You could encounter errors if you do not follow the exact procedure as described above. + +```text +error: failed to push some refs to 'git@github.com:myrepo.git' +``` + +Solution: + +```shell +git pull origin main +``` + +or + +```text +fatal: refusing to merge unrelated histories +``` + +Solution: + +```shell +git pull --allow-unrelated-histories +``` + +### 4.6 Generating the ssh keypair + +To create an ssh keypair start by opening GitBash (in Windows) or the terminal (in Linux and Mac) and type: + +```shell +ssh-keygen -t ed25519 -C "your_email@example.com" +``` + +Supply your Github email address instead of this fake one. +Accept the default location storage (default file) for the keys. When prompted for a passphrase either leave it empty or make up one, and don't forget it! This is your private key, do not share it with anyone. +You will have an `id_ed25519.pub` file in the directory `~/.ssh/`, where `~/` is your home directory. + +You want to copy the contents of the `id_ed25519.pub` (open it with a text editor or use the command `cat id_ed25519.pub` in the command line to print out the contents of the file). After you copy the contents of the `id_ed25519.pub` file, go to your GitHub account, go to the settings, find SSH and GPG keys option and add New SSH key. + +## 5. Pull requests + +Pull requests make it easier for developers to collaborate. They provide a user-friendly (web) interface for discussing proposed changes before integrating them into the official project. +In the simplest form, pull requests are a means for a developer to notify a team member that they have completed a feature. But the pull-request is more than just a notification. It's a dedicated forum where teammates can post feedback, push follow-up commits. +Even though it is named a pull request it is more like a merge request, where you ask for permission to merge a branch into another branch. + +### What does a pull request contain? + +When you create a pull request, you want another developer to merge your branch into another branch. This means that you need to provide 2 pieces of information to create a pull request: + +- the destination branch +- the branch to be merged + +Pull requests can be used in conjunction with various workflows: + +- [Feature-branch workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow) +- [Gitflow workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) +- [Forking workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/forking-workflow) + +The workflow you use in your homework is pretty much the Feature-branch workflow, where the central repository is your `hyf-homework` repository, and the feature branch is your homework branch. Also, instead of BitBucket you use Github. + +There are a few other differences, for instance: + +- in the section "Start with the main branch", instead of doing: + + ```shell + git checkout main + git fetch origin + git reset --hard origin/main + ``` + + to update your main branch, you should just do: + + ```shell + git checkout main + git pull origin main + ``` + +- once the pull request is accepted you just merge it directly on github, no need to use the command line :) + +### 6. Checkout + +We didn't talk about this in class, but it's kind of nice to know. +To move around a repository, to different branches or commits, you can use the `git checkout` command. + +When you do `git log` you see the history of all commits in the branch where you are. The first line of each commit looks like `commit fe48414f5c9a21c986ae3c65f198d477a81299cc`, where the weird sequence of numbers and letters is the commit hash key. If you want to go to a particular commit all you need to do is: + +```shell +git checkout +``` + +At that point you can take a look around and see what your code looked like. +Do **not** commit any changes when are in that state, it will probably get you into trouble :) + +To return to the latest commit you do: + +```shell +git checkout +``` + +Where `branch_name` is the name of the branch where you are. diff --git a/legacy/git/git2/Git_advanced.pdf b/legacy/git/git2/Git_advanced.pdf new file mode 100644 index 00000000..187be8e2 Binary files /dev/null and b/legacy/git/git2/Git_advanced.pdf differ diff --git a/legacy/git/git2/cheatsheet.md b/legacy/git/git2/cheatsheet.md new file mode 100644 index 00000000..90f2a7cd --- /dev/null +++ b/legacy/git/git2/cheatsheet.md @@ -0,0 +1,62 @@ +# Cheat sheet + +Here are the commands we used in the class and their meaning. + +Commands to deal with branches: + +- `git branch ` - create a new branch ``. +- `git checkout ` - go to branch ``. +- `git branch` - check which local branches you have and where you are (in green). +- `git branch -a` - show both local and remote tracking branches. +- `git branch -vv` - to see local tracking branches. +- `git merge ` - merges the branch `` into your current branch. +- `git merge /` - merges the remote branch `` into your current branch. +- `git branch -d ` - delete the branch ``. +- `git branch -u /` - make the current branch a local tracking branch for the branch `/`. + +Commands to interact with Github: + +- `git clone ` - clone a remote github repository. +- `git remote add ` - adds a link between your local repository and the remote github repository with the url ``. `` is typically `origin`. +- `git remote -v` - shows a list of remotes and respective URLs. +- `git push ` - push your local changes in your current branch into the branch `` in the `` github repository. +- `git fetch ` - gets all changes on in the `` github repository but does **not** merge them with your current branch. This is useful if you just want to check what the difference is between a remote branch and a local branch. +- `git pull origin ` - gets all changes on in the `` and merges them with your current branch. + +Some mixed commands: + +- `git init` - start a new git repository in the folder where you are (always do `git status` before `git init` to make sure you are not inside a git repository already). +- `git status` - remember, it is your best friend, it tells you what is the state of your repository and sometimes what you should do. +- `git branch` - this is your second best friend, it tells you in which branch you are (you can also see where you are when you do `git status`) +- `git log` - shows the history of commits in the current branch. Also allows you to see if branches are synchronyzed. +- `git log --oneline` - shows the history of commits in a summarized form. +- `git rm --cached ` - removes the file with name `` from your git repo, so it won't be tracked by git anymore, but the file stays in your computer, it is not deleted. +- `git cherry-pick ` - will copy the commit with hash ` from another branch to your current branch. To find the hash for the commit you want use `git log` on the branch where the commit exists. +- `git rebase -i HEAD~` - will rebase the last `` commits. It will allow you to drop/remove a commit from the middle or change the content of a commit from the past. + +Commands for stashing: + +- `git stash` - will stash your current changes, i.e., save them in a safe place so you can move to other branches without your changes being overwritten. +- `git stash list` - will show the list of all stashes you have. +- `git stash pop ` - will recover the changes in `` for you and delete them from the stash list. You can get the `` by doing `git stash list`, it looks like `stash@{0}`, where the 0 can be any number. +- `git stash apply ` - will recover the changes in `` for you. The changes will not be deleted from the stash with this command. + +Commands for checking differences: + +- `git diff` - will show all the changes in the files in your workspace, that are not staged for commit yet (i.e. you didn't do git add yet). +- `git diff --staged` - will show all the changes in the files in your staging/index are (i.e. after you do git add). +- `git diff --stat` - shows which files in your workspace have been changed, and the type of changes (adding and/or removing content). +- `git diff --staged --stat` - shows which files in your staging/index area have been changed, and the type of changes (adding and/or removing content). +- `git diff ` - shows the differences between your current branch and another branch named ``. +- `git diff ` - shows the differences between your current commit and a specific commit with hash ``. +- `git diff ` - shows the differences between two specific commits, one with hash `` and the other with hash ``. + +Commands to go back in history: + +- `git checkout ` - you use this to go back to a specific commit and take a look at your code back then, but **do NOT ever** change your code at this point, since you are in a detached HEAD state when you go back to a specific commit. Remember, you wouldn't walk around if your head wasn't glued to your neck :). To go back to your latest commit you just do `git checkout `, where `` is the name of the branch where you are. +- `git revert ` - will revert whatever was done in a specific commit with hash ``. Be careful with possible conflicts. If you get conflicts and you want to abort the revert, you can do it with `git revert --abort`. +- `git reset --soft ` - will remove all commits until the commit with hash ``, but the file changes will stay in the staging/index area. +- `git reset --mixed ` - will remove all commits until the commit with hash ``, but the file changes will stay in your filesystem. +- `git reset --hard ` - will remove all commits until the commit with hash ``, as well as the changes in your files. Be very careful with this one! + +Note: you can get the commit hash for a specific commit using either `git log` or `git log --oneline` diff --git a/legacy/git/git2/class_exercises.md b/legacy/git/git2/class_exercises.md new file mode 100644 index 00000000..ed8474a6 --- /dev/null +++ b/legacy/git/git2/class_exercises.md @@ -0,0 +1,70 @@ +# Class exercises for the flipped classroom + +These are the suggested exercises when using the flipped classroom method. + +The key goal of the class is for the students to be able to use git/github to collaborate in the final project. + +## Exercise 1 + +This exercise is about mimicking collaboration between two people on the same project. +The workflow is the same that the students will use during the final project. + +1. create a repo named `git_exercise_1` on github; +2. clone the repo you just created on github; +3. on your computer, on the `master` branch create the file `fruits.txt`, add the names of 3 fruits, one per line, and commit your changes; +4. push `master` to github; +5. on your computer, from `master` create the branch `feature/fruits` and move to it; +6. on your computer, modify the name of the second fruit, add two new fruits at the end of the file (one per line), and commit your changes; +7. on github, on branch `master`, change the name of the second fruit in the file `fruits.txt` +8. update your local branch `feature/fruits` with the contents of the branch `master` on github +9. push `feature/fruits` to github +10. create pull request to merge `feature/fruits` into `master` + +**Note**: the students will get a merge conflict on step 8. + +## Exercise 2 + +The goal of this exercise is to learn how to get rid of a particular commit, that is not the latest commit. + +1. clone the repo: +2. in the branch add_fruits, get rid of the commit "added beetroots file". Hint: you need to create a new branch and use cherry-pick. +3. in the branch add_veggies, get rid of the commit "added apples". + Hint: You can either use one of the following approaches: + +- create a new branch and use cherry-pick. (This one will lead to a conflict). +- use interactive rebasing on the branch. (This one will lead to a conflict). + +Note: use git log --all --oneline to see all commits in all branches (the --oneline part is only to see a shorter version of the log). + +## Exercise 3 + +This is about git revert and how you can get conflicts when you use it. +The goal is that the students learn why sometimes they get conflicts when doing git revert and sometimes they don't. + +1. clone the repo: +2. revert the commit where file a was added. +3. revert the commit where sweden was added. (This will lead to a conflict). + +## Exercise 4 + +This exercise is about git stash (and reset or commit --amend) + +1. create a new repository on github called `git_exercise_4`; +2. clone the repo you just created on github; +3. create a new file in the repo called `project.txt`; +4. write "Hello world!" on `project.txt`, commit, and push the changes to the github; +5. create a new local branch `feature/new_sentence` and write "learning code" on the second line, commit, and push the branch to github; +6. on the local branch `feature/new_sentence`, edit the second line to "learning code javascript" and save the file, do **not** commit; +7. move to master, you should get an error, remember you don't want to commit because your feature is not complete yet, but you still need to move to master; +8. once you are on `master`, you want to work on a different feature so create a new local branch named `feature/new_number`; +9. on branch `feature/new_number`, add a new line with number 1 to `project.txt`, commit, and push to github; +10. go to github and on the branch `feature/new_number` add one more line with number 2 to `project.txt`; +11. on your computer, add a new line with number 3 to `project.txt` and save, do **not** commit; +12. pull the `feature/new_number` branch (oh, what a message again! remember, you don't want to commit!); +13. finish the pull; +14. check list of all stashes you have; +15. go to `feature/new_sentence` branch, bring back the stash you did in this branch, push to github; +16. go to `feature/new_number` branch, bring back the stash you did in this branch, solve the conflict and commit (do **not** push); +17. before you push `feature/new_number` to github you noticed a mistake in the commit message; +18. remove the commit, create correct commit message and push to github; +19. your project is finished :) diff --git a/legacy/git/git2/homework.md b/legacy/git/git2/homework.md new file mode 100644 index 00000000..267ea9ed --- /dev/null +++ b/legacy/git/git2/homework.md @@ -0,0 +1,72 @@ +# Homework + +## Part 1 + +In this exercise you will get some practice creating branches, merging, pushing/pulling to Github, and creating a pull request. Here are the instructions: + +1. In your computer, in your `hyf-homework` repository, start by creating a branch for your homework, named `git-week2`, and move to that branch +2. Inside the folder `hyf-homework/git/week2` create a new file named `veggies.txt`, inside the file write the name of 5 veggies, one per line. Commit your changes. +3. Push the branch `git-week2` to github. +4. While on `git-week2`, create a branch named `feature/veggies` and move to that branch. +5. On the file `veggies.txt`, modify the name of the third veggie, and add two more veggies (one per line) at the end. Commit your changes. +6. On Github, go to branch `git-week2` and modify the name of the third veggie in the file `veggies.txt`. Commit your changes. +7. Before pushing the branch `feature/veggies` to github, update it with the latest changes on branch `git-week2` (hint: pull that branch from github and merge it with `feature/veggies`). +8. Now that `feature/veggies` has been updated, push it to github and create a pull request to `git-week2`. +9. Wait for feedback, there will be one more task before merging :) + +Commands that you will need for this part: + +- `git add ` - tell git to start tracking a file and to update what will be commited +- `git commit -m "commit_message"` - commit (save) your changes +- `git branch ` - to create a new branch named `` +- `git checkout ` - to move to a branch named `` +- `git merge ` - to merge the branch named `` with the branch where you are. +- `git push origin ` - push (upload) your changes in your current branch to your github repository into the branch named ``. +- `git pull origin ` - pull (download) your changes from your github repository in the branch named ``, into your current local branch. + +**_Note_** +For the sake of consistency (and to avoid mistakes), make sure that when you push you do it to a branch with the same name as the branch where you are, e.g. if you are on a branch named `my-homework` then push to a branch named `my-homework` by typing `git push origin my-homework`. + +When pulling, if you want to pull from a branch named, for instance `git-homework`, make sure that you are in a branch with the same name (`git-homework`) on your computer as well, and only then do `git pull origin `. + +## Part 2 + +This part is only for you to do by yourself in your computer so you can see how the commands work and get comfortable with them :) + +It is important that after each step you run `git log --oneline` and `git status` to see what has changed. Also check the contents of your folder :) + +### Git reset and revert + +1. Create a new folder somewhere in your computer, named `reset_playground`; +2. Start a git repository inside `reset_playground` (make sure you are not inside a git repo before you create it!!!) +3. Create a file named `countries.txt`, commit your changes. +4. Add a country name to `countries.txt` and commit your changes. Repeat this 5 times, so that at the end you have 5 country names in your `countries.txt` file and a commit for each. +5. Create a new branch named `feature/more_countries`, move to it. +6. Create a new file, named `more_countries.txt`, add the name of 2 countries to that file and commit your changes. +7. Go back to `master`. +8. Use `git cherry-pick ` to get the commit where you created the file `more_countries.txt` into your master branch (you need to get the commit hash by doing `git log` when you are in the branch `feature/more_countries`). +9. In the file `countries.txt`, add one more country, and commit your changes. +10. Again, in the file `countries.txt`, add one more country, and commit your changes. +11. Remove the latest commit you did using `git reset --soft ` +12. Either commit or stash the changes from the last step. +13. Use `git revert ` to revert the commit that you cherry picked from the branch `feature/more_countries`, the one where the file `more_countries.txt` was added (get the commit hash by doing `git log` and looking for the commit you want). +14. Use `git reset --mixed ` to get rid of the last 2 commits. +15. Either commit or stash the changes from the last step. +16. Use `git checkout ` to check what your repo looked like after your first commit. +17. Now go back to your latest commit using `git checkout master`. +18. Finally, use `git revert ` to revert the commit where you added country number 3. Most likely you will get a conflict and you must solve it. + +Commands that you'll need for this part: + +- `git log` - see your commit history with all the details +- `git log --oneline` - see your commit history in a single line. +- `git cherry-pick ` - will copy the commit with hash ` from another branch to your current branch. To find the hash for the commit you want use `git log` on the branch where the commit exists. +- `git checkout ` - you use this to go back to a specific commit and take a look at your code back then, but **do NOT ever** change your code at this point, since you are in a detached HEAD state when you go back to a specific commit. Remember, you wouldn't walk around if your head wasn't glued to your neck :). To go back to your latest commit you just do `git checkout `, where `` is the name of the branch where you are. +- `git revert ` - will revert whatever was done in a specific commit with hash ``. Be careful with possible conflicts. If you get conflicts and you want to abort the revert, you can do it with `git revert --abort`. +- `git reset --soft ` - will remove all commits until the commit with hash ``, but the file changes will stay in the staging/index area. +- `git reset --mixed ` - will remove all commits until the commit with hash ``, but the file changes will stay in your filesystem. + +Other useful git commands: + +- `git status` - remember, it is your best friend, it tells you what is the state of your repository and sometimes what you should do. +- `git branch` - this is your second best friend, it tells you in which branch you are (you can also see where you are when you do `git status`) diff --git a/legacy/git/git2/images/branches_diagram.jpg b/legacy/git/git2/images/branches_diagram.jpg new file mode 100644 index 00000000..05bd34f5 Binary files /dev/null and b/legacy/git/git2/images/branches_diagram.jpg differ diff --git a/legacy/git/git2/lesson_plan.md b/legacy/git/git2/lesson_plan.md new file mode 100644 index 00000000..8b706577 --- /dev/null +++ b/legacy/git/git2/lesson_plan.md @@ -0,0 +1,68 @@ +# Lesson plan + +This lesson plan is intended for the "old style" presential classes. If using the flipped classroom method, the contents would be about the same, but the class itself should focus on exercises. Suggested exercises for the flipped classroom can be found [here](./class_exercises.md). + +In any of the cases, the goal of the class is for the students to be able to use git/github to collaborate in the final project. + +1. Why branches? + +2. The 3 types of branches: + + - the local non-tracking branches + - the local tracking branches + - the remote tracking branches + +3. Push/Pull branches to github + +4. Create a merge conflict and show how to solve it (use vscode to select which changes to keep). + +5. Do an exercise (to basically repeat what was shown before with the slides and all): + + 1. create repo `class_example`, both locally and on github + 2. in master, create file `fruits.txt`, add the names of 3 fruits, one per line, Commit your changes. + 3. push `master` to github + 4. from `master`, create branch `feature/fruits`, modify the name of the second fruit and add two new fruits at the end of the file (one per line) + 5. on github, on branch `master`, change the name of the second fruit in the file `fruits.txt` + 6. update your local branch `feature/fruits` with the contents of `master` + 7. push `feature/fruits` to github + 8. create pull request to merge `feature/fruits` into `master` + +6. Git diff and git stash: + + 1. show the git diff when we make changes in current feature + 2. explain git stash + 3. show git diff (when there are no differences) + 4. explain git stash list and then git stash apply + 5. explain difference between git stash apply and git stash pop + 6. show some more options like git diff --stat + +7. How to "remove" commits + + - git reset soft vs. hard + - git revert + - git cherry-pick + - git rebase -i HEAD~N + +8. Exercise to create commit use reset soft, and then create another commit use reset hard. + +9. Show git checkout to a specific commit. + +10. Random things that should be mentioned throughout the class: + + - `git checkout -- ` / `git restore ` (only works in git 2.23+) + - `git reset HEAD ` / `git restore --staged ` (only works in git 2.23+) + - `git rm --cached` + - `git commit --amend` + - show how to check that local branch is up to date with origin (with git log) + +11. How to write a good commit message. + +12. How to create a good, easy to understand PR. + +## Other materials and links + +- **[Review](review.md)** - contains a short review over the materials taught in class; +- **[Class exercises](class_exercises.md)** - contains a short review over the materials taught in class; +- **[Cheatsheet](cheatsheet.md)** - contains a cheatsheet with the commands used during the class (and a few extra); +- **[Resources](resources.md)** - contains some resources about Git that might be useful; +- **[Git Advance](Git_advanced.pdf)** - the slides used to teach some concepts during class. diff --git a/legacy/git/git2/preparation.md b/legacy/git/git2/preparation.md new file mode 100644 index 00000000..be6ecec1 --- /dev/null +++ b/legacy/git/git2/preparation.md @@ -0,0 +1,9 @@ +# Git + +## Week 2 - Preparation + +The main preparation for this module is that you collect all the questions and doubts that you have about Git before starting the Final Project. Think about the conflicts, or maybe questions about how to best separate your code into small commits or even how to review a PR. + +## Flipped classroom material + +- **[Preparation Flipped Classroom](./preparation_flipped_classroom.md)** - contains what the students should do before coming to class with Flipped Class room setting diff --git a/legacy/git/git2/preparation_flipped_classroom.md b/legacy/git/git2/preparation_flipped_classroom.md new file mode 100644 index 00000000..0f29da02 --- /dev/null +++ b/legacy/git/git2/preparation_flipped_classroom.md @@ -0,0 +1,9 @@ +# Preparation for flipped classroom + +Before the Git 2 class on Sunday, it is very important that the students watch the following videos: + +- [git branches part 1](https://www.youtube.com/watch?v=3sZ7RLDESew) by Nathan Kuik (ignore the exercise he mentions :) ); +- [git branches part 2](https://www.youtube.com/watch?v=_vgGeH3Dmwk) by Nathan Kuik; +- [git reset, revert, and cherry-pick](https://www.youtube.com/watch?v=qf3vJYnxNu0), or in short: how to get rid of commits when you mess up, by Ida Naderian; +- [git stash](https://www.youtube.com/watch?v=rlgrs8MA0Jg); +- [how to solve merge conflicts](https://www.youtube.com/watch?v=WlHQpRCEMwg). diff --git a/legacy/git/git2/readme.md b/legacy/git/git2/readme.md new file mode 100644 index 00000000..5ed80480 --- /dev/null +++ b/legacy/git/git2/readme.md @@ -0,0 +1,9 @@ +# Git2 + +The main goal of this class is to become comfortable with branches, merge conflicts, and pull requests, so that the students can work together on the final project. + +| Week | Topic | Preparation | Lesson Plan | Homework | +| ---- | --------------------------------------------------- | ------------------------------- | ------------------------------- | ------------------------- | +| 1. | Advanced Git and Preparation for the Final Project. | [Preparation](./preparation.md) | [Lesson Plan](./lesson_plan.md) | [Homework](./homework.md) | + +Please check the material shared on Preparation, Lesson Plan and Homework ⬆️ diff --git a/legacy/git/git2/resources.md b/legacy/git/git2/resources.md new file mode 100644 index 00000000..ce7b29bc --- /dev/null +++ b/legacy/git/git2/resources.md @@ -0,0 +1,30 @@ +# Resources + +Here are some links that might be useful: + +- A style guide for commit messages: +- For interactive tutorials, explore this: +- About git stash: +- About git diff: +- About git reset and revert: +- About git cherry-pick: +- About git interactive rebasing: +- For when things really go wrong, you can check this, but be very careful: + +How to write a good commit message: + +- +- +- +- +- +- + +How to write a good pull request: + +- +- +- +- + +In general, [atlassian](https://www.atlassian.com/git/tutorials/) has very good tutorials, so just explore :) diff --git a/legacy/git/git2/review.md b/legacy/git/git2/review.md new file mode 100644 index 00000000..ad32f5b3 --- /dev/null +++ b/legacy/git/git2/review.md @@ -0,0 +1,306 @@ +# Review + +This is a review for HackYourFuture Git advanced. It has the following sections: + +1. Github and remotes +2. Git branches +3. Pull requests +4. Our workflow in the class +5. Others + - git stash + - HEAD + - git checkout + - git reset + - git revert + - git cherry-pick + - git rebase -i + +## 1. Github and remotes + +### 1.1 What is remote ? + +Before anything else, let's just clarify what is a remote. +If you're using Git collaboratively, you'll probably need to sync your commits with other machines or locations. In Git terminology, each machine or location is called a remote, and each one may have one or more branches. Most often, you'll have just one remote, named `origin`, which is a git repository in your own github account. + +To list all the remotes, run + +```shell +git remote +``` + +To see which locations these remote names are shortcuts for, run + +```shell + git remote -v +``` + +## 1.2 Adding a remote to your local repository + +If you have not cloned an existing repository on github and want to connect your repository to a remote github repository, you need to add it with + +```shell +git remote add origin https://github.com/marta_matos/my_first_repo.git +``` + +Replace the URL with the URL of the repository that you actually want to add. +Also, remember that `origin` is just a place holder, and the convention is to use `origin` for a repository that is in your own github account and `upstream` for a repository that is in someone else's github account (used in the forking worklow). + +Now you are able to push your changes to the selected remote server i.e. your remote repository on GitHub. + +### 1.3 Pushing, pulling, fetching changes to/from Github + +To send any changes in a given branch on your local repository to your remote repository, go to that branch (``) and execute + +```shell +git push origin +``` + +However, this command will fail if there are changes in the remote repository that you do not have on your local machine. In that case you first need to get the changes from the remote repository to your local machine. To do so you do: + +```shell +git pull origin +``` + +As a best practice, you should always do this before you push any changes into the remote repository. + +If instead of getting the new changes from the remote repository into your local machine you just want to know if there are any changes, you can do + +```shell +git fetch origin +``` + +Then if you do `git diff origin/` it will tell you any differences between your local `` and `origin/` (i.e. the `` branch on your github repository). +If you then want to incorporate those changes with your local `` you do: + +```shell +git merge origin/ +``` + +Doing `git fetch` followed by `git merge` is equivalent to doing `git pull`. + +## Troubleshooting + +You could encounter errors if you do not follow the exact procedure as described above. + +```text +error: failed to push some refs to 'git@github.com:myrepo.git' +``` + +Solution: + +```shell +git pull origin +``` + +or + +```text +fatal: refusing to merge unrelated histories +``` + +Solution: + +```shell +git pull --allow-unrelated-histories +``` + +## 2 Branches + +### 2.1 Why Branches ? + +To expand. +Trees need branches to expand. +Banks needs (office) branches to expand. +Company needs (code) branches to expand. +E.g. Branches for Bugs, testing, features, production, staging etc. + +### 2.2 Types of Branches + +On your local machine, you've got three types of branches: + +1. local branches : non-tracking +2. local branches : tracking +3. remote-tracking branches + +On a remote machine, you have just one type of branch. + +### Types of Branches (1) Branches on your machine + +#### 2.2.1 Local branches + +To view a list of all the local branches on your machine, run + +```shell +git branch +``` + +There are two types of local branches on your machine: non-tracking local branches, and tracking local branches. + +##### 2.2.1.1 Non-tracking local branches + +Non-tracking local branches are not associated with any other branch in the remote repository. To create one, run + +```shell +git branch +``` + +##### 2.2.1.2 Tracking local branches + +Tracking local branches are associated with another branch on the remote repository, usually a remote-tracking branch. To convert an existing non-tracking local branch into a tracking local branch do: + +```shell +git branch -u / +``` + +Where `` will typically be `origin`. + +To view which one of your local branches are tracking branches, run + +```text + $ git branch -vv + master b31f87c85 [origin/master] "my sample commit" + new-feature b760e04ed "my branch is strong" +``` + +From this command's output, you can see that the local branch master is tracking the remote-tracking branch origin/master, and the local branch new-feature is not tracking anything. + +"Tracking local branches" are useful. They allow you to run `git pull` and `git push` without specifying which branch to use. + +#### 2.2.2 Remote-tracking branches (still on your machine) + +To view a list of all the remote-tracking branches on your machine, run + +```shell +git branch -a +``` + +Think of your remote-tracking branches as your local cache for what the remote machines contain. You can update your remote-tracking branches using `git fetch `, which `git pull` uses behind the scenes. +Even though all the data for a remote-tracking branch is stored locally on your machine (like a cache), it's still never called a local branch. (At least, I wouldn't call it that!). It's just called a remote-tracking branch. + +### 2.3.3 Branches on a remote machine + +To view all the remote branches (that is, the branches on the remote machine), run + +```text + $ git remote show origin + *remote origin + Fetch URL: git@github.com:Flimm/example.git + Push URL: git@github.com:Flimm/example.git + HEAD branch: master + Remote branches: + io-socket-ip new (next fetch will store in remotes/origin) + master tracked + new-branch tracked + Local ref configured for 'git pull': + master merges with remote master + new-branch merges with remote new-branch + Local ref configured for 'git push': + master pushes to master (up to date) + new-branch pushes to new-branch (fast-forwardable) +``` + +This git remote command queries the remote machine over the network about its branches. It does not update the remote-tracking branches on your local machine, use `git fetch origin ` or `git pull origin ` for that. +From the output, you can see all the branches that exist on the remote machine by looking under the heading "Remote branches" (ignore lines marked as "stale"). + +## 3. Pull requests + +Pull requests make it easier for developers to collaborate. They provide a user-friendly (web) interface for discussing proposed changes before integrating them into the official project. +In the simplest form, pull requests are a means for a developer to notify a team member that they have completed a feature. But the pull-request is more than just a notification. It's a dedicated forum where teammates can post feedback, push follow-up commits. +Even though it is named a pull request it is more like a merge request, where you ask for permission to merge a branch into another branch. + +### What does a pull request contain? + +When you create a pull request, you want another developer to pull a branch from your repository into their repository. This means that you need to provide 4 pieces of information to create a pull request: + +- the source repository +- the source branch +- the destination repository +- the destination branch + +Pull requests can be used in conjunction with various workflows: + +- [Feature-branch workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow) +- [Gitflow workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) +- [Forking workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/forking-workflow) + +## 4. Our workflow in the class + +The workflow you learned in class was pretty much the Feature-branch workflow, and most workflows out there are based on this one. + +In this workflow you never commit directly to the master branch. The master branch should always be working, no errors there. Imagine your website is using the code on master to run, you don't want it to break :) + +When you want to add a new feature, fix a bug, etc., you create a new branch and add your code there, and commit your changes as usual. +Once you are done with your task, you check if there are any new commits on master, and if so you get them into your branch. To do this you: + +- go to master (`git checkout master`) +- pull from master on github to update your local master (`git pull origin master`) +- go back to your branch (`git checkout `) +- merge the commits in your local master with your current branch (`git merge master`) + +After your branch is up do date with master you can push it to github (`git push origin `), and then on github you create a Pull Request from your branch to `master`. + +In your project, instead of `master` you'll probably have `develop` though. + +This is a scheme of what it looks like: + +![branches_diagram](images/branches_diagram.jpg) + +(As a shortcut you can pull directly from the remote master to your branch, just make sure it works :) ) + +## 5. Others + +### Git stash + +Sometimes you try to move to a different branch and git won't let you because the changes you have made in your current branch will be overwritten. + +In that case you have two options: to commit your changes or to stash them. + +If you don't want to commit yet, because you didn't finish what you were doing for example, you can stash your changes by doing `git stash`. Then you can go to another branch. + +When you want to get your changes back you can first do `git stash list` to see your list of "stashes", and then you select the stash that you want to get back by running: + +- `git stash pop stash@{}` - this will get your changes back and delete them from the stash list. +- `git stash apply stash@{}` - this will get your changes back without deleting them from the stash list. + +### HEAD + +The HEAD is basically a pointer that points to your latest commit in your current branch. + +### Git checkout + +The command `git checkout` is generally used to move somewhere in your repository: + +- to a branch: `git checkout ` +- to a specific commit: `git checkout ` + +To find the hash of the commit you want to move to use `git log`. + +However, when you move to a specific commit you get into a detached HEAD state, in this state you definitely should not do any commits. You should only look around, maybe run your code, and then go back to your latest commit using `git checkout `. + +Going back to specific commit can be useful to check what our code looked like back then. + +### Git reset + +You use `git reset` when you want to get rid of commits. + +There are three types of `git reset`: + +- `git reset --soft ` - will remove all commits until the commit with hash ``, but the file changes will stay in the staging/index area. +- `git reset --mixed `- will remove all commits until the commit with hash ``, but the file changes will stay in your filesystem. +- `git reset --hard `- will remove all commits until the commit with hash ``, as well as the changes in your files. Be very careful with this one! + +Bottom line: use the soft or mixed reset whenever you want, but think three times before using hard reset :) + +### Git revert + +You use `git revert ` when you want to revert what you did in a specific commit, with hash ``. + +This command will not remove any commits, instead it will create a new commit that undoes the selected commit (with hash ``) + +### Git cherry-pick + +You use `git cherry-pick ` when you want to copy a commit from another branch to the branch where you are. + +To get the commit hash you should go to the branch where the commit has been made and do `git log`. + +Then go to the branch where you want to "paste" the commit and do `git cherry-pick `. diff --git a/legacy/git/homework-submission.md b/legacy/git/homework-submission.md new file mode 100644 index 00000000..408405db --- /dev/null +++ b/legacy/git/homework-submission.md @@ -0,0 +1,76 @@ +# HOMEWORK SUBMISSION + +## TL;DR + +- [ ] Start any coding session from `main`. +- [ ] Periodically keep your local `main` up to date with changes in the remote `main`. +- [ ] Periodically merge the up-to-date local `main` into your homework branch. +- [ ] Always checkout to a new homework branch from `main`. +- [ ] Did we mention `main`? +- [ ] Implement the homework in the right folder. +- [ ] Write meaningful commit messages. +- [ ] Before pushing, double check that your branch name is correct. +- [ ] If the branch name is not correct, you can checkout to a new, correct branch from the current branch - you will carry all the commits with you. +- [ ] If your PR has been auto-closed, do not reopen it. Follow the guidlines and make a proper PR. +- [ ] Stay patient. Slack, Google and ChatGPT are your best friends now. +- [ ] Make the changes as per PR review in the appropriate branch, push the changes to the appropriate branch, and close the PR. + +## Before you start your homework + +1. You are probably opening the local repo on the last weeks branch - make sure that any changes you have there are either committed and pushed, or stashed, or discarded - whatever you prefer. The point is to be mindful that: + +- you are most probably starting on a branch you last worked with, that is how VS Code works, +- and there might be changes that you have not handled last time. + +2. Checkout to `main` and pull the latest changes from it. If you skip this step, you will get in trouble sooner or later. + +3. Checkout to your new homework branch, following the branch naming convention of `module-week/yourname`. If `week` is not applicable, it is obviously just `module/yourname`. See [allowed branch name prefixes](#allowed-branch-name-prefixes). + +❗ If you name the branch incorrectly, your PR might get automatically closed (soon after opening), depending on the configurations that are set up at that moment in your homework repo. It is your responsibility to monitor it and, if needed, open a new PR from a new correctly-named branch. **Do not reopen the closed PR**. + +❗ Always firstly checkout to the new homework branch from an updated `main`. Always. + +### Allowed branch name prefixes + +| | | | | +| ----------------- | ----------------- | ----------------- | ----------------- | +| git-week1 | git-week2 | | | +| javascript1-week1 | javascript1-week2 | javascript1-week3 | javascript1-week4 | +| javascript2-week1 | javascript2-week2 | javascript2-week3 | | +| typescript | | | | +| databases-week1 | databases-week2 | databases-week3 | | +| node-week1 | node-week2 | node-week3 | | +| react1-week1 | react1-week2 | react1-week3 | | +| react2-week1 | react2-week2 | react2-week3 | | + +### Examples + +- ❌ git/weeek1/maria +- ❌ javascript1/maria +- ❌ git-week2 +- ❌ node-week1-homework +- ❌ react2-week4/maria +- ❌ react1week1/maria +- βœ… javascript1-week3/maria + +## Completing and submitting your homework + +1. Implement your homework in the right folder. Be mindful of structuring and naming. + +2. If you take a longer time to finish the homework, periodically update your local `main` and your homework branch with `main`. Google "update your feature branch with main". The feature branch in this case is your homework branch. + +3. Verify that your branch name is right. Commit and push your homework to the repository. If the branch name is not right, you can commit and checkout to a new, correct branch from the current branch - you will carry all the commits with you. Then you can push. + +4. Go to the homework repository and create a Pull Request from your homework branch to `main`. + +5. Post the link to the PR to your class channel and celebrate with your classmates! πŸŽ‰ πŸ’ƒπŸ½ πŸ•ΊπŸΎ πŸ₯³ + +## After submitting your homework + +1. Follow the PR to see the review (if you submitted it on time) and interact with the reviewer as well as make the suggested changes. + +2. When you have made changes to the code since the homework submission and review, push the changes and close the PR without merging`*`. + +> `*` Why you should close the PR _without_ merging? PRs are normally intended to merge code! +> +> It's because you are sharing a central homework repository. We do not aim to merge all your homeworks into one clump - that does not make any sense and would be a very chaotic process as you are implementing your homeworks in the same folders, and some of you might even have the same naming. The more you understand about Git, the more this will make sense. The point here is just to have a convenient submission process while you also practise shared repository handling every week. diff --git a/legacy/html-and-css/Pre-course/README.md b/legacy/html-and-css/Pre-course/README.md new file mode 100644 index 00000000..92544b25 --- /dev/null +++ b/legacy/html-and-css/Pre-course/README.md @@ -0,0 +1,84 @@ +# Pre-course materials + +This section lists the steps you have to complete **BEFORE** the bootcamp starts. + +You are going to be fully self-learning `HTML` and `CSS`, so it is very important and **mandatory** that you complete the steps before the first sunday session at HackYourFuture. + +You will also get a little introduction to `Javascript`, so that you can be more comfortable jumping into it when the course starts. + +## HTML and CSS + +### freeCodeCamp certifications + +The `freeCodeCamp` courses are a good way to learn and their certifications are widely recognized, therefore we use this platform to give you a good start with learning `Web Development` and having a way to showcase your learning. + +### What you have done so far + +There are 5 parts in the [Responsive Web Design certification](https://www.freecodecamp.org/learn/2022/responsive-web-design/). Each part contains a few sections and a certification project at the end of each part. +You have already finished at least 2 sections from the first part as part of the application assignment: + +- [Learn HTML by Building a Cat Photo App](https://www.freecodecamp.org/learn/2022/responsive-web-design/learn-html-by-building-a-cat-photo-app/) + +- [Learn Basic CSS by Building a Cafe Menu](https://www.freecodecamp.org/learn/2022/responsive-web-design/learn-basic-css-by-building-a-cafe-menu/) + +### What you have to do before the first Sunday session + +You should finish the first part and the certification project that goes with it: + +- [Learn CSS Colors by Building a Set of Colored Markers](https://www.freecodecamp.org/learn/2022/responsive-web-design/learn-css-colors-by-building-a-set-of-colored-markers) + +- [Learn HTML Forms by Building a Registration Form](https://www.freecodecamp.org/learn/2022/responsive-web-design/learn-html-forms-by-building-a-registration-form) + +- [Certification Project - Survey Form](https://www.freecodecamp.org/learn/2022/responsive-web-design/build-a-survey-form-project/build-a-survey-form) + +This will familiarise you with `CSS` colors and building `Forms` with `HTML` and `CSS`, which are both essential parts of basic Web Development knowledge. + +You should also complete 2 more sections from the second part: + +- [Learn the CSS Box Model by Building a Rothko Painting](https://www.freecodecamp.org/learn/2022/responsive-web-design/learn-the-css-box-model-by-building-a-rothko-painting) +- [Learn CSS Flexbox by Building a Photo Gallery](https://www.freecodecamp.org/learn/2022/responsive-web-design/learn-css-flexbox-by-building-a-photo-gallery) + +Learning the CSS Box Model and Flexbox will give you very good foundational knowledge to deal with any styling or layout challenge. + +## JavaScript + +Complete these steps in the freeCodeCamp [JavaScript Algorithms and Data Structures certification](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/): + +- [Comment Your JavaScript Code](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/comment-your-javascript-code) +- [Declare JavaScript Variables](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/declare-javascript-variables) +- [Storing Values with the Assignment Operator](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/storing-values-with-the-assignment-operator) +- [Assigning the Value of One Variable to Another](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/assigning-the-value-of-one-variable-to-another) +- [Initializing Variables with the Assignment Operator](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/initializing-variables-with-the-assignment-operator) +- [Declare String Variables](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/declare-string-variables) +- [Understanding Uninitialized Variables](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/understanding-uninitialized-variables) +- [Understanding Case Sensitivity in Variables](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/understanding-case-sensitivity-in-variables) +- [Explore Differences Between the var and let Keywords](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/explore-differences-between-the-var-and-let-keywords) +- [Declare a Read-Only Variable with the const Keyword](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/declare-a-read-only-variable-with-the-const-keyword) +- [Add Two Numbers with JavaScript](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/add-two-numbers-with-javascript) +- [Subtract One Number from Another with JavaScript](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/divide-one-number-by-another-with-javascript) +- [Multiply Two Numbers with JavaScript](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/multiply-two-numbers-with-javascript) +- [Divide One Number by Another with JavaScript](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/divide-one-number-by-another-with-javascript) +- [Increment a Number with JavaScript](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/increment-a-number-with-javascript) +- [Decrement a Number with JavaScript](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/decrement-a-number-with-javascript) +- [Create Decimal Numbers with JavaScript](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/create-decimal-numbers-with-javascript) +- [Multiply Two Decimals with JavaScript](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/multiply-two-decimals-with-javascript) +- [Divide One Decimal by Another with JavaScript](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/divide-one-decimal-by-another-with-javascript) +- [Finding a Remainder in JavaScript](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/finding-a-remainder-in-javascript) +- [Compound Assignment With Augmented Addition](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/compound-assignment-with-augmented-addition) +- [Compound Assignment With Augmented Subtraction](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/compound-assignment-with-augmented-subtraction) +- [Compound Assignment With Augmented Multiplication](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/compound-assignment-with-augmented-multiplication) +- [Compound Assignment With Augmented Division](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/compound-assignment-with-augmented-division) + +If you like the `freeCodeCamp` format, you should definitely continue beyond what we ask of you and attain the various relevant certifications - especially by finishing off the **Responsive Web Design** and **Javascript Algorithms and Data Structures** certifications! + +### Submitting your preparation + +Before the first Sunday session, you must have completed all the steps listed above. You then need to make your freeCodeCamp profile public - [Video here to show you how to do this](https://www.loom.com/share/019547eab49e4e198fd2d24f6cb27d3c) - and post a link to your profile in your class Slack channel. If you do not do this before the first Sunday session, you will not be able to continue with the course. + +### What if? + +- If you have completed all these parts already, just continue further with the certifications. You are here to learn after all and you are entering a journey of self-teaching! + +- If you have not completed the steps listed above from the `Responsive Web Design` ceritification and the `JavaScript Algorithms and Data Structures` certification by the time of the first Sunday session, you will not be able to continue with the course. + +- Stuck or need help? Please use your class Slack channel to ask for help from your fellow students. Asking for help, explaining the problems you have, and sharing your own knowledge with your fellow students are all very important to succeed in HackYourFuture, so start practicing right now! diff --git a/legacy/html-and-css/README.md b/legacy/html-and-css/README.md new file mode 100644 index 00000000..7bd5b19d --- /dev/null +++ b/legacy/html-and-css/README.md @@ -0,0 +1,15 @@ +# HTML-CSS + +This repository contains the course material for the one and only HTML/CSS session. During the session we will review the concepts learned from the [Pre-course](./Pre-course/README.md) materials and work hands-on with a large [exercise](./The-one-and-only-week1/README.md). + +| Week | Topic | Preparation | Lesson Plan | Homework | +| ---- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------ | ------------------------------------------------- | ------------------------- | +| 1. | Advanced HTML & CSS concepts, hands-on exercise turning Figma Wireframe into code, teamwork & peer-learning | [Pre-course](./Pre-course/README.md) | [Lesson Plan](./The-one-and-only-week1/README.md) | [Homework](./homework.md) | + +## Learning goals + +- Round-up the [Pre-course](./Pre-course/README.md) materials +- Talk about any possible questions regarding the concepts learned so far +- Briefly introduce Figma +- Spend a lot of time with hands-on coding, figuring out the [exercise](./The-one-and-only-week1/README.md) +- Learn to work efficiently with your teammates diff --git a/legacy/html-and-css/The-one-and-only-week1/README.md b/legacy/html-and-css/The-one-and-only-week1/README.md new file mode 100644 index 00000000..58e8a9f2 --- /dev/null +++ b/legacy/html-and-css/The-one-and-only-week1/README.md @@ -0,0 +1,10 @@ +# Order form exercise + +Use the `Session-exercise-template` to get started! + +Design: + + +![Desktop design](Session-exercise-template/images/order-desktop.png) + +![Mobile design](Session-exercise-template/images/order-mobile.png) diff --git a/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/cards.png b/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/cards.png new file mode 100644 index 00000000..c352c20f Binary files /dev/null and b/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/cards.png differ diff --git a/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/images/order-desktop.png b/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/images/order-desktop.png new file mode 100644 index 00000000..5e0b4cca Binary files /dev/null and b/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/images/order-desktop.png differ diff --git a/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/images/order-mobile.png b/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/images/order-mobile.png new file mode 100644 index 00000000..2c061632 Binary files /dev/null and b/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/images/order-mobile.png differ diff --git a/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/order.css b/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/order.css new file mode 100644 index 00000000..d8c26ae7 --- /dev/null +++ b/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/order.css @@ -0,0 +1,4 @@ +/* var(--gradient) */ +/* :root { + --gradient: your gradient color here; +} */ diff --git a/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/order.html b/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/order.html new file mode 100644 index 00000000..347de4df --- /dev/null +++ b/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/order.html @@ -0,0 +1,62 @@ + + + + + + + PAYMENT <span>FORM</span> + + + +
+
+
+ +
+
+

Payment Method

+
+ +
+

Card Info

+
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + +

Need Help?

+
+ + diff --git a/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/paypal.png b/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/paypal.png new file mode 100644 index 00000000..94588ef5 Binary files /dev/null and b/legacy/html-and-css/The-one-and-only-week1/Session-exercise-template/paypal.png differ diff --git a/legacy/html-and-css/first-homework-submission.md b/legacy/html-and-css/first-homework-submission.md new file mode 100644 index 00000000..9d969f6a --- /dev/null +++ b/legacy/html-and-css/first-homework-submission.md @@ -0,0 +1,48 @@ +# How to submit the first homework + +While you have not gone through [Git](https://github.com/HackYourFuture-CPH/Git) yet, you will submit your first homework in a different way. This applies only to the first homework. If you are confident with basic Git already, feel free to do the submission in a proper version-control way. + +`1.` Go to your homework repository`*` on github and to the branches section: + +![screenshot](images/image.png) + +`2.` Find the "New branch" button and create a new branch, that follows the naming convention: + +`html-css/yourname` + +- ❌ html/css/maria +- ❌ hmtl-css/maria +- ❌ html-css-homework +- ❌ html/maria +- ❌ htmlcss/maria +- βœ… html-css/maria + +`3.` Go to the branch. It appears in the branch overview right after creation: + +![screenshot](./images/image-1.png) + +Or, if you are not there for some reason, go back to the repository overview and find your new branch in the drop-down: + +![screenshot](./images/image-2.png) + +To verify that you have switched to the branch, it should appear selected: + +![screenshot](./images/image-3.png) + +`4.` Go to the html-css folder and upload your homework: + +![screenshot](./images/image-4.png) + +`5.` Write a commit message and press "Commit changes": + +![screenshot](./images/image-5.png) + +`6.` Go to "Pull requests" in the repository bar, and create a new pull request to the main branch <- from your branch: + +![screenshot](./images/image-6.png) + +`7.` That is it! You should see your pull request listed in the "Pull requests" tab. + +`8.` Post a link to your homework Pull Request in your class channel. + +`*` It is either your own homework repository in your own GitHub account or the central class homework repository in the HackYourFuture-CPH GitHub account - depending on what approach is being followed for your class. Follow the information and instructions regarding this, and ask if you are still unsure. diff --git a/legacy/html-and-css/homework.md b/legacy/html-and-css/homework.md new file mode 100644 index 00000000..05ff4d0b --- /dev/null +++ b/legacy/html-and-css/homework.md @@ -0,0 +1,33 @@ +# HOMEWORK + +Make your own `Developer CV / Portfolio page`! + +There is a long way to go in the learning journey, but why not start with a good online presence from the get-go? + +Make it as extravagant as you like and look around the internet for inspiration (f.x. [here](https://scrimba.com/articles/web-developer-portfolio-inspiration)), while the **minimum requirements** are: + +- [ ] Two files: .html and .css +- [ ] Navigation bar leading to different parts of the single-page website +- [ ] Header element with your name and title +- [ ] Contact section that also includes the most important SoMe links +- [ ] Short description section +- [ ] Skill showcase section highlighting your technical skills +- [ ] Portfolio section having the [FCC Survey Form](https://www.freecodecamp.org/learn/2022/responsive-web-design/build-a-survey-form-project/build-a-survey-form) as the first project.`*` +- [ ] Advanced CSS and/or animations applied to implement interesting interactive elements +- [ ] Website responsiveness so it looks good on different screen sizes and devices +- [ ] Deploy your page on [Netlify](https://www.netlify.com)! + +`*` it is not advisable to have tutorial or course projects in your portfolio, you should make sure to have unique and interesting self-driven projects. However, it is a bit too early for that. Start with the "Survey Form" and keep building and extending your project portfolio as you learn! + +❗ Remember: you have to submit the homework during the week, before the weekend, so plan your workload accordingly. You can keep working on this portfolio in the future, so just focus on doing a nice initial version for now! + +Check [the first homework submission](https://github.com/HackYourFuture-CPH/HTML-CSS/blob/main/first-homework-submission.md) instructions to make sure to submit the homework correctly! + +**Small tip:** + +- Got to [Loom.com](https://www.loom.com/) and download the app or plugin. +- It's a great way to quickly share explainer videos or explain issues you are facing. + +Good luck! ✌️ + +![Jim Carrey as the eponymous "Bruce Almighty", busily typing away](https://media.giphy.com/media/13GIgrGdslD9oQ/giphy.gif) diff --git a/legacy/html-and-css/images/image-1.png b/legacy/html-and-css/images/image-1.png new file mode 100644 index 00000000..7e86a9f8 Binary files /dev/null and b/legacy/html-and-css/images/image-1.png differ diff --git a/legacy/html-and-css/images/image-2.png b/legacy/html-and-css/images/image-2.png new file mode 100644 index 00000000..c56efa49 Binary files /dev/null and b/legacy/html-and-css/images/image-2.png differ diff --git a/legacy/html-and-css/images/image-3.png b/legacy/html-and-css/images/image-3.png new file mode 100644 index 00000000..e16c592a Binary files /dev/null and b/legacy/html-and-css/images/image-3.png differ diff --git a/legacy/html-and-css/images/image-4.png b/legacy/html-and-css/images/image-4.png new file mode 100644 index 00000000..16089511 Binary files /dev/null and b/legacy/html-and-css/images/image-4.png differ diff --git a/legacy/html-and-css/images/image-5.png b/legacy/html-and-css/images/image-5.png new file mode 100644 index 00000000..772e8213 Binary files /dev/null and b/legacy/html-and-css/images/image-5.png differ diff --git a/legacy/html-and-css/images/image-6.png b/legacy/html-and-css/images/image-6.png new file mode 100644 index 00000000..98e6e94f Binary files /dev/null and b/legacy/html-and-css/images/image-6.png differ diff --git a/legacy/html-and-css/images/image-7.png b/legacy/html-and-css/images/image-7.png new file mode 100644 index 00000000..1934d43e Binary files /dev/null and b/legacy/html-and-css/images/image-7.png differ diff --git a/legacy/html-and-css/images/image.png b/legacy/html-and-css/images/image.png new file mode 100644 index 00000000..cf76fdd0 Binary files /dev/null and b/legacy/html-and-css/images/image.png differ diff --git a/legacy/javascript/README.md b/legacy/javascript/README.md new file mode 100644 index 00000000..2e614fad --- /dev/null +++ b/legacy/javascript/README.md @@ -0,0 +1,3 @@ +# javascript + +TODO diff --git a/legacy/nodejs/README.md b/legacy/nodejs/README.md new file mode 100644 index 00000000..3a0cc7f3 --- /dev/null +++ b/legacy/nodejs/README.md @@ -0,0 +1,52 @@ +# NodeJS - Fullstack development + +For almost any web application, it is essential to have a backend. The backend is a place where we, the developers, can store our data, communicate with users and let the users communicate with us, do smart things like calculations, data processing etc. + +There are many languages for this. We might've heard of Java, C, C++, Go, Python, Ruby, PHP and the list goes on. +There are two reasons why we at HYF choose Node.JS over others: + +1. You already know JavaScript, so it's easier to get started than other languages +2. Node.js is great for making web APIs because it is asynchronous by nature and thus allows for high input/output. By this we mean that it allows many users to make very light requests at the same time. + +In this 3-week module, we will use NodeJS to create and connect both the backend api and serve the frontend html, css and javascript. +Most of this course will focus on the backend part. Meaning building a webserver that has an api connected to a database. + +`Database <--> Webserver` + +## Planning + +| Week | Topic | Preparation | Homework | Lesson plan | +| ---- | ----------------------------------------------- | ----------------------------------- | ------------------------------------ | ----------------------------------- | +| 1. | HTTP; Introduction to node js; Simple webserver | [Preparation](week1/preparation.md) | [Homework](week1/homework/readme.md) | [Lesson plan](week1/lesson-plan.md) | +| 2. | Express | [Preparation](week2/preparation.md) | [Homework](week2/homework/readme.md) | [Lesson plan](week2/lesson-plan.md) | +| 3. | Database connection; API | [Preparation](week3/preparation.md) | [Homework](week3/homework/readme.md) | [Lesson plan](week3/lesson-plan.md) | + +## Pre-requisites + +We will build on knowledge from the following HYF (sub)modules. If we feel we have gaps we should review the curriculum ourselves or ask a teacher to help. + +- [JavaScript](https://github.com/HackYourFuture-CPH/JavaScript) +- [Git](https://github.com/HackYourFuture-CPH/git) +- [CommandLine](https://github.com/HackYourFuture-CPH/CommandLine) + +## What will we learn? + +- What is Node.js? +- Using Node Package Manager (NPM) +- Using `import` to include modules +- Using `express` to make a RESTful API +- Using `mysql` to connect the API to the backend +- Postman + +## Extra practice + +If you have the time, you could follow another simple set of exercises to get a better grasp of Node.js and some more practice. +Feel free to bring any questions from this to the class or raise them on slack! + +Clone the repository that holds the exercises templates: + +See each week's `readme.md` and follow the instructions to setup the server. + +--- + +_Please help us improve and share your feedback! If you find better tutorials or links, please share them by opening a Pull Request._ diff --git a/legacy/nodejs/assets/deploy-step-1.PNG b/legacy/nodejs/assets/deploy-step-1.PNG new file mode 100644 index 00000000..428593cb Binary files /dev/null and b/legacy/nodejs/assets/deploy-step-1.PNG differ diff --git a/legacy/nodejs/assets/deploy-step-2.PNG b/legacy/nodejs/assets/deploy-step-2.PNG new file mode 100644 index 00000000..6a78e6d5 Binary files /dev/null and b/legacy/nodejs/assets/deploy-step-2.PNG differ diff --git a/legacy/nodejs/assets/deploy-step-3.PNG b/legacy/nodejs/assets/deploy-step-3.PNG new file mode 100644 index 00000000..71488ec5 Binary files /dev/null and b/legacy/nodejs/assets/deploy-step-3.PNG differ diff --git a/legacy/nodejs/assets/deploy-step-4.PNG b/legacy/nodejs/assets/deploy-step-4.PNG new file mode 100644 index 00000000..8b1239f0 Binary files /dev/null and b/legacy/nodejs/assets/deploy-step-4.PNG differ diff --git a/legacy/nodejs/assets/deploy-step-5.PNG b/legacy/nodejs/assets/deploy-step-5.PNG new file mode 100644 index 00000000..dbc3cec9 Binary files /dev/null and b/legacy/nodejs/assets/deploy-step-5.PNG differ diff --git a/legacy/nodejs/assets/deploy-step-6.PNG b/legacy/nodejs/assets/deploy-step-6.PNG new file mode 100644 index 00000000..f2e88e1a Binary files /dev/null and b/legacy/nodejs/assets/deploy-step-6.PNG differ diff --git a/legacy/nodejs/week1/exercises/01-server.md b/legacy/nodejs/week1/exercises/01-server.md new file mode 100644 index 00000000..fafe902b --- /dev/null +++ b/legacy/nodejs/week1/exercises/01-server.md @@ -0,0 +1,71 @@ +# Server + +Create a new, separate folder somewhere on your machine: + +```shell +mkdir nodejs-week1 +code nodejs-week1 # to open the folder in VS Code +``` + +You can also reuse some other folder. Main thing to watch out for is that the folder you decide to use should ideally be empty. + +--- + +Initialize and install: + +```shell +npm init -y +npm pkg set type="module" +npm install express +echo node_modules/ >> .gitignore +``` + +Make sure you see a `package.json`. +Make sure you have `"type": "module"` in your `package.json`. +Do you see `express` somewhere in `package.json`? +Make sure you see the `node_modules` folder. +Also make sure that the `node_modules/` folder is ignored by Git. + +--- + +Create a file called `app.js`: + +```js +import express from "express"; +const app = express(); +const port = 3000; + +app.get("/", (req, res) => { + res.send("Hello Class!"); +}); + +app.listen(port, () => { + console.log(`Listening on port ${port}`); +}); +``` + +Start your server! + +```shell +node app.js +``` + +Go to in your browser to verify that everything is working as expected. + +Press Ctrl-C to shut down the server. + +--- + +**Task:** + +- Add a `/info` route to `app.js`. +- It should respond with a **JSON object** containing the Node.js version; something like this: `{ "nodeVersion": "v17.3.0" }` +- You can get the Node.js version from `process.version` + +To test that the response is indeed JSON, you can use Postman or cURL: + +```shell +curl -i localhost:3000/info +``` + +The response `Content-Type` header should look like this: `Content-Type: application/json; charset=utf-8`. diff --git a/legacy/nodejs/week1/exercises/02-database.md b/legacy/nodejs/week1/exercises/02-database.md new file mode 100644 index 00000000..4a352fea --- /dev/null +++ b/legacy/nodejs/week1/exercises/02-database.md @@ -0,0 +1,48 @@ +# Database + +Now we want to connect to a MySQL database from Node.js. + +First we need to install some packages: + +```shell +npm install mysql2 knex +``` + +--- + +Create a new MySQL database named `hyf_node_week1`. +In `app.js` we can now establish the database connection. +Add the following to the top of `app.js`: + +```js +import knex from "knex"; +const knexInstance = knex({ + client: "mysql2", + connection: { + host: "127.0.0.1", + port: 3306, + user: "your_database_user", + password: "your_database_password", + database: "hyf_node_week1", + }, +}); + +// The code from before is down here +// [...] +``` + +--- + +Using `knex.raw` we can now execute SQL queries. +Let's extend the `/info` route to also respond with the MySQL version: `{ "nodeVersion":"v17.3.0", "mysqlVersion":"8.0.30" }` + +```js +app.get("/info", async (req, res) => { + const [rows] = await knexInstance.raw("SELECT VERSION()"); + + res.json({ + nodeVersion: process.version, + mysqlVersion: rows[0]["VERSION()"], + }); +}); +``` diff --git a/legacy/nodejs/week1/exercises/03-user-routes.md b/legacy/nodejs/week1/exercises/03-user-routes.md new file mode 100644 index 00000000..67346f5f --- /dev/null +++ b/legacy/nodejs/week1/exercises/03-user-routes.md @@ -0,0 +1,63 @@ +# User routes + +## Note on server restarts + +It is annoying to shutdown the server with Ctrl-C and start it again every time you make a change and want to test the change: + +```shell +npm install --save-dev nodemon +``` + +Also, it is recommended to add a script to `package.json`, like so: + +```json +"scripts": { + "dev": "nodemon app.js" +} +``` + +There is a command to do that: + +```shell +npm pkg set scripts.dev="nodemon app.js" +``` + +Now you can run + +```shell +npm run dev +``` + +to start a server that automatically restarts when you make changes πŸŽ‰ + +## Schema + +Create a `users` table with the following fields: + +- `id` (primary key) +- `created_at` +- `confirmed_at` (can be `NULL`) +- `first_name` +- `last_name` +- `email` (unique) + +## Routes + +- `/all-users` should respond with all users sorted by ID +- `/unconfirmed-users` should respond with unconfirmed users +- `/gmail-users` should respond with users with an @gmail.com email +- `/2022-users` should respond with users created in 2022 + +--- + +## More routes + +- `/user-count` should respond with the number of users +- `/last-name-count` should respond with how many users there are with a given last name, sorted alphabetically +- `/first-user` should respond with the first user. If there are no users in the table, respond with a 404 + +## Frontend <-> Backend integration + +Turn the `/` route into a HTML page that fetches the count value from `/user-count` and shows it. Feel free to style this in whatever way you see fit. + +Optional: update the count every 2 seconds or something like that. diff --git a/legacy/nodejs/week1/homework/readme.md b/legacy/nodejs/week1/homework/readme.md new file mode 100644 index 00000000..87c34b9a --- /dev/null +++ b/legacy/nodejs/week1/homework/readme.md @@ -0,0 +1,105 @@ +# Week 1 homework + +This homework will result in 2 pull requests: + +- A pull request for the **Warmup** - in your regular hyf-homework repository +- A pull request for the **meal sharing endpoints** - in a newly created meal-sharing repository + +## meal-sharing repository + +Go to the [HYF project template repository](https://github.com/HackYourFuture-CPH/hyf-project-template) and click the "Use this template" button, then the "Create a new repository" option. + +In the field `Repository name` fill in "meal-sharing", and mark the repository as "Public" before clicking "Create repository". + +You should now have a new repository based on this template that you can clone to your local machine using: + +```shell +git clone git@github.com:YOUR_GITHUB_USER_NAME/meal-sharing.git +``` + +### Branch + +For us mentors to easily give feedback on your code, create all functionality in a PR just like we do normally with homework, so: + +- `git checkout -b nodejs-week1` <- in the meal-sharing repo you have cloned down. +- Make your code in the `nodejs-week1` branch and when you are done create a PR with the `nodejs-week1` branch. + +## Warmup + +In your hyf-homework repository, `nodejs/week1` directory, create a file named `avg.js` which will calculate the average of the numbers provided as command line arguments. + +But what are command line arguments? They are simple parameters that we can pass to command line programs, which can be either values or files. Here's an example of how we would invoke `avg.js` with 3 numbers: + +```text +$ node avg.js 13 7 4 +8 +``` + +Hint: [read](https://tecadmin.net/how-to-parse-command-line-arguments-in-nodejs/) to see how we can deal with command line arguments. + +Optional improvements and considerations: + +- What should happen if the provided arguments are not numbers (`node avg.js 1 two hello 4`)? +- What about if no arguments are provided (`node avg.js`)? + +## Meal sharing endpoints + +You will begin working in the meal-sharing repository for this homework and continue throughout the whole Node.js module. +Each week you will extend the endpoints, resulting in the backend setup for your future meal sharing website. + +### Setup + +Please follow the instructions in the [README.md](https://github.com/HackYourFuture-CPH/hyf-project-template/blob/main/README.md) in your meal-sharing repository to get your environment ready. You can ignore the "Deploying" section for now, you will come back to that in a few weeks. + +#### Database + +In the Database module, we worked on the meal sharing database. The diagram for that database can be found [here](https://dbdiagram.io/d/5f0460690425da461f045a29). + +In this homework, we will **reuse the same database** schema and build an API server with the below routes. + +#### Getting started + +The routes you need to implement as part of this homework should go into `/api/src/index.js`. +You can go ahead and define the desired routes like you normally would using the `app` variable: + +```js +app.get("/my-route", (req, res) => { + res.send("Hi friend"); +}); +``` + +### Routes + +| Route | Description | +| --------------- | ---------------------------------------------------------------------- | +| `/future-meals` | Respond with all meals in the future (relative to the `when` datetime) | +| `/past-meals` | Respond with all meals in the past (relative to the `when` datetime) | +| `/all-meals` | Respond with _all_ meals sorted by ID | +| `/first-meal` | Respond with the first meal (meaning with the minimum `id`) | +| `/last-meal` | Respond with the last meal (meaning with the maximum `id`) | + +### Responses + +All the specified routes should respond with JSON with the available columns from the meal table. + +**Multiple meals:** `/future-meals`, `/past-meals` and `/all-meals` are expected to respond with a collection of meals, meaning an array of objects. + +**Single meal:** The other 2 routes, `/first-meal` and `/last-meal`, are expected to respond with a single meal, meaning an object. + +**What if there are no meals?:** `/first-meal` and `/last-meal` should in that case return a 404 response with an explanation that there are no meals. +The other routes should in that case just return an empty array. + +#### Knex + +Our usage of Knex will get more advanced over the coming weeks but for now, we will focus on the simplified `knex.raw` function that can execute a raw SQL query. Example: + +```js +const meals = await knex.raw("SELECT * FROM Meal"); +console.log(meals); +``` + +## Hand in homework + +Need to brush up on the homework hand-in process? + +Check [this resource](https://github.com/HackYourFuture-CPH/Git/blob/main/homework-submission.md) to remember how to hand in the homework correctly! diff --git a/legacy/nodejs/week1/lesson-plan.md b/legacy/nodejs/week1/lesson-plan.md new file mode 100644 index 00000000..f4b97d52 --- /dev/null +++ b/legacy/nodejs/week1/lesson-plan.md @@ -0,0 +1,152 @@ +# Lesson plan + +- Focus on having lots of in class exercises. +- DONT teach everything, let the students investigate topics on their own aswell! +- Focus on how to read documentation, google answers and google errors!! +- Teach towards the students being able to solve the homework + +Remember to add the code you wrote in the class to the relevant class branch's class work folder. If the branch has not been created just create and push it :) If you dont have access, write to one from the core team. You can see an example below! + +To find examples of what teachers have taught before go to the class branches in the classwork folder, Fx [class 07](https://github.com/HackYourFuture-CPH/JavaScript/tree/class07/JavaScript1/Week1/classwork) + +If you find anything that could be improved then please create a pull request! We welcome changes, so please get involved if you have any ideas!!! + +## Introduction + +In the first week of the module we will focus on a general introduction starting from what happens when you open a webpage in the browser, an introduction to the underlying protocol HTTP (the roads of the internet) as well as an introduction to what can be build with node. + +## Learning goals + +- [ ] What happens when you open a webpage? + - Client sends http request to a url + - The request is directed to the correct ip using DNS + - The server reads the request and sends a respond + - Show a simple request and response in Chrome dev tools +- [ ] HTTP - What is the internet + - [ ] Client + - Sends request + - Receives response + - [ ] HTTP server + - Listen for requests + - Responds with data + - +- [ ] Introduction to node js + - [ ] [What is node and why node?](https://www.youtube.com/watch?v=pU9Q6oiQNd0) + - [ ] V8 vs the browser that runs js? + - [ ] What can you build with nodejs? + - Utilities + - Web server + - Much more +- [ ] Simple webserver with node js + - [ ] npm init + - [ ] Tests + - [ ] Modules + - [ ] Creating and importing using `export` and `import` in modern ES6 syntax + - [ ] [Live coding](#created-module) + - [ ] Npm modules + - npmjs.org + - `npm install -s express` + - node_modules + - package.json + - [.gitignore](https://github.com/HackYourFuture-CPH/teacher-live-coding/blob/main/.gitignore) + - [ ] Nodemon + - [ ] Express - Simple `GET` requests + +### What is backend? + +In software development, we separate the user experience and utility (the `frontend`) from the code that actually makes it work (the `backend`). The real world contains many examples of this division: take for example an [ATM](../images/atm.jpg). What you can interact with it (press a button or insert a card), you are dealing with the `user interface`; which is the end result of frontend code. However, everything that's needed to make it work like that is found within the device: this is the hardware and software needed to make it work the way it does. + +In web development the term backend can be boiled down to 3 components: + +- A `server`: a computer that is connected to other computers, which runs an application (see below) that allows for sharing and managing services (like a calculator or word processor) and resources (like images, text files). +- A `database`: software that manages and saves sensitive data for later use. +- An `application`: software that communicates between the server, database and frontend. It contains code that allows it to interact with and manipulate the server, database and other type of software services. + +For more information, read: + +- [Basics of backend development](https://www.upwork.com/hiring/development/a-beginners-guide-to-back-end-development/) +- [Getting started with backend development](https://codeburst.io/getting-started-with-backend-development-bfd8299e22e8) + +When people refer to backend programming, they usually refer to **writing the application** part of the backend: the software that interacts with a server and database, and moves data from one computer to the next. The application consists of code that will be read by a database and/or server, so that they know what to do with the incoming input. + +Why would we need a backend? There are multiple reasons: + +- **Security**. We don't want any random user to directly access our sensitive data, without verifying who they are. For example, if you have an online back account then you need to login to verify it's you. The whole process of login and verification is code written in a place that can't be reached so easily. +- **Performance**. The speed of our user interfaces is greatly dependent upon the server that provides it. The backend contains code that makes sure it optimally makes use of the server's resources (hardware, memory, etc.) to provide the user with the best experience. +- **Software interactions**. A web application usually makes use of other people's software, web services. The code that communicates with these services and implements it into the frontend is also contained within the backend. + +For more information, read: +[Why do we need the backend?](https://www.quora.com/Why-do-we-need-a-back-end-in-web-development-Cant-the-front-end-directly-send-requests-to-the-database) + +### What is Node.js? + +Node.js is software that allows you to use JavaScript to write the `application` part of the backend. The application is written in different _.js_ files, and are then read and executed using the _node_ command in the Command Line. For example, `node script.js`. + +Read the following article and code along: [Introduction into Node.js](https://codeburst.io/the-only-nodejs-introduction-youll-ever-need-d969a47ef219) + +Software builds on other software. Node.js is powerful because it allows us to use software others have written to help build our own unique applications. In Node.js these are called `modules`/`packages`/`dependencies` (can be used interchangeably). An easy way to get access to these is by using the Node Package Manager, also known as `npm`. + +Read the following article and code along: [A Beginner’s Guide to npm β€” the Node Package Manager](https://nodesource.com/blog/an-absolute-beginners-guide-to-using-npm/) + +It is also powerful because we can use the language we already know, JavaScript, to write backend applications. Watch the following video and code along: [Node.js Crash Course](https://www.youtube.com/watch?v=fBNz5xF-Kx4) + +### The client-server model + +The client-server model is one of the most important concepts within web development. The easiest way to explain this concept is by using an analogy. + +> Let's say you are hungry and feel like going to a restaurant. The moment you enter the restaurant you are a customer, or in IT terms a `client`. You take a seat and decide to order various things, each order representing a separate `request`: you are requesting an orange juice and requesting a nice, healthy salad. Your requests are heard by the waiter, or in IT terms the `server`. Their job is to listen to your requests and do whatever is necessary to provide you with what you want. The actual services, like cooking the food, making the drinks or doing the dishes are all done by others. However, to the client the end result of these services are all provided by the server. You don't want to know who performs what service, you just want to eat. When the server comes back with whatever you ordered, they provide you with a `response`. This happens whether or not they could fulfill your requests. + +In web development the same thing happens. The browser is the client, and some computer that has the data you want is the server. Let's say you login to your online bank account. As the client you want to see the amount of money you currently have. The browser sends out a request to the server, who then activates the necessary services (in this example, some kind of database) and returns with a response containing the exact amount of money you currently have in the bank. + +Look into the following resources to increase your understanding: + +- [The Client Server Model](https://www.youtube.com/watch?v=L5BlpPU_muY) +- [Client-Server Model & Structure of a Web Application](https://medium.freecodecamp.org/how-the-web-works-part-ii-client-server-model-the-structure-of-a-web-application-735b4b6d76e3) + +### What is Hypertext Transfer Protocol (HTTP)? + +How HTTP and HTTPS works: + + + +A big part of making applications that follow the REST architecture is by use of HTTP methods. + +If you've every typed in a URL you might've seen the letters HTTP at the beginning of it, i.e. `http://www.hackyourfuture.net`. It stands for **Hypertext Transfer Protocol** and it is the basic way of sending requests and receiving responses. + +Like verbal communication, there's the _content_ (WHAT you are saying) and the _style_ (HOW you are saying it). HTTP refers to the \***\*style\*\*** of online communication. How you communicate over the web is done through specific HTTP methods (also called HTTP verbs), that describe what type of request is being made. The most important ones are: + +- **GET**. This type of request is only about getting data from the server. Whenever a user enters a new webpage, this usually means a GET request gets send to the server to get the required files to display that webpage. All other data in the website stays unaffected. +- **POST**. This type of request allows the client to submit new data to the server. Generally speaking, its purpose is to store this new data into a database, or manipulate it and later return it back to the client. +- **PUT**. This type of request allows the client to update existing data, which is already present in the client. The data is edited and then send back to the server, similar to the POST request but more semantic. +- **DELETE**. This type of request tells the server to delete a particular set of data or resources. + +Why do you need to know all of this? HTTP is the foundation of how client-server interactions work on the web. It's important to have a universal policy that everyone holds on to, in order to have fast and effective online communication. + +If you really wanna get into what happens in the network layer, check out this: Its really nicely done! + +Look into the following resources to increase your understanding: + +- [The Http and the Web: Http explained](https://www.youtube.com/watch?v=eesqK59rhGA) +- [Basics concepts of web applications](https://www.youtube.com/watch?v=RsQ1tFLwldY) + +- [@NoerGitKat (lots of web app clones/examples to learn from)](https://www.github.com/NoerGitKat) + +### Flipped classroom videos + +[Flipped classroom videos](https://github.com/HackYourFuture-CPH/node.js/blob/main/week1/preparation.md#flipped-classroom-videos) + +### Code inspiration + +#### Created module + +Go to the `teacher-live-coding` [project repository](https://github.com/HackYourFuture-CPH/teacher-live-coding), `npm install` and run using `nodemon ./src/backend/created-module.js`. Try and implement this functionality from the bottom while explaining. + +#### Building a simple http webserver + +Go to the `teacher-live-coding` [project repository](https://github.com/HackYourFuture-CPH/teacher-live-coding), run using `nodemon ./src/backend/simple-webserver.js`. Try and implement this functionality from the bottom while explaining. + +## Exercises + +1. [Server](./exercises/01-server.md): Setup project and create a server with Express +1. [Database](./exercises/02-database.md): Connect to your MySQL database from Node.js and Express +1. [User routes](./exercises/03-user-routes.md): Declare new routes that interact with a `users` table diff --git a/legacy/nodejs/week1/preparation.md b/legacy/nodejs/week1/preparation.md new file mode 100644 index 00000000..a35eb881 --- /dev/null +++ b/legacy/nodejs/week1/preparation.md @@ -0,0 +1,88 @@ +# Preparation + +## Installing node + +1. Setup `node` on your computer (skip to step 2 to check): + 1. Download from: + 2. Check if node is installed in your system by running the sollowing commands in Command Promt/PowerShell/Git Bash: + - `node -v` + - `npm -v` + - In either case you should see the version of `node` or `npm` installed. + +## Understanding the basics of NodeJS + +- Client server model: (6 min) +- HTTP and HTML: (7 min) +- Video about node: (13 min) +- Until `That’s all folks! (Well, sorta…)` (10 min) + +Try to formulate an answer to the question: + +- What is the server and what is the client? +- What is http? +- What is Node.js? + +## Flipped classroom videos + +### Teacher Live Coding Videos + + + +- [What happens when you open a webpage - Class 1](https://youtu.be/wdj2LrpKSdg) +- [What is node js and how to use it - Class 1](https://youtu.be/gTa5R1PHIiY) +- [Node js project structure - Class1](https://youtu.be/CUY20f-KBxE) +- [Creating a simple Express webserver in Node js and creating your own modules - Class 1](https://youtu.be/R-dl4-VnZYA) + +## Extras + +### Good resources for learning node + +[8 hours intro to NodeJS](https://www.youtube.com/watch?v=Oe421EPjeBE) + +### The REPL + +There are many ways to interact with Node. We can start the environment up in a REPL, we can start it up with a file, we can start it inside a docker container. + +After installing NodeJS on your machine, you will have access to the environment by typing `node` in the terminal. This will drop you into the node REPL (Read Evaluate Print Loop). + +```text +Welcome to Node.js v15.14.0 +Type β€œ.help” for more information. +> +``` + +In here you will have access to the javascript language. There are limitations, which depends on the version number of Node. The further it progresses in time, the more features will be included. + +### Feeding the REPL files + +You can also feed node files to evaluate and this is where node becomes such a powerful tool for any developer, especially frontend developers. + +### Creating an NPM project with a script that starts the application + + + +### As a Webserver + +- Can serve HTTP responses to HTTP requests. +- Is most often used together with the REST principle. +- The REST principle is an architecture for organising resources. + +### Security and authentication + +In many cases we don’t want the web server to just serve information to anyone, some of it might be privileged i.e. should only be available to a specific user. It is the responsibility of the web server to check that the requests it receives have the right authentication required e.g. so user A can only get information about their own account, not other users. + +### Database interaction + +The web server rarely has any information or data built into it. It relies on external systems built specifically for that purpose and acts as a proxy between the database and the requester. (However, node is a general purpose programming language, so it can indeed also be used to write a database system e.g. ). + +### Tests + +Testing is an often used technique in software development to better ensure your code does what you expect it to. Booting up a server locally and doing manual testing works to some extent, but this is not manageable or scalable as an application grows in complexity. + +To help you get accustomed to what testing looks like, each week's homework includes a set of tests to move you along in the exercises. This provides structure for you to better understand what you need to complete and to help you be sure that you are correctly completing the tasks. + +If in doubt, from the week's `homework` directory from which you are completing the exercises, run (after running `npm install`): + +`npm test` + +This will give you an idea of the tasks you need to complete. diff --git a/legacy/nodejs/week1/readme.md b/legacy/nodejs/week1/readme.md new file mode 100644 index 00000000..afe4cbe2 --- /dev/null +++ b/legacy/nodejs/week1/readme.md @@ -0,0 +1,9 @@ +# Introduction + +In the first week of the module we will focus on a general introduction starting from what happens when you open a webpage in the browser, an introduction to the underlying protocol HTTP (the roads of the internet) as well as an introduction to what can be build with node. + +## Planning + +| Week | Topic | Preparation | Homework | Lesson plan | +| ---- | ----------------------------------------------- | ------------------------------------ | ------------------------------------- | ------------------------------------ | +| 1. | HTTP; Introduction to node js; Simple webserver | [Preparation](/week1/preparation.md) | [Homework](/week1/homework/readme.md) | [Lesson plan](/week1/lesson-plan.md) | diff --git a/legacy/nodejs/week2/exercises/01-server.md b/legacy/nodejs/week2/exercises/01-server.md new file mode 100644 index 00000000..8469bc89 --- /dev/null +++ b/legacy/nodejs/week2/exercises/01-server.md @@ -0,0 +1,47 @@ +# Server + +Create a new, separate folder somewhere on your machine: + +```shell +mkdir nodejs-week2 +code nodejs-week2 # to open the folder in VS Code +``` + +You can also reuse some other folder. Main thing to watch out for is that the folder you decide to use should ideally be empty. + +--- + +Initialize and install: + +```shell +npm init -y +npm pkg set type="module" +npm install express mysql2 knex +echo node_modules/ >> .gitignore +``` + +Create a file named `app.js` and use the following as a starting point for this exercise: + +```js +import express from "express"; +const app = express(); +const port = process.env.PORT || 3000; + +app.get("/", (req, res) => { + res.send("Hello Class!"); +}); + +app.listen(port, () => { + console.log(`Listening on port ${port}`); +}); +``` + +--- + +```shell +npm install --save-dev nodemon +npm pkg set scripts.dev="nodemon app.js" +npm run dev +``` + +Go to in your browser to verify that the server started. diff --git a/legacy/nodejs/week2/exercises/02-schema.md b/legacy/nodejs/week2/exercises/02-schema.md new file mode 100644 index 00000000..67a5a71a --- /dev/null +++ b/legacy/nodejs/week2/exercises/02-schema.md @@ -0,0 +1,35 @@ +# Schema + +This week we will work with 2 tables: + +- A `users` table similar to week 1 but now with an added `token` column. +- A `snippets` table containing (code) snippets that belong to a user. + +Create a new database/schema `hyf_node_week2` containing the following tables: + +```sql +CREATE TABLE `users` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `confirmed_at` datetime DEFAULT NULL, + `first_name` varchar(255) NOT NULL, + `last_name` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `token` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `email_UNIQUE` (`email`), + UNIQUE KEY `token_UNIQUE` (`token`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4; + +CREATE TABLE `snippets` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `user_id` int unsigned NOT NULL, + `title` varchar(255) NOT NULL, + `contents` text NOT NULL, + `is_private` tinyint NOT NULL DEFAULT '1', + PRIMARY KEY (`id`), + KEY `id_idx` (`user_id`), + CONSTRAINT `id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +``` diff --git a/legacy/nodejs/week2/exercises/03-api.md b/legacy/nodejs/week2/exercises/03-api.md new file mode 100644 index 00000000..1d5c7602 --- /dev/null +++ b/legacy/nodejs/week2/exercises/03-api.md @@ -0,0 +1,57 @@ +# API + +The end goal of the exercise is to implement the following routes: + +- `POST /api/snippets` to create a snippet +- `GET /api/snippets` to get a list of snippets +- `GET /api/snippets/:id` to get a single snippet + +We will create the snippet routes in a different file, `api/snippets.js`, which will export an [Express Router](http://expressjs.com/en/4x/api.html#router). + +That will look something like this: + +```js +// Contents of api/snippets.js + +import express from "express"; +const router = express.Router(); + +// GET /api/snippets +router.get("/", async (request, response) => { + // TODO +}); + +// TODO: POST /api/snippets +// TODO: GET /api/snippets/:id + +export default router; +``` + +We will also have the database connection in a separate file: + +```js +// Contents of database.js + +import knex from "knex"; + +const knexInstance = knex({ + client: "mysql2", + connection: { + host: process.env.DB_HOST || "127.0.0.1", + port: process.env.DB_PORT || 3306, + user: process.env.DB_USER || "root", + password: process.env.DB_PASSWORD || "my-secret-pw", + database: process.env.DB_NAME || "hyf_node_week2", + }, +}); + +export default knexInstance; +``` + +At this point verify that your project structure looks like this: + +- api + - snippets.js +- app.js +- database.js +- package.json diff --git a/legacy/nodejs/week2/exercises/04-post-endpoint.md b/legacy/nodejs/week2/exercises/04-post-endpoint.md new file mode 100644 index 00000000..8da1929e --- /dev/null +++ b/legacy/nodejs/week2/exercises/04-post-endpoint.md @@ -0,0 +1,91 @@ +# API + +## `POST /api/snippets` + +Let's start with a simplified version of the `POST /api/snippets` route. First we add the POST route to `api/snippets.js`: + +```js +// Contents of api/snippets.js + +import express from "express"; +import knexInstance from "../database.js"; + +const router = express.Router(); + +// GET /api/snippets +router.get("/", async (request, response) => { + // TODO +}); + +// POST /api/snippets +router.post("/", async (request, response) => { + // TODO +}); + +// TODO: GET /api/snippets/:id + +export default router; +``` + +--- + +To be able to insert a row into the `snippets` table, we need to have data in the `users` table. Create a user and note what the user ID is. + +The POST request we want to make will look something like this: + +```text +POST /api/snippets +{ + "title": "Snippet title", + "contents": "#hello", + "is_private": false +} +``` + +But first, for Express to handle JSON requests, we need to add `app.use(express.json())` to `app.js`: + +```js +// Contents of app.js + +import express from "express"; +const app = express(); +const port = process.env.PORT || 3000; + +app.use(express.json()); + +app.get("/", (req, res) => { + res.send("Hello Class!"); +}); + +// Rest of the file... +``` + +--- + +One remaining thing in the setup is to actually use the router we're exporting from `api/snippets.js`. +Inside `app.js`, below `app.use(express.json())`, add the following: + +```js +import snippetsRouter from "./api/snippets.js"; +app.use("/api/snippets", snippetsRouter); +``` + +--- + +**Task:** when we now make a request like + +```text +POST /api/snippets +{ + "title": "Snippet title", + "contents": "#hello", + "is_private": false +} +``` + +you should insert a new row into the `snippets` table with the data from the request body. + +Hints: + +- [Insert with Knex](https://knexjs.org/guide/query-builder.html#insert) +- When creating a snippet we also need to specify a `user_id`. For now, you can just pass in the `user_id` in the request body (alongside the other snippet data) diff --git a/legacy/nodejs/week2/exercises/05-get-endpoints.md b/legacy/nodejs/week2/exercises/05-get-endpoints.md new file mode 100644 index 00000000..abfdd0ea --- /dev/null +++ b/legacy/nodejs/week2/exercises/05-get-endpoints.md @@ -0,0 +1,43 @@ +# API + +## `GET /api/snippets` + +Return all non-private snippets together with some information about the user. Example response: + +```json +[ + { + "id": 1, + "created_at": "...", + "title": "avg.js", + "contents": "console.log('1')", + "is_private": false, + "user": { + "id": 1, + "first_name": "Orhan", + "last_name": "Toy" + } + } +] +``` + +## `GET /api/snippets/:id` + +Return a single snippet. Example response: + +```json +{ + "id": 1, + "created_at": "...", + "title": "avg.js", + "contents": "console.log('1')", + "is_private": true, + "user": { + "id": 1, + "first_name": "Orhan", + "last_name": "Toy" + } +} +``` + +**Not found:** we respond with a 404 if the snippet with the given ID cannot be found. diff --git a/legacy/nodejs/week2/exercises/06-auth.md b/legacy/nodejs/week2/exercises/06-auth.md new file mode 100644 index 00000000..57ff25e8 --- /dev/null +++ b/legacy/nodejs/week2/exercises/06-auth.md @@ -0,0 +1,119 @@ +# API + +Now we can move onto adding authentication for the API. You will have to modify the routes you already created in `api/snippets.js`. + +## Authentication + +The token is used to authenticate certain requests by setting the `Authorization` header, like so: + +`Authorization: token xyz` + +The "xyz" part is the token value that you can look up and find in the `users.token` column. + +## Routes + +See below for details about authentication and the response expectations. + +### `POST /api/snippets` + +**Authenticated access:** if the user has provided a valid token, we go ahead and insert a new row into the `snippets` table. + +Ideally you should try to validate the request and make sure it has + +- a non-empty `title` +- a non-empty `contents` +- `is_private` is optional + +**Invalid authentication:** if the user has provided an invalid token or no token at all, we respond with a 403 Forbidden: + +```json +{ + "error": "Not authorized" +} +``` + +### `GET /api/snippets` + +**Anonymous access:** if there is no `Authorization` header, this should return all non-private snippets together with some information about the user. Example response: + +```json +[ + { + "id": 1, + "created_at": "...", + "title": "avg.js", + "contents": "console.log('1')", + "is_private": false, + "user": { + "id": 1, + "first_name": "Orhan", + "last_name": "Toy" + } + } +] +``` + +**Authenticated access:** if the user has provided a valid token, we return _all_ snippets belonging to that user. Example response: + +```json +[ + { + "id": 1, + "created_at": "...", + "title": "avg.js", + "contents": "console.log('1')", + "is_private": true, + "user": { + "id": 1, + "first_name": "Orhan", + "last_name": "Toy" + } + } +] +``` + +**Invalid authentication:** if the user has provided an invalid token, we respond with a 403 Forbidden response: + +```json +{ + "error": "Not authorized" +} +``` + +### `GET /api/snippets/:id` + +This endpoint should just return the snippet with the given ID: + +```json +{ + "id": 1, + "created_at": "...", + "title": "avg.js", + "contents": "console.log('1')", + "is_private": true, + "user": { + "id": 1, + "first_name": "Orhan", + "last_name": "Toy" + } +} +``` + +**Invalid authentication:** if the user has provided an invalid token, we respond with a 403 Forbidden response: + +```json +{ + "error": "Not authorized" +} +``` + +**Not found:** we respond with a 404 if the snippet with the given ID cannot be found. + +--- + +It is left as an optional exercise to add the following routes: + +- `PUT /api/snippets/:id` to update a snippet +- `DELETE /api/snippets/:id` to delete a snippet + +Also, it could be a good idea to deny the request if the user making the request is not confirmed diff --git a/legacy/nodejs/week2/homework/readme.md b/legacy/nodejs/week2/homework/readme.md new file mode 100644 index 00000000..8ddf1450 --- /dev/null +++ b/legacy/nodejs/week2/homework/readme.md @@ -0,0 +1,205 @@ +# Week 2 homework + +This homework, just like the previous week, will result in 2 pull requests: + +- A pull request for the **Warmup** - in your regular hyf-homework repository +- A pull request for the additional **Meal sharing endpoints** - in the meal-sharing repository + +In both repositories, create a `nodejs-week2` branch from `main` to work on the homework (`git checkout -b nodejs-week2` ) + +## Warmup + +For the warmup you're going to build a search engine. The search engine will have 3 routes: + +- `GET /search` +- `GET /documents/:id` +- `POST /search` + +The purpose of the search engine is to search and find documents from a file called `documents.json`. Example contents: + +```json +[ + { + "id": 1, + "name": "Used Apple Airpods", + "price": "50", + "description": "Battery life is not great" + }, + { + "id": 2, + "type": "doc", + "value": "hello world" + } +] +``` + +### Setup + +Go to `nodejs/week2` in your `hyf-homework` repo: + +```shell +npm init -y +npm pkg set type="module" +npm i express +npm i --save-dev nodemon +npm pkg set scripts.dev="nodemon app.js" +``` + +You should ensure that the `node_modules/` folder is ignored by Git: + +```shell +echo node_modules/ >> .gitignore +``` + +Create `app.js` and as a starting point you can use the following code: + +```js +import express from "express"; +const app = express(); +const port = process.env.PORT || 3000; + +// Support parsing JSON requests +app.use(express.json()); + +app.get("/", (req, res) => { + res.send("This is a search engine"); +}); + +app.listen(port, () => { + console.log(`Listening on port ${port}`); +}); +``` + +You also need to create a `documents.json` file. + +### `GET /search` + +This endpoint will accept a query parameter called `q`, short for _query_. A bit confusing to have a query parameter called q(uery) but hang in there πŸ’ͺ + +- If `q` is not provided, the endpoint should return all documents. +- If `q` is provided, the endpoint should return the documents with some field that matches the value of `q`. + +Example response if we call `GET /search?q=hello`: + +```json +[ + { + "id": 2, + "type": "doc", + "value": "hello world" + } +] +``` + +### `GET /documents/:id` + +This endpoint is simple: find and respond with the document matching the `id` parameter. If there is no such document, respond with a 404 Not Found. +You can assume that the document IDs are unique so there's no need to handle duplicates. + +### `POST /search` + +This endpoint is sort of like `GET /search`. + +It also accepts a query parameter called `q` and it should behave just like `GET /search`. +But it also accepts a field called `fields` in the JSON request body. `fields` is an object where it will be possible to filter by specific fields. + +Example request: + +```text +POST /search +{ + "fields": { + "price": "50" + } +} +``` + +Response to the example request: + +```json +[ + { + "id": 1, + "name": "Used Apple Airpods", + "price": "50", + "description": "Battery life is not great" + } +] +``` + +If both `q` (query parameter) and `fields` (in body) are provided, we should respond with status 400 Bad Request and explain that both can't be provided. + +## Meal sharing endpoints + +You will continue working in the meal-sharing repository for this homework. This week you will build more endpoints, developing some [CRUD](https://www.freecodecamp.org/news/crud-operations-explained/) operations for your future meal sharing website backend functionality. + +### Routes + +In last week's homework you added routes in `/api/src/index.js`. You can just leave them there as they are. + +For this week's homework, we will add two categories of routes: meals and reservations. + +- The routes for meals will go into `/api/src/routers/meals.js` +- The reservation routes will live in `/api/src/routers/reservations.js` + +This means that we will end up having two Routers: a meals router and a reservations router. +You can read more about Express Routers [here](http://expressjs.com/en/4x/api.html#router). + +You can reference the file `/api/src/routers/nested.js` for an example, and see how it is used in `/api/src/index.js`. + +#### Meals + +| Route | HTTP method | Description | +| ---------------- | ----------- | ------------------------------- | +| `/api/meals` | GET | Returns all meals | +| `/api/meals` | POST | Adds a new meal to the database | +| `/api/meals/:id` | GET | Returns the meal by `id` | +| `/api/meals/:id` | PUT | Updates the meal by `id` | +| `/api/meals/:id` | DELETE | Deletes the meal by `id` | + +#### Reservations + +Now that you have built the basic set of endpoints for **meals**, you can get some more practice and expand your app backend by creating the same for **reservations**: + +| Route | HTTP method | Description | +| ----------------------- | ----------- | -------------------------------------- | +| `/api/reservations` | GET | Returns all reservations | +| `/api/reservations` | POST | Adds a new reservation to the database | +| `/api/reservations/:id` | GET | Returns a reservation by `id` | +| `/api/reservations/:id` | PUT | Updates the reservation by `id` | +| `/api/reservations/:id` | DELETE | Deletes the reservation by `id` | + +##### Requests + +All the `POST` or `PUT` endpoints will require a request body - the information that your database will be updated with. + +##### Responses + +All the specified `GET` routes should respond with JSON with the available columns from the associated tables. + +The `GET`, `PUT` and `DELETE` routes that include an `/:id` in the path should make sure to handle the case when the row with that ID does not exist. + +> Think about what special HTTP status code would be appropriate for that scenario. + +You are free to decide on the response for a successful `POST`, `PUT` and `DELETE` request. Some ideas: + +- Respond with an acknowledgement message: `{ "message": "Deleted meal" }` +- Respond with data from the row itself like with `GET` + +And lastly, if the `POST` request is successful, the response status code should be 201 Created, as that would indicate something was _created_. + +#### Knex + +Your usage of Knex should be getting a bit more advanced now. You will move from `knex.raw` on to different `knex` function, for example: + +- `.select`, `.from`, `.where` +- `.insert` +- `.update` +- `.del` (for deletion) + +Check out the [Knex cheatsheet](https://devhints.io/knex)! + +## Hand in homework + +Need to brush up on the homework hand-in process? +Check [this resource](https://github.com/HackYourFuture-CPH/Git/blob/main/homework-submission.md) to remember how to hand in the homework correctly! diff --git a/legacy/nodejs/week2/lesson-plan.md b/legacy/nodejs/week2/lesson-plan.md new file mode 100644 index 00000000..b23919b6 --- /dev/null +++ b/legacy/nodejs/week2/lesson-plan.md @@ -0,0 +1,71 @@ +# Lesson plan + +- Focus on having lots of in class exercises. +- DON'T teach everything, let the students investigate topics on their own aswell! +- Focus on how to read documentation, google answers and google errors!! +- Teach towards the students being able to solve the homework. + +Remember to add the code you wrote in the class to the relevant class branch's class work folder. If the branch has not been created just create and push it :) If you dont have access, write to one from the core team. You can see an example below! + +To find examples of what teachers have taught before go to the class branches in the classwork folder, Fx [class 07](https://github.com/HackYourFuture-CPH/JavaScript/tree/class07/JavaScript1/Week1/classwork) + +If you find anything that could be improved then please create a pull request! We welcome changes, so please get involved if you have any ideas!!! + +--- + +- Express + - What is express + - Routing (focus on `get` requests) + - `app.use` + - `app.get` + - [Live coding](#app-get-vs-app-use) + - Params `users/:id` + - Query parameters `users?limit=5` + - [Live coding](#query-parameters-vs-parameters) + - Exercise + - Route order + - [Live coding](#route-order) + - Logging and debugging + - Focus on the students understanding **the order** in which things are executed + - Middleware + - `next` method + - Modifying `request` and `response` + - + - [Live coding](#middleware) + - Exercise +- Postman + - Create collection and save queries + - Sending get requests requests + - Query parameters + - Parameters + +## Flipped classroom videos + +[Flipped classroom videos](https://github.com/HackYourFuture-CPH/node.js/blob/main/week1/preparation.md#flipped-classroom-videos) + +## Code inspiration + +### app get vs app use + +Go to the `teacher-live-coding` [repo](https://github.com/HackYourFuture-CPH/teacher-live-coding), run `npm install` and run using `nodemon ./src/backend/app-use-vs-app-get.js`. Try and implement this functionality from the bottom while explaining. + +### Query parameters vs parameters + +Run `nodemon ./src/backend/query-parameters-vs-parameters.js`. Try and implement this functionality from the bottom while explaining. + +### Route order + +Run `nodemon ./src/backend/route-order.js`. Try and implement this functionality from the bottom while explaining. + +### Middleware + +Run using `nodemon ./src/backend/middleware.js`. Try and implement this functionality from the bottom while explaining. + +## Exercises + +1. [Server](./exercises/01-server.md): Setup project +1. [DB schema](./exercises/02-schema.md): Setup MySQL database schema +1. [API](./exercises/03-api.md): Snippets API exercises + - [POST endpoint](./exercises/04-post-endpoint.md) + - [GET endpoints](./exercises/05-get-endpoints.md) + - [Authentication](./exercises/06-auth.md) diff --git a/legacy/nodejs/week2/preparation.md b/legacy/nodejs/week2/preparation.md new file mode 100644 index 00000000..890ecce8 --- /dev/null +++ b/legacy/nodejs/week2/preparation.md @@ -0,0 +1,13 @@ +# Preparation + +- (8 min) +- (5 min) +- until but without the `nodemon` part! (10 min) + +## Flipped classroom videos + +- [Nodejs express part 1 - Class 2](https://youtu.be/4HIq70RzDTY) +- [Nodejs express part 2 - Class 2](https://youtu.be/-J1pd4LgjUo) +- [Nodejs express query parameters and params - Class 2](https://youtu.be/_H-bP10Fmaw) +- [Nodejs express middleware - Class 2](https://youtu.be/ZcwmyYGzBnk) +- [Working with Postman - Class 2](https://youtu.be/zNeOUJPxw2s) diff --git a/legacy/nodejs/week2/readme.md b/legacy/nodejs/week2/readme.md new file mode 100644 index 00000000..2b010544 --- /dev/null +++ b/legacy/nodejs/week2/readme.md @@ -0,0 +1,82 @@ +# Introduction + +This is the second week of the NodeJS module, where we will focus on Express, which is an application architecture for building webservers in an easy manner. Although we could write everything from scratch in Node, we don’t want to. In many situations a webserver is generic enough for us and we gain a lot by using something that just works and makes our lives as developers easier – as long as what we are trying to do is within the scope of Express. + +When writing an Express application we are registering routes on HTTP keywords (GET,POST,PUT, DELETE) and handler functions for those routes. + +The most basic express webserver looks like the following: + +```js +// We require the express package after having installed it +// via β€œnpm i express” +import express from "express"; + +// We create an express instance and bind it to our app const +const app = express(); + +// We register the first route with the following; + +// all β€œGET” requests on the path β€œ/β€œ +// will be handled by the function (req, res) {} +app.get("/", function (req, res) { + // the handler receives the request on β€œreq” + // and has access to the response on β€œres” + + // res.send allows us to send a response to a request + res.send("hello world"); +}); + +// We start the express webserver by listening to port 3000 +app.listen(3000); +``` + +If we run this script, node will start up and run the code ending with app.listen(3000). This tells Node to bind and listen for connections on this specified host and port. + +If there is no specified host, Node will bind to localhost and the Node application will be available on . + +If you open that URL in the browser you will see β€œhello world” (without any styling). + +## Extensibility + +This is a very basic example of an express application. There many parameters to tweak and cases to take into consideration. +One of the first things we’d like to do in a typical Express application is to not return strings or HTML, but instead use JSON as the transport encoding format. Meaning we accept JSON in requests and we can respond with JSON formatted data. + +There are a few good extensions or middleware that is easy to plug into express and allows us to tweak and change some of the parts of the webserver. Some of these middleware extensions include body-parser, compression, cors, errorhandler - find the full list here: . + +## More resources + +The best way to learn Express is to use it to build small simple applications and read the documentation. + +## Learning goals + +- [ ] Express + - [ ] What is express + - [ ] Routing + - [ ] Logging and debugging +- [ ] Middleware +- [ ] Postman + +Reproduce a log hitting errors and understanding flow. + +### Relevant links + +- [Preparation](preparation.md) +- [Homework](homework/readme.md) +- [Lesson plan](lesson-plan.md) + +### Express.js + +In Node.js it's possible to make a HTTP server using the native `http` module. However, this is rarely used in practice. Instead, we'll use [Express.js](https://expressjs.com/en/4x/api.html), a backend framework that can do what the `http` module does and much more (in a simpler, faster and more readable way). + +Practically speaking, what can we do with a web server like `http` or `Express`? All the magic that makes the frontend work: + +- Get and store data that comes from the frontend +- Make API calls to other services +- Secure data that comes from both the frontend and the database +- Any other type of calculation or business logic + +For more research, use the following resources: + +- [Express JS Crash Course](https://www.youtube.com/watch?v=L72fhGm1tfE) +- [Going out to eat and understanding the basics of Express.js](https://medium.freecodecamp.org/going-out-to-eat-and-understanding-the-basics-of-express-js-f034a029fb66) +- [Express documentation](https://expressjs.com/en/4x/api.html) diff --git a/legacy/nodejs/week3/homework/readme.md b/legacy/nodejs/week3/homework/readme.md new file mode 100644 index 00000000..c78d3441 --- /dev/null +++ b/legacy/nodejs/week3/homework/readme.md @@ -0,0 +1,209 @@ +# Week 3 homework + +Once again, you will deliver 2 pull requests: + +- A pull request for the **Warmup** - in your regular hyf-homework repository +- A pull request for the additional **meal sharing endpoints** - in the meal-sharing repository + +In both repositories, create a `nodejs-week3` branch from `main` to work on the homework (`git checkout -b nodejs-week3` ). + +## Warmup + +For the warmup you will be handed a Contacts API with a single endpoint: + +- `GET /api/contacts` + +This endpoint accepts a query parameter `sort`. Here's how you can use it: + +- `GET /api/contacts?sort=first_name%20ASC` + - Sorts contacts by first name, ascending +- `GET /api/contacts?sort=last_name%20DESC` + - Sorts contacts by last name, descending + +But this `sort` query parameter has been introduced with a SQL injection vulnerability and the goal is to demonstrate the issue and then fix and remove the vulnerability. + +### Setup + +Go to `nodejs/week3` in your `hyf-homework` repo: + +```shell +npm init -y +npm i express mysql2 knex +npm i --save-dev nodemon +npm set-script dev "nodemon app.js" +``` + +Make sure you have `"type": "module"` in your `package.json`. + +You should also ensure that the `node_modules/` folder is ignored by Git: + +```shell +echo node_modules/ >> .gitignore +``` + +Create a database/schema called `hyf_node_week3_warmup` with a `contacts` table: + +```sql +CREATE TABLE `contacts` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `first_name` varchar(255) NOT NULL, + `last_name` varchar(255) NOT NULL, + `email` varchar(255) DEFAULT NULL, + `phone` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- Sample data +insert into contacts (id, first_name, last_name, email, phone) values (1, 'Selig', 'Matussov', 'smatussov0@pinterest.com', '176-630-4577'); +insert into contacts (id, first_name, last_name, email, phone) values (2, 'Kenny', 'Yerrington', null, null); +insert into contacts (id, first_name, last_name, email, phone) values (3, 'Emilie', 'Gaitskell', null, null); +insert into contacts (id, first_name, last_name, email, phone) values (4, 'Jordon', 'Tokell', null, null); +insert into contacts (id, first_name, last_name, email, phone) values (5, 'Sallyann', 'Persse', 'spersse4@webnode.com', '219-157-2368'); +insert into contacts (id, first_name, last_name, email, phone) values (6, 'Berri', 'Bulter', null, null); +insert into contacts (id, first_name, last_name, email, phone) values (7, 'Lanni', 'Ivanilov', 'livanilov6@fda.gov', null); +insert into contacts (id, first_name, last_name, email, phone) values (8, 'Dagny', 'Milnthorpe', null, null); +insert into contacts (id, first_name, last_name, email, phone) values (9, 'Annadiane', 'Bansal', null, null); +insert into contacts (id, first_name, last_name, email, phone) values (10, 'Tawsha', 'Hackley', null, null); +insert into contacts (id, first_name, last_name, email, phone) values (11, 'Rubetta', 'Ozelton', null, null); +insert into contacts (id, first_name, last_name, email, phone) values (12, 'Charles', 'Boughey', 'cbougheyb@senate.gov', '605-358-5664'); +insert into contacts (id, first_name, last_name, email, phone) values (13, 'Shantee', 'Robbe', null, null); +insert into contacts (id, first_name, last_name, email, phone) values (14, 'Gleda', 'Peat', null, null); +insert into contacts (id, first_name, last_name, email, phone) values (15, 'Arlinda', 'Ethersey', 'aetherseye@biglobe.ne.jp', '916-139-1300'); +insert into contacts (id, first_name, last_name, email, phone) values (16, 'Armando', 'Meachem', 'ameachemf@oaic.gov.au', '631-442-5339'); +insert into contacts (id, first_name, last_name, email, phone) values (17, 'Codi', 'Redhouse', null, '401-953-6897'); +insert into contacts (id, first_name, last_name, email, phone) values (18, 'Ann', 'Buncombe', 'abuncombeh@ow.ly', '210-338-0748'); +insert into contacts (id, first_name, last_name, email, phone) values (19, 'Louis', 'Matzkaitis', 'lmatzkaitisi@ebay.com', '583-996-6979'); +insert into contacts (id, first_name, last_name, email, phone) values (20, 'Jessey', 'Pala', null, null); +insert into contacts (id, first_name, last_name, email, phone) values (21, 'Archy', 'Scipsey', 'ascipseyk@ask.com', '420-983-2426'); +insert into contacts (id, first_name, last_name, email, phone) values (22, 'Benoit', 'Mould', 'bmouldl@bing.com', '271-217-9218'); +insert into contacts (id, first_name, last_name, email, phone) values (23, 'Sherm', 'Girardey', 'sgirardeym@guardian.co.uk', '916-999-2957'); +insert into contacts (id, first_name, last_name, email, phone) values (24, 'Raquel', 'Mudge', 'rmudgen@slate.com', '789-830-7473'); +insert into contacts (id, first_name, last_name, email, phone) values (25, 'Tabor', 'Reavey', null, null); +``` + +Create `app.js`: + +```js +import knex from "knex"; +const knexInstance = knex({ + client: "mysql2", + connection: { + host: process.env.DB_HOST || "127.0.0.1", + port: process.env.DB_PORT || 3306, + user: process.env.DB_USER || "root", + password: process.env.DB_PASSWORD || "my-secret-pw", + database: process.env.DB_NAME || "hyf_node_week3_warmup", + multipleStatements: true, + }, +}); + +import express from "express"; +const app = express(); +const port = process.env.PORT || 3000; + +app.use(express.json()); + +const apiRouter = express.Router(); +app.use("/api", apiRouter); + +const contactsAPIRouter = express.Router(); +apiRouter.use("/contacts", contactsAPIRouter); + +contactsAPIRouter.get("/", async (req, res) => { + let query = knexInstance.select("*").from("contacts"); + + if ("sort" in req.query) { + const orderBy = req.query.sort.toString(); + if (orderBy.length > 0) { + query = query.orderByRaw(orderBy); + } + } + + console.log("SQL", query.toSQL().sql); + + try { + const data = await query; + res.json({ data }); + } catch (e) { + console.error(e); + res.status(500).json({ error: "Internal server error" }); + } +}); + +app.listen(port, () => { + console.log(`Listening on port ${port}`); +}); +``` + +As mentioned above, the `sort` query parameter has been introduced with a SQL injection vulnerability. + +First, you should demonstrate the SQL injection and that it for instance is possible to drop/delete the `contacts` table with the `sort` query parameter. +You can for instance demonstrate this with a screen recording and include it in the PR description. + +After having demonstrated the SQL injection vulnerability, the goal is then to fix the issue by updating `app.js`. + +**Hint:** the `multipleStatements: true` part in the configuration indicates how you can use the vulnerability. The configuration should not be changed though, the SQL injection should be fixed by making changes in the `/api/contacts` route. + +## Meal sharing endpoints + +You will continue working in the meal-sharing repository for this task. + +You should have the basic [CRUD](https://www.freecodecamp.org/news/crud-operations-explained/) endpoints for **meals** and **reservations** as the result of last week's homework. This week, you will add **query parameters**, that will allow you to **sort** and **filter** the information retrieved from the database. + +### Routes + +#### Meals + +Work with your `GET api/meals` route to add the query parameters. +Make sure that the query parameters can be combined, f.x. `?limit=4&maxPrice=90`. + +| Parameter | Data type | Description | Example | +| ----------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | +| `maxPrice` | Number | Returns all meals that are cheaper than `maxPrice`. | `api/meals?maxPrice=90` | +| `availableReservations` | Boolean | Returns all meals that still have available spots left, if `true`. If `false`, return meals that have no available spots left.[^1] | `api/meals?availableReservations=true` | +| `title` | String | Returns all meals that partially match the given title. `RΓΈd grΓΈd` will match the meal with the title `RΓΈd grΓΈd med flΓΈde`. | `api/meals?title=Indian%20platter` | +| `dateAfter` | Date | Returns all meals where the date for `when` is after the given date. | `api/meals?dateAfter=2022-10-01` | +| `dateBefore` | Date | Returns all meals where the date for `when` is before the given date. | `api/meals?dateBefore=2022-08-08` | +| `limit` | Number | Returns the given number of meals. | `api/meals?limit=7` | +| `sortKey`[^2] | String | Returns all meals sorted by the given key. Allows `when`, `max_reservations` and `price` as keys. Default sorting order is asc(ending). | `api/meals?sortKey=price` | +| `sortDir`[^3] | String | Returns all meals sorted in the given direction. Only works combined with the `sortKey` and allows `asc` or `desc`. | `api/meals?sortKey=price&sortDir=desc` | + +[^1]: `availableReservations` requires you to work with several database tables at once. Try practicing the right query in MySQL Workbench first (you might have it from Database week3 homework) and once you have it working, build it with `knex`. + +[^2]: This used to be `sort_key` in a previous version of the homework text. + +[^3]: This used to be `sort_dir` in a previous version of the homework text. + +#### Reviews + +By now, you have the basic set of endpoints for **meals** and **reservations** and even a collection of query parameters for **meals**. To practice a bit more and finalize the basic backend functionality, create the set of routes for **reviews**: + +| Route | HTTP method | Description | +| ----------------------------- | ----------- | ---------------------------------------- | +| `/api/reviews` | GET | Returns all reviews. | +| `/api/meals/:meal_id/reviews` | GET | Returns all reviews for a specific meal. | +| `/api/reviews` | POST | Adds a new review to the database. | +| `/api/reviews/:id` | GET | Returns a review by `id`. | +| `/api/reviews/:id` | PUT | Updates the review by `id`. | +| `/api/reviews/:id` | DELETE | Deletes the review by `id`. | + +#### Knex + +You should try to avoid using `knex.raw` and instead use the different `knex` functions, for example: + +- `.select`, `.from`, `.where`, `join`, `leftJoin` +- `.insert` +- `.update` +- `.del` (for deletion) + +Check out the [Knex cheatsheet](https://devhints.io/knex)! + +## Hand in homework + +Need to brush up on the homework hand-in process? + +Check [this resource](https://github.com/HackYourFuture-CPH/Git/blob/main/homework-submission.md) to remember how to hand in the homework correctly! + +## Feedback + +And finally, please take two minutes to answer the survey [here](https://forms.gle/YG5KCnSCPhb8dJAL9) to give feedback to the staff and mentors. diff --git a/legacy/nodejs/week3/lesson-plan.md b/legacy/nodejs/week3/lesson-plan.md new file mode 100644 index 00000000..f50d2f66 --- /dev/null +++ b/legacy/nodejs/week3/lesson-plan.md @@ -0,0 +1,60 @@ +# Lesson plan + +- Focus on having lots of in class exercises. +- DONT teach everything, let the students investigate topics on their own aswell! +- Focus on how to read documentation, google answers and google errors!! +- Teach towards the students being able to solve the homework. + +Remember to add the code you wrote in the class to the relevant class branch's class work folder. If the branch has not been created just create and push it :) If you dont have access, write to one from the core team. You can see an example below! + +To find examples of what teachers have taught before go to the class branches in the classwork folder, Fx [class 07](https://github.com/HackYourFuture-CPH/JavaScript/tree/class07/JavaScript1/Week1/classwork) + +If you find anything that could be improved then please create a pull request! We welcome changes, so please get involved if you have any ideas!!! + +--- + +- Database interaction + - Connecting to mysql using knex + - Executing queries + - `select`, `create`. You could let the students figure out how `delete` and `update` works + - [Code inspiration](#phonebook-database) especially focus on the promise and query part +- API + - REST + - CRUD + - Router verb `GET`, `POST`, `DELETE`, `PUT` + - Especially focus on post with `app.use(express.urlencoded({ extended: true }));` and `app.use(express.json());` + - [Code inspiration](#phonebook-api) +- Postman + - `POST`, `DELETE`, `PUT` requests +- Exercise finish concerts api + +## Flipped classroom videos + +[Flipped classroom videos](https://github.com/HackYourFuture-CPH/node.js/blob/main/week1/preparation.md#flipped-classroom-videos) + +## Code inspiration + +### Phonebook database + +- Go to the `teacher-live-coding` [repo](https://github.com/HackYourFuture-CPH/teacher-live-coding), to the relevant folder +- Copy the `.env.example` and rename the copied file to `.env` +- Run `npm install` +- Start the application by running `nodemon ./src/backend/phonebook-database-queries.js` + +Try and implement this functionality from the bottom while explaining. + +### Phonebook api + +Start the application by running `nodemon ./src/backend/create-an-api.js`. + +The following two routes have been created, get help by the students to create some of the other routes. + +| Url | Verb | Functionality | Example | +| ------------------- | ------ | --------------------------- | -------------------- | +| `api/contacts/` | GET | Returns all contacts | `GET api/contacts/` | +| `api/contacts/` | POST | Adds a new contact | `POST api/contacts/` | +| `api/contacts/{id}` | GET | Returns contact by `id` | `GET api/contacts/2` | +| `api/contacts/{id}` | PUT | Updates the contact by `id` | `PUT api/contacts/2` | +| `api/contacts/{id}` | DELETE | Deletes the contact by `id` | `DELETE contacts/2` | + +Thank you very much for teaching NodeJS. Please don't hesitate to give feedback by clicking [here](https://forms.gle/sAuVhsTmJ1qSmjgJ6) (teachers and teacher assistants). For homework reviewers, please access the survey [here](https://forms.gle/nVbX9ShusF2a5Aa87). diff --git a/legacy/nodejs/week3/preparation.md b/legacy/nodejs/week3/preparation.md new file mode 100644 index 00000000..57d4892b --- /dev/null +++ b/legacy/nodejs/week3/preparation.md @@ -0,0 +1,11 @@ +# Preparation + +- (15 min) +- until but without `The Visual Studio Code REST client` (15 min) +- - Good example of an api (5 min) + +## Flipped classroom videos + +- [Connecting nodejs to a database using Knex part 1 - Class 3](https://youtu.be/W5xFbiAl4bo) +- [Connecting nodejs to a database using Knex part 2 - Class 3](https://youtu.be/cacTSGU7Hrc) +- [Creating an api using nodejs and express - Class 3](https://youtu.be/i-BUdUMz6Zk) diff --git a/legacy/nodejs/week3/readme.md b/legacy/nodejs/week3/readme.md new file mode 100644 index 00000000..5609f122 --- /dev/null +++ b/legacy/nodejs/week3/readme.md @@ -0,0 +1,37 @@ +# Learning goals + +- [ ] Database interaction + - [ ] Connecting to mysql using Knex + - [ ] Environment variables + - [ ] Executing queries using knex +- [ ] API + - [ ] REST + - [ ] CRUD + - [ ] Router verb `GET`, `POST`, `DELETE`, `PUT` + - [ ] POST mention express.json middleware + - [ ] Postman + +## Relevant links + +- [Preparation](preparation.md) +- [Homework](homework/readme.md) +- [Lesson plan](lesson-plan.md) + +### 1. What is Representational State Transfer (REST)? + +Building software is like building houses: architecture is everything. The design of each part is just as important as the utility of it. REST is a specific architectural style for web applications. It serves to organise code in **predictable** ways. + +The most important features of REST are: + +- An application has a `frontend` (client) and a `backend` (server). This is called [separation of concerns](https://medium.com/machine-words/separation-of-concerns-1d735b703a60): each section has its specific job to do. The frontend deals with presenting data in a user friendly way, the backend deals with all the logic and data manipulation +- The server is `stateless`, which means that it doesn't store any data about a client session. Whenever a client sends a request to the server, each request from the client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. This makes it possible to handle requests from millions of users. +- Server responses can be temporarily stored on the client (a browser) using a process called `caching`: storing files like images or webpages in the browser to load the next time you enter a website (instead of getting them from the server, which generally takes longer to do). +- Client-server communication is done through `Hypertext Transfer Protocol (HTTP)` (more on that later), which serves as the style (the how) of communication. + +It's important to know about REST because it teaches us how web applications are designed and holds us to a standard that makes development and usage predictable. However, don't worry if you don't know what any of this means just yet. It's good to be exposed to it, and understanding will come with experience. + +For more research, check the following resource: + +- [What is REST: a simple explanation for beginners](https://medium.com/extend/what-is-rest-a-simple-explanation-for-beginners-part-1-introduction-b4a072f8740f) + +- [@NoerGitKat (lots of web app clones/examples to learn from)](https://www.github.com/NoerGitKat) diff --git a/legacy/react/README.md b/legacy/react/README.md new file mode 100644 index 00000000..321616b4 --- /dev/null +++ b/legacy/react/README.md @@ -0,0 +1,54 @@ +# HackYourFuture - React + +> [!NOTE] +> Please help us improve and share your feedback! If you find better tutorials or links, please share them by [opening a pull request](https://github.com/HackYourFuture-CPH/React/pulls). + +![React logo](./assets/react-logo.png) + +React is free an open-source frontend JavaScript library for building user interfaces based on UI components. We will learn React to empower us to build even more complex applications faster. + +![Next.js logo](./assets/nextjs-logo.png) + +Next.js is a popular framework which further enhances the development process and performance of our web applications. Next.js builds on top of React by adding several features and optimizations that are often required in modern web applications. + +> [!IMPORTANT] +> The HackYourFuture curriculum is subject to CC BY copyright. This means you can freely use our materials, but just make sure to give us credit for it :blush: + +## Module goals + +This course is divided in 2 modules + +### [React 1](./react1/readme.md) (3 weeks) + +Here we will focus on: + +- Why we learn React +- How to write React components in **JSX** +- How to use **props** and **state** in components +- How to react to events using **hooks** + +### [React 2](./react2/readme.md) (3 weeks) + +In React 2 we will further expand our skills and learn: + +- How to use component libraries +- How to connect to your Node.js API from the Node.js course +- How to build scalable web applications using **Context**, **Reducer**, and **Routing** + +#### Individual Project (Meal Sharing App) + +Additionally, you will also implement the UI for your [Meal Sharing App](./react2/Meal-sharing/homework.md) using the skills you learn in this course. :rocket: + +## Read up before we get started + +1. Watch the [React introductory video](https://www.youtube.com/watch?v=N3AkSS5hXMA) +2. Read the [React landing page](https://react.dev) +3. Read the [Next.js landing page](https://nextjs.org) + +## Beyond Next.js + +Unfortunately, we won't be able to cover all areas of React in this course, but only the essentials. There are a lot of powerful tools out there for you to learn after you finish this course such as: + +- **[TypeScript](https://www.typescriptlang.org/)** - a way to annotate ES6 with types +- **[Redux](https://redux.js.org)** - predictable (application) state container, a Flux implementation +- **[Tailwind CSS](https://tailwindcss.com/)** - Open-source CSS framework diff --git a/legacy/react/assets/nextjs-logo.png b/legacy/react/assets/nextjs-logo.png new file mode 100644 index 00000000..758a548f Binary files /dev/null and b/legacy/react/assets/nextjs-logo.png differ diff --git a/legacy/react/assets/react-logo.png b/legacy/react/assets/react-logo.png new file mode 100644 index 00000000..f8481617 Binary files /dev/null and b/legacy/react/assets/react-logo.png differ diff --git a/legacy/react/assets/react_curriculum.png b/legacy/react/assets/react_curriculum.png new file mode 100644 index 00000000..7b2e76a1 Binary files /dev/null and b/legacy/react/assets/react_curriculum.png differ diff --git a/legacy/react/react1/readme.md b/legacy/react/react1/readme.md new file mode 100644 index 00000000..a81c889d --- /dev/null +++ b/legacy/react/react1/readme.md @@ -0,0 +1,9 @@ +# HackYourFuture - React 1 + +In this 3 week module we will learn React! + +| Week | Topic | Preparation | Lesson plan | Homework | +| ---- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------- | ------------------------------------- | ------------------------------- | +| 1. | Why React and Next.js?; Setting up the Next App (Create-next-app); Building components using JSX | [Preparation](./week1/preparation.md) | [Lesson plan](./week1/lesson-plan.md) | [Homework](./week1/homework.md) | +| 2. | Passing props to components; Managing component state; Sharing state between components | [Preparation](./week2/preparation.md) | [Lesson plan](./week2/lesson-plan.md) | [Homework](./week2/homework.md) | +| 3. | Creating input forms; Rendering a list of components; Understanding effects and hooks; Using data from async APIs | [Preparation](./week3/preparation.md) | [Lesson plan](./week3/lesson-plan.md) | [Homework](./week3/homework.md) | diff --git a/legacy/react/react1/week1/homework.md b/legacy/react/react1/week1/homework.md new file mode 100644 index 00000000..530d921f --- /dev/null +++ b/legacy/react/react1/week1/homework.md @@ -0,0 +1,3 @@ +# Homework + +Complete this week's tasks in the [React 1 homework project](https://github.com/HackYourFuture-CPH/react-1-hw) diff --git a/legacy/react/react1/week1/lesson-plan.md b/legacy/react/react1/week1/lesson-plan.md new file mode 100644 index 00000000..eec7fa56 --- /dev/null +++ b/legacy/react/react1/week1/lesson-plan.md @@ -0,0 +1,177 @@ +# Lesson Plan + +## Part 1 + +### Why React and Next.js? (10 min) + +- Limitations of Javascript +- Purpose of React +- Purpose of Next.js + +### Thinking in Components (10 min) + +- What are components? +- Breaking down UI into reusable components +- Hierarchy and composition of components + +### Creating and running a Next.js app (10 min) + +- Creating a new app using `npx create-next-app@latest` +- folder structure +- Running the app using `npm run dev` + +### Basic Routing (10 minutes) + +- Explanation of routes +- Creating subfolders in `app` directory with `page.jsx` file. +- Create a component that defines a page + +## Part 2 + +### Writing your first static component (20 min) + +- Creating a Functional Component +- Returning JSX + - Single Root Element Requirement + - Fragments +- Using components inside components + +### Use {} to execute JS inside JSX (10 minutes) + +- Embedding Expressions in JSX +- Conditional Rendering + +### Setting attributes (5 min) + +- HTML attributes +- className + +### Importing / exporting .jsx (5 min) + +- defauls exports and named exports + +### Importing .css (5 minutes) + +- Global styles vs. component-specific styles +- CSS modules in Next.js + +## Exercises + +### Exercises Part 1 + +#### 1. Set up a new Next.js project (5 minutes) + +- Create a new app using `create-next-app` following [Setting up a new Next.js app](#setting-up-a-new-nextjs-project). +- Start the web app + +#### 2. Writing static components (10 minutes) + +- Create a functional component called `Greeting` that returns an `h1` element with the text "Hello, React!". +- Create a functional component called `Card` that returns a `div` element with a nested `h2` element and a `p` element. The `h2` should display the text "Card Title", and the `p` should display the text "This is a card component". + +#### 3. Nesting components (10 minutes) + +Create a functional component called `Cards` that renders two instances of the `Card` components from the previous exercise + +#### 4. Executing JS inside JSX (10 minutes) + +Create a functional component called `Person` containing two constants `name` and `age`. The component should display the text: `{name} is an adult` if the age is 18 or higher or `{name} is a minor` if the age is less than 18. + +### Exercises Part 2 + +#### 5. Setting properties such as className and value (15 minutes) + +- Create a functional component called `Button` that renders a `button` element with a `className` prop set to `btn btn-primary`. +- Create a functional component called `DangerButton` that renders a `button` element with a dangerous text and a `className` prop set to `btn btn-primary`. +- Create a functional component called `TextInput` that renders a text input field with a placeholder value `Type something here`. +- Create a functional component called `ProfileImage` that renders an image of a person. +- Add all of the above components to your app + +#### 6. Create sub pages (5 minutes) + +- Create a subpage `/why-us` with a list of 3 reasons your site is worth visiting +- Create two subpages `/products/{product name}` for two fictional products your site contains. Add a simple header with the product name on both pages. + +#### 7. Add basic styling (5 minutes) + +- Create a global CSS file that changes the color of all buttons to blue +- Add component styles for the `DangerButton` which makes it large and red + +#### (Bonus) Create a simple component structure + +- Design a basic layout with header, main content, and footer +- Create separate components for each section + +## Help + +### Setting up a new Next.js project + +To create a new Next.js project, you can use the `create-next-app` command provided by [the React.js team](https://react.dev/learn/start-a-new-react-project): + +```bash +npx create-next-app@latest +``` + +You will presented with a few options for the project you are generating. For this module we will use the following options: + +| Option | Value | +| ---------------------- | -------------------- | +| Project name | Name of your project | +| Use TypeScript | No | +| Use ESLint | Yes | +| Use Tailwind | No | +| Use `src/` directory | No | +| Use App Router | Yes | +| Customize import alias | No | + +This will set up a new Next.js project with the necessary dependencies and a basic file structure. + +> [!NOTE] +> Understanding all the options is out of the scope of this module, but if you are interested you can read more about it here: +> +> - _[TypeScript](https://www.typescriptlang.org/)_ is a superset of Javascript and introduces type checking which means it checks if the specified types match before running the code, not while running the code. It helps identifying errors early on. +> - _[ESLint](https://eslint.org/)_ is an a tool which analyzes your code to ensure it follows good coding conventions. This helps keep the code clean and maintainable. +> - _[Tailwind CSS](https://tailwindcss.com/)_ is a CSS framework which comes with a lot of utility classes to quickly add CSS styling to your components. It enables you to add styling without having to add most of the common CSS classes. +> - Using a `src/` directory is a common pattern to separate your source code from your configuration of the app. It can help you get a better overview of the project as it grows, but this option ultimately comes down to personal preference and won't affect your app. +> - _[App Router](https://www.freecodecamp.org/news/routing-in-nextjs/)_ enables us to easily navigate between pages found in the `/app/pages/` folder. It is a build-in feature of Next.js and will solve most of your needs for page navigation. + +#### Running the development server + +First make sure to navigate to your project folder in the terminal + +```bash +cd my-app # replace 'my-app' with the name of your app +``` + +To start the Next.js development server, run the following command: + +```bash +npm run dev +``` + +#### Next.js project structure overview + +A typical Next.js project structure looks like this: + +```text +my-app/ +β”œβ”€β”€ node_modules/ +β”œβ”€β”€ app/ +β”‚ β”œβ”€β”€ page.jsx +β”‚ β”œβ”€β”€ layout.jsx +β”‚ β”œβ”€β”€ globals.css +β”‚ β”œβ”€β”€ favicon.ico +β”‚ └── ... +β”œβ”€β”€ components/ +β”œβ”€β”€ public/ +β”œβ”€β”€ .gitignore +β”œβ”€β”€ next.config.js +β”œβ”€β”€ jsconfig.json +β”œβ”€β”€ package.json +└── package-lock.json +``` + +- `app/` directory contains the React components that represent different pages in your application. +- `components/` directory contains the React components that represent all the custom components built by you. +- `public/` directory is where you can store static assets like images, documents, etc. +- `next.config.js` is a configuration file for customizing Next.js behavior. diff --git a/legacy/react/react1/week1/preparation.md b/legacy/react/react1/week1/preparation.md new file mode 100644 index 00000000..0aa00f7d --- /dev/null +++ b/legacy/react/react1/week1/preparation.md @@ -0,0 +1,15 @@ +# Preparation + +## React + +- Watch [React introductory video](https://www.youtube.com/watch?v=N3AkSS5hXMA) (5 min) +- Read [React Landing Page](https://react.dev/) (5 min) +- Read [Your First Component](https://react.dev/learn/your-first-component) (15 min) +- Read [Importing and Exporting Components](https://react.dev/learn/importing-and-exporting-components) (10 min) +- Read [Writing Markup with JSX](https://react.dev/learn/writing-markup-with-jsx) (10 min) +- Read [JavaScript in JSX with Curly Braces](https://react.dev/learn/javascript-in-jsx-with-curly-braces) (10 min) + +## Next.js + +- Read [Next.js introduction](https://nextjs.org/docs) (10 min) +- Read [Defining Routes](https://nextjs.org/docs/app/building-your-application/routing/defining-routes) (5 min) diff --git a/legacy/react/react1/week2/homework.md b/legacy/react/react1/week2/homework.md new file mode 100644 index 00000000..530d921f --- /dev/null +++ b/legacy/react/react1/week2/homework.md @@ -0,0 +1,3 @@ +# Homework + +Complete this week's tasks in the [React 1 homework project](https://github.com/HackYourFuture-CPH/react-1-hw) diff --git a/legacy/react/react1/week2/lesson-plan.md b/legacy/react/react1/week2/lesson-plan.md new file mode 100644 index 00000000..b3b6456c --- /dev/null +++ b/legacy/react/react1/week2/lesson-plan.md @@ -0,0 +1,148 @@ +# Lesson Plan + +## Part 1 + +### Introduction to Props (10 min) + +- What are props and why are they used? +- Props as a way to make components flexible and reusable +- Why props should never be changed within components (one-way data flow) + +### Passing and reading Props (20 minutes) + +- How to pass props to components +- reading props using `props.x` syntax +- reading props using destructing syntax +- forwarding props using spread syntax + +### Using children Props (10 minutes) + +- What are children props +- Creating wrapper components + +### Conditionally rendering (10 minutes) + +- Conditional rendering using if/else +- Conditional rendering using ternary operator `( ? : )` or ` && ` + +## Part 2 + +### Introduction to State (5 min) + +- What is state and when to use it +- Differences between props and state + +### useState Hook Syntax (10 minutes) + +- Introduction to hooks +- How to declare and use state with useState + +### Updating state (10 minutes) + +- Updating State arrays +- Updating State objects + +### React rendering triggers (5 minutes) + +- What causes React to re-render components +- Using functional updates for consecutive state changes + +### Dynamically rendering content (10 minutes) + +- Conditional rendering using if/else +- Conditional rendering using ternary operator `( ? : )` or ` && ` +- Rendering multiple items using `.map()` + +### Sharing State between components (5 min) + +- Lifting state up to parent + +### Creating and running a Next.js app (10 min) + +- Creating a new app using `npx create-next-app@latest` +- folder structure +- Running the app using `npm run dev` + +### Basic Routing (10 minutes) + +- Explanation of routes +- Creating subfolders in `app` directory with `page.jsx` file. +- Create a component that defines a page + +### Writing your first static component (20 min) + +- Creating a Functional Component +- Returning JSX + - Single Root Element Requirement + - Fragments +- Using components inside components + +### Use {} to execute JS inside JSX (10 minutes) + +- Embedding Expressions in JSX +- Conditional Rendering + +### Setting attributes (5 min) + +- HTML attributes +- className + +### Importing / exporting .jsx (5 min) + +- defauls exports and named exports + +## Exercises + +### Exercises Part 1 + +#### 1. Create a reusable Button component (10 minutes) + +1. Create a new component called `Button`. +2. Accept `text` and `onClick` as props. +3. Render a button element with the `text` prop as its content. +4. Attach the `onClick` prop to the button's `onClick` event handler. + +#### 2. Create a Card component (15 minutes) + +1. Create a new component called `Card`. +2. Accept `title`, `description`, and `imageUrl` as props. +3. Use destructuring to extract the props. +4. Render a card-like structure with the provided `title`, `description`, and `imageUrl`. + +#### 3. Create a Layout component (10 minutes) + +1. Create a new component called `Layout`. +2. Accept `children` as a prop. +3. Render a layout structure (e.g., header, main content area, footer) with the `children` prop rendered inside the main content area. + +#### 4. Implement conditional rendering (10 minutes) + +1. Create a new component called `ToggleContent`. +2. Accept a `show` prop as a boolean value. +3. Accept `content` as a prop, which can be a string or a React element. +4. Render the `content` prop only if the `show` prop is true, otherwise render a message or nothing. + +### Exercises Part 2 + +#### 5. Create a Counter component (10 minutes) + +1. Create a new component called `Counter`. +2. Use the `useState` hook to manage a count state variable. +3. Implement functions to increment and decrement the count. +4. Render the current count value and buttons to call the increment and decrement functions. + +#### 6. Develop a Form component (10 minutes) + +1. Create a new component called `Form`. +2. Use the `useState` hook to manage the state of form input fields. +3. Implement a function to handle form submission. +4. Render input fields for each form field and a submit button. + +#### 7. Create a ParentChild component set (10 minutes) + +1. Create a new component called `Parent`. +2. Create another component called `Child`. +3. In the `Parent` component, use the `useState` hook to manage a state variable. +4. Implement a function to update the state variable. +5. Render the `Child` component and pass the state variable and the update function as props. +6. In the `Child` component, render the data received from the parent and a button to call the update function. diff --git a/legacy/react/react1/week2/preparation.md b/legacy/react/react1/week2/preparation.md new file mode 100644 index 00000000..5524ec53 --- /dev/null +++ b/legacy/react/react1/week2/preparation.md @@ -0,0 +1,12 @@ +# Preparation + +## React + +- Read [Passing Props to a Component](https://react.dev/learn/passing-props-to-a-component) (15 min) +- Read [Conditional Rendering](https://react.dev/learn/conditional-rendering) (15 min) +- Read [State: A Component's Memory](https://react.dev/learn/state-a-components-memory) (10 min) +- Read [Render and Commit](https://react.dev/learn/render-and-commit) (5 min) +- Read [State as a Snapshot](https://react.dev/learn/state-as-a-snapshot) (10 min) +- Read [Queueing a Series of State Updates](https://react.dev/learn/queueing-a-series-of-state-updates) (10 min) +- Read [Updating Objects in State](https://react.dev/learn/updating-objects-in-state) (10 min) +- Read [Updating Arrays in State](https://react.dev/learn/updating-arrays-in-state) (10 min) diff --git a/legacy/react/react1/week3/homework.md b/legacy/react/react1/week3/homework.md new file mode 100644 index 00000000..4bbf10ca --- /dev/null +++ b/legacy/react/react1/week3/homework.md @@ -0,0 +1,13 @@ +# Homework + +Complete this week's tasks in the [React 1 homework project](https://github.com/HackYourFuture-CPH/react-1-hw) + +## Meal sharing + +For this, you will work in your meal-sharing repository - the same that you worked on in the **Node** module. + +You have just learned **fetching** and rendering the fetched data, and you have built the backend of your meal sharing app during the Node module, so it is time to work on the frontend! + +Create a `MealsList` component that fetches and renders the meals. Place the component in its own folder under `/frontend/components`. +Your component will have a `meals` state. Render the meal title, description and price at least as simple paragraphs. +Add your `MealsList` component to the home page by using it inside `/frontend/components/HomePage/HomePage.jsx`. diff --git a/legacy/react/react1/week3/lesson-plan.md b/legacy/react/react1/week3/lesson-plan.md new file mode 100644 index 00000000..d2945f92 --- /dev/null +++ b/legacy/react/react1/week3/lesson-plan.md @@ -0,0 +1,95 @@ +# Lesson Plan + +## Part 1 + +### Adding Event Handlers (15 min) + +- Passing event handlers as Props +- event handler naming conventions + +### Managing Form Inputs (15 min) + +- Adding form inputs +- Submitting inputs +- Performing simple input validation + +### Rendering multiple components (10 min) + +- Rendering components using `map()` +- `key` property + +## Part 2 + +### Introduction to Hooks (10 min) + +- Rules of Hooks +- Life cycles +- Effects for synchronization + +### How to use `useEffect` (15 min) + +- Usage of `useEffect` +- dependencies of effect (onMount) +- cleanup after effect + +### Connecting to APIs (10 min) + +- Calling async APIs using effects +- Implementing initial page load with loading wheel + +### Introduction to Meal Sharing app (5 min) + +## Exercises + +### Exercises Part 1 + +#### 1. Create a ClickCounter component (10 minutes) + +1. Create a new component called `ClickCounter`. +2. Use the `useState` hook to manage a `count` state variable. +3. Implement an `onClick` event handler function that increments the `count`. +4. Render a button and display the current value of `count`. + +#### 2. Build a SimpleForm component (15 minutes) + +1. Create a new component called `SimpleForm`. +2. Use the `useState` hook to manage the state of form inputs. +3. Create input fields for the form (e.g., name, email, message). +4. Implement a `handleSubmit` function to handle form submission. +5. Render the form inputs and a submit button. + +#### 3. Develop a TodoList component (20 minutes) + +1. Create a new component called `TodoList`. +2. Use the `useState` hook to manage an array of todo items. +3. Implement a function to add a new todo item to the array. +4. Implement a function to remove a todo item from the array. +5. Render a list of todo items using the `.map` method, ensuring each item has a unique `key` prop. +6. Render an input field to add new todos and buttons/functionality to remove todos. + +### Exercises Part 2 + +#### 4. Create a Clock component (15 minutes) + +1. Create a new component called `Clock`. +2. Use the `useState` hook to manage the current time. +3. Use the `useEffect` hook to set up an interval that updates the time every second. +4. Implement the cleanup function in `useEffect` to clear the interval when the component unmounts. +5. Render the current time in the component. + +#### 5. Build a DataFetcher component (15 minutes) + +1. Create a new component called `DataFetcher`. +2. Use the `useState` hook to manage the data, loading, and error states. +3. Use the `useEffect` hook to fetch data from a public API when the component mounts. +4. Implement loading and error states in the component's JSX. +5. Render the fetched data when it's available. + +#### 6. Develop a WindowResizer component (15 minutes) + +1. Create a new component called `WindowResizer`. +2. Use the `useState` hook to manage the window size. +3. Use the `useEffect` hook to set up an event listener for the `resize` event. +4. Update the window size state whenever the `resize` event is triggered. +5. Implement the cleanup function in `useEffect` to remove the event listener when the component unmounts. +6. Render the current window size in the component. diff --git a/legacy/react/react1/week3/preparation.md b/legacy/react/react1/week3/preparation.md new file mode 100644 index 00000000..8401ea88 --- /dev/null +++ b/legacy/react/react1/week3/preparation.md @@ -0,0 +1,14 @@ +# Preparation + +## React + +- Read [Keeping Components Pure](https://react.dev/learn/keeping-components-pure) (10 min) +- Read [Reacting to Input with State](https://react.dev/learn/reacting-to-input-with-state) (10 min) +- Read [Synchronizing with Effects](https://react.dev/learn/synchronizing-with-effects) (10 min) +- Read [Lifecycle of Reactive Effects](https://react.dev/learn/lifecycle-of-reactive-effects) (15 min) +- Read [Using the Form Component](https://react.dev/reference/react-dom/components/form) (15 min) +- Read [Using the Effect Hook](https://react.dev/reference/react/useEffect) (20 min) + +## Next.js + +- (Optional) Read [NextJS Server Side Rendering vs Static Generation](https://vercel.com/blog/nextjs-server-side-rendering-vs-static-generation) (10 min) diff --git a/legacy/react/react2/Meal-sharing/design-inspo.md b/legacy/react/react2/Meal-sharing/design-inspo.md new file mode 100644 index 00000000..d3c65e33 --- /dev/null +++ b/legacy/react/react2/Meal-sharing/design-inspo.md @@ -0,0 +1,37 @@ +# Meal-sharing website examples + +![screenshot](./examples/meal-sharing/ms-1.png) +![screenshot](./examples/meal-sharing/ms-2.png) +![screenshot](./examples/meal-sharing/ms-3.png) +![screenshot](./examples/meal-sharing/ms-4.png) +![screenshot](./examples/meal-sharing/ms-5.png) +![screenshot](./examples/meal-sharing/ms-6.png) +![screenshot](./examples/meal-sharing/ms-7.png) +![screenshot](./examples/meal-sharing/ms-8.png) +![screenshot](./examples/meal-sharing/ms-9.png) +![screenshot](./examples/meal-sharing/ms-10.png) +![screenshot](./examples/meal-sharing/ms-11.png) +![screenshot](./examples/meal-sharing/ms-12.png) +![screenshot](./examples/meal-sharing/ms-13.png) +![screenshot](./examples/meal-sharing/ms-14.png) +![screenshot](./examples/meal-sharing/ms-15.png) +![screenshot](./examples/meal-sharing/ms-16.png) +![screenshot](./examples/meal-sharing/ms-17.png) +![screenshot](./examples/meal-sharing/ms-18.png) +![screenshot](./examples/meal-sharing/ms-19.png) +![screenshot](./examples/meal-sharing/ms-20.png) + +## Restaurant/ordering websites for layout and design inspiration + +![screenshot](./examples/other-websites/ow-1.png) +![screenshot](./examples/other-websites/ow-2.png) +![screenshot](./examples/other-websites/ow-3.png) +![screenshot](./examples/other-websites/ow-4.png) +![screenshot](./examples/other-websites/ow-5.png) +![screenshot](./examples/other-websites/ow-6.png) +![screenshot](./examples/other-websites/ow-7.png) +![screenshot](./examples/other-websites/ow-8.png) +![screenshot](./examples/other-websites/ow-9.png) +![screenshot](./examples/other-websites/ow-10.png) +![screenshot](./examples/other-websites/ow-11.png) +![screenshot](./examples/other-websites/ow-12.png) diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-1.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-1.png new file mode 100644 index 00000000..f79c22ac Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-1.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-10.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-10.png new file mode 100644 index 00000000..e5beed44 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-10.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-11.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-11.png new file mode 100644 index 00000000..ae497ac8 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-11.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-12.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-12.png new file mode 100644 index 00000000..9d79aa85 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-12.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-13.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-13.png new file mode 100644 index 00000000..f3d36417 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-13.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-14.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-14.png new file mode 100644 index 00000000..f37fd977 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-14.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-15.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-15.png new file mode 100644 index 00000000..fd0fe454 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-15.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-16.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-16.png new file mode 100644 index 00000000..5a0c09b6 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-16.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-17.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-17.png new file mode 100644 index 00000000..0bf5f03b Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-17.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-18.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-18.png new file mode 100644 index 00000000..05c4776b Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-18.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-19.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-19.png new file mode 100644 index 00000000..2279fae1 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-19.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-2.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-2.png new file mode 100644 index 00000000..b3907328 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-2.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-20.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-20.png new file mode 100644 index 00000000..bf14e247 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-20.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-3.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-3.png new file mode 100644 index 00000000..5df7ed3f Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-3.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-4.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-4.png new file mode 100644 index 00000000..e984c915 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-4.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-5.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-5.png new file mode 100644 index 00000000..f70acb80 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-5.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-6.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-6.png new file mode 100644 index 00000000..fe7416c1 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-6.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-7.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-7.png new file mode 100644 index 00000000..f7edd653 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-7.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-8.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-8.png new file mode 100644 index 00000000..ec783a99 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-8.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-9.png b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-9.png new file mode 100644 index 00000000..c1b20473 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/meal-sharing/ms-9.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/other-websites/ow-1.png b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-1.png new file mode 100644 index 00000000..2e72787e Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-1.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/other-websites/ow-10.png b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-10.png new file mode 100644 index 00000000..946effb8 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-10.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/other-websites/ow-11.png b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-11.png new file mode 100644 index 00000000..6d8f9e12 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-11.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/other-websites/ow-12.png b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-12.png new file mode 100644 index 00000000..66ad1735 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-12.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/other-websites/ow-2.png b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-2.png new file mode 100644 index 00000000..644eaf56 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-2.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/other-websites/ow-3.png b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-3.png new file mode 100644 index 00000000..7bc89846 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-3.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/other-websites/ow-4.png b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-4.png new file mode 100644 index 00000000..cf3234b4 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-4.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/other-websites/ow-5.png b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-5.png new file mode 100644 index 00000000..2680f895 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-5.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/other-websites/ow-6.png b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-6.png new file mode 100644 index 00000000..243d60dd Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-6.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/other-websites/ow-7.png b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-7.png new file mode 100644 index 00000000..65be692d Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-7.png differ diff --git a/legacy/react/react2/Meal-sharing/examples/other-websites/ow-9.png b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-9.png new file mode 100644 index 00000000..b8b84c60 Binary files /dev/null and b/legacy/react/react2/Meal-sharing/examples/other-websites/ow-9.png differ diff --git a/legacy/react/react2/Meal-sharing/homework.md b/legacy/react/react2/Meal-sharing/homework.md new file mode 100644 index 00000000..43bdbca8 --- /dev/null +++ b/legacy/react/react2/Meal-sharing/homework.md @@ -0,0 +1,121 @@ +# Meal sharing project recap + +This page provides you with: + +1. A summary of the homeworks from the NodeJS and React modules that **relate** to the meal-sharing project +2. Some additional steps to complete **after** the meal sharing session + +## NodeJS + +### Week 1: Feature routes + +- `/future-meals` +- `/past-meals` +- `/all-meals` +- `/first-meal` +- `/last-meal` + +[Full description](https://github.com/HackYourFuture-CPH/node.js/blob/main/week1/homework/readme.md#meal-sharing-endpoints) + +### Week 2: CRUD routes for meals and reservations + +`/meals`: + +- GET `/api/meals` +- POST `/api/meals` +- GET `/api/meals/:id` +- PUT `/api/meals/:id` +- DELETE `/api/meals/:id` + +`/reservations`: + +- GET `/api/reservations` +- POST `/api/reservations` +- GET `/api/reservations/:id` +- PUT `/api/reservations/:id` +- DELETE `/api/reservations/:id` + +[Full description](https://github.com/HackYourFuture-CPH/node.js/blob/main/week2/homework/readme.md#meal-sharing-endpoints) + +### Week 3: Meal filtering and CRUD routes for reviews + +`GET /api/meals` query parameters: + +- `maxPrice` +- `availableReservations` +- `title` +- `dateAfter` +- `dateBefore` +- `limit` +- `sortKey` +- `sortDir` + +> Make sure that the query parameters can be **combined**, e.g. `?limit=4&maxPrice=90`. + +`/reviews`: + +- GET `/api/reviews` +- GET `/api/meals/:meal_id/reviews` +- POST `/api/reviews` +- GET `/api/reviews/:id` +- PUT `/api/reviews/:id` +- DELETE `/api/reviews/:id` + +[Full description](https://github.com/HackYourFuture-CPH/node.js/blob/main/week3/homework/readme.md#meal-sharing-endpoints) + +## React 1 + +### Week 3: `` component + +- Add a new component named `` which fetches some meals from the API and shows them in a simple list + +[Full description](https://github.com/HackYourFuture-CPH/React/blob/main/react1/week3/homework.md#meal-sharing) + +## React 2 + +### Week 1: `` component and grid layout + +- Add a new component named `` which renders the information for a meal in a nice card design +- Change the `` to place the `` cards in a grid + +[Full description](https://github.com/HackYourFuture-CPH/React/blob/main/react2/week1/homework.md#meal-sharing) + +### Week 2: Frontend routing and form submissions + +Routes: + +- `/` (home page) +- `/meals/{id}` (meal detail page) +- `/meals` (all meals page) + +Meal detail page forms: + +- form for reservation (`POST /api/reservations`) +- form for review (`POST /api/reviews`) + +[Full description](https://github.com/HackYourFuture-CPH/React/blob/main/react2/week2/homework.md#meal-sharing-app-continued) + +## Meal sharing session + +These tasks should be completed after all of the **above** homework. These tasks will require you to make changes to both the web app and the API! + +Searching for meals: + +- Add a search control (e.g. a text field with a "Search" button) to the page that shows all meals (`/meals`) +- When a user fills in a text and clicks search, the list of meals shown should be limited to those that partially match the search string + > Hint: Your API should already accept a query parameter called `title` to perform this kind of filtering! + +Sorting meals: + +- Add a sort control (e.g. two drop downs, one for which field to sort on and one for which direction to sort in) to the page that shows all meals (`/meals`) +- When a user changes which field to sort on **or** when they change the sorting direction, the list of meals shown should change its sort order + > Hint: Your API should already accept two query parameters called `sortKey` and `sortDir`! + +Showing available spots: + +- Add an indicator to the `Meal` component for how many spots are left to be reserved for a given meal + > Hint: You can extend the `GET /meals` and `GET meals/:id` endpoints to include this information! Another alternative is to create a new endpoint just for this information and call it as an addiontal effect inside of the ` component. + +> Bonus: How can you update this information every 5 seconds? + +Once those 3 tasks are done and you have time over, feel free to polish your application, you can find lots of examples [here](./design-inspo.md). diff --git a/legacy/react/react2/readme.md b/legacy/react/react2/readme.md new file mode 100644 index 00000000..3e77ad52 --- /dev/null +++ b/legacy/react/react2/readme.md @@ -0,0 +1,11 @@ +# HackYourFuture - React 2 + Individual Project (Meal Sharing App) + +In this 3 week module we will continue to learn React! + +## Planning + +| Week | Topic | Preparation | Lesson plan | Homework | +| ---- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------- | -------------------------------------- | +| 1. | **Advanced Routing and Components**; Routing; Component Libraries; Refs | [Preparation](week1/preparation.md) | [Lesson plan](week1/lesson-plan.md) | [Homework](week1/homework.md) | +| 2. | **Contexts and Reducers**; Contexts; Reducers; Localization | [Preparation](week2/preparation.md) | [Lesson plan](week2/lesson-plan.md) | [Homework](week2/homework.md) | +| 3. | **Individual Project - Meal Sharing app**; Complete backend in Node.js; Complete frontend in Next.js | [API exercises from NodeJS](./Meal-sharing/homework.md#nodejs); [Web app exercises from React](./Meal-sharing/homework.md#react-1); [Project Template](https://github.com/HackYourFuture-CPH/hyf-project-template) | [Lesson plan](./Meal-sharing/homework.md#meal-sharing-session) | [Homework](./Meal-sharing/homework.md) | diff --git a/legacy/react/react2/week1/homework.md b/legacy/react/react2/week1/homework.md new file mode 100644 index 00000000..348b0df2 --- /dev/null +++ b/legacy/react/react2/week1/homework.md @@ -0,0 +1,24 @@ +# Homework + +## Start the homework + +Need to brush up on the homework setup process? Check [this](https://github.com/HackYourFuture-CPH/Git/blob/main/homework_hand_in.md) out before you get into some git confusion! + +This week the homework will result in 2 PRs: 1 in your homework repository and 1 in the Meal Sharing repository. + +The homework for this week are the class exercises, along with the meal sharing app. + +## Meal sharing + +Let's not forget to give some attention to the meal sharing frontend! +You have built a `MealsList` last week. +Now build the `Meal` component so that you can use it in the `MealsList` and render a nice card for each meal. +Decide how the meal card should look like and style it. +The component should accept a meal object as a prop and render all its relevant details. +The `MealsList` should render all the meals in a grid. + +## Hand in homework + +Need to brush up on the homework hand-in process? + +Check [this resource](https://github.com/HackYourFuture-CPH/Git/blob/main/homework_hand_in.md) to remember how to hand in the homework correctly! diff --git a/legacy/react/react2/week1/lesson-plan.md b/legacy/react/react2/week1/lesson-plan.md new file mode 100644 index 00000000..de7af8b4 --- /dev/null +++ b/legacy/react/react2/week1/lesson-plan.md @@ -0,0 +1,163 @@ +# Lesson Plan + +## Advanced Routing 2.1 Lecture (40 minutes) + +### Server-Side Rendering (SSR) and Static Site Generation (SSG) (10 minutes) + +- **Explanation of SSR and SSG** + + - Define Server-Side Rendering (SSR) and Static Site Generation (SSG) + - Explain the benefits of SSR and SSG over client-side rendering + +- **Use cases for SSR and SSG** + - Discuss when to use SSR (dynamic data, personalization, etc.) + - Discuss when to use SSG (static content, blogs, documentation, etc.) + +### Introduction to Next.js App Router (15 minutes) + +- **Overview of Next.js routing system** + + - File-based routing system in Next.js + - Dynamic Routes + - Mention the Next.js Link Component & why it is used + +- **Advantages over traditional client-side routing** + - Improved performance with built-in server-side rendering and static site generation + - Simplified routing configuration + - Nested layouts and nested routes + +### Next.js Router Hooks (15 minutes) + +- **Understanding the usePathname hook** + + - Explain the purpose of the `usePathname` hook + - Demonstrate how to use `usePathname` to access the current path + +- **Understanding the useSearchParams hook** + + - Explain the purpose of the `useSearchParams` hook + - Demonstrate how to use `useSearchParams` to access the query strings + +- **Working with the useRouter hook** + - Discuss the need for redirects in web applications (authentication, URL changes, etc.) + - Introduce the `useRouter` hook + - Explain how to access various router properties (push, replace, etc.) + - Demonstrate programmatic navigation using `router.push` and `router.replace` + +## Advanced Routing 2.1 Exercises (45 minutes) + +### 1. Create a page that renders the NASA Astronomy Picture of the Day (with caption) using Server Side Rendering (10 minutes) + +- Use the [NASA API](https://api.nasa.gov/#MarsPhotos) to fetch the Astronomy Picture of the Day data +- Implement [data fetching](https://nextjs.org/docs/app/building-your-application/data-fetching/fetching) to fetch the data during the render +- Render the fetched image and caption on the page + +### 2. Dynamic Rendering with useEffect (15 minutes) + +- **Create a component that fetches NASA Mars Rover Photos from an API (with caption)** + + - Use the [NASA API](https://api.nasa.gov/#MarsPhotos) to fetch Mars Rover photos + - Implement [client-side data fetching](https://nextjs.org/docs/pages/building-your-application/rendering/client-side-rendering) using the `useEffect` hook + +- **Use useEffect to fetch data on component mount** + + - Fetch the data when the component mounts + - Handle component unmount and dependency updates + +- **Render fetched data in the component** + - Display the fetched photos and captions in the component + +### 3. Routing and Navigation Exercise (10 minutes) + +- **Create a blog website with dynamic routes to different blog posts** + + - Create a route /blogs that displays blogs + - Create a dynamic route for a blog post that displays the title from the route. For example, `/blogs/my-new-post` should dynamically display "My New Post". + - Hint: Check out the [documentation](https://nextjs.org/docs/app/api-reference/functions/use-pathname) for `usePathName`. + +- **Create a page that displays a NASA EPIC image on a different date depending on a query string parameter received** + - Use the [NASA API](https://api.nasa.gov/#EPIC) to fetch EPIC images + - Access the query string parameter using `useSearchParams` + - Fetch and display the EPIC image for the specified date + +## Advanced Components 2.1 Lecture (30 minutes) + +### Using Refs in React (10 minutes) + +- **What are refs and their use cases?** + + - Explain the purpose of refs in React + - Discuss common use cases for refs (focus management, integration with third-party libraries, etc.) + +- **Creating refs with useRef hook** + + - Introduce the `useRef` hook + - Demonstrate how to create a ref using `useRef` + +- **Accessing DOM elements with refs** + + - Show how to access and manipulate DOM elements using refs + +- **Handling focus, text selection, and media playback using refs** + - Provide examples of using refs for focus management, text selection, and media playback + +### Component Libraries (20 minutes) + +- **What are component libraries?** + + - Explain the concept of component libraries + - Discuss the benefits of using component libraries + +- **Benefits of using component libraries** + + - Consistency: Consistent design and branding across the application + - Reusability: Reusable components for faster development + - Accessibility: Built-in accessibility features + +- **Popular component library (Material-UI)** + + - Introduce Material-UI as a popular React component library + - Showcase some commonly used Material-UI components + +- **How to install and use a component library** + - Demonstrate how to install Material-UI in a Next.js application + - Show how to import and use Material-UI components + +## Advanced Components 2.1 Exercises (30 minutes) + +### 4. Build a Responsive Navbar with links to various pages (15 minutes) + +- **Use a component library (Material-UI) to create a responsive navbar** + + - Import and use the necessary Material-UI components + - Implement a responsive navbar with a hamburger menu for smaller screens + +- **Implement dynamic rendering to show/hide menu items based on screen size** + + - Use conditional rendering to show/hide menu items based on the screen size + +- **When a user clicks on an item, navigate them to the relevant page with a router or link** + - Use the `useRouter` hook to handle navigation or a `Link` component + - Implement redirects when a link is clicked + +### 5. Create a Form with Focus Management (15 minutes) + +- **Build a sign up form** + + - Create a sign-up form with first name, last name, email and phone number fields. + - Use Material-UI where possible for certain components (_not recommended for the input fields_) + +- **Use refs to manage focus on input fields** + + - Notice if MUI is used for the inputs the fact that the ref prop is called [inputRef](https://mui.com/material-ui/api/input/) in MUI + - Create refs for the input fields using the `useRef` hook + - Implement focus management using refs (e.g., focus on the next field after entering data) + +- **Implement form validation and highlight invalid fields** + + - Add form validation logic + - Highlight invalid input fields using styles or Material-UI components + +- **Redirect the user to the home page after form gets submitted** +- Add an event listener for form submit +- Once the user clicks it redirect them to a different page using the router. diff --git a/legacy/react/react2/week1/preparation.md b/legacy/react/react2/week1/preparation.md new file mode 100644 index 00000000..4dfc1ff9 --- /dev/null +++ b/legacy/react/react2/week1/preparation.md @@ -0,0 +1,7 @@ +# Preparation + +- [Next.js Router](https://nextjs.org/docs/app/building-your-application/routing) and a brief skim of the [Next Steps](https://nextjs.org/docs/app/building-your-application/routing#next-steps) (15 min) +- [SSG vs SSR](https://medium.com/@chrisebuberoland/static-site-generation-ssg-vs-server-side-rendering-in-next-js-debf43f4bb7f) (10 min) +- [Referencing Values with Refs](https://react.dev/learn/referencing-values-with-refs) (5 min) +- [Manipulating the DOM with Refs](https://react.dev/learn/manipulating-the-dom-with-refs) (10 min) +- [Material UI Getting Started](https://mui.com/material-ui/getting-started/learn/) (5 min) diff --git a/legacy/react/react2/week2/homework.md b/legacy/react/react2/week2/homework.md new file mode 100644 index 00000000..2da803f6 --- /dev/null +++ b/legacy/react/react2/week2/homework.md @@ -0,0 +1,46 @@ +# Homework + +The homework for this week is to finish the class exercises and continue working on the meal sharing app, just like the previous week. + +## Meal sharing app continued + +Let's create some routing in your `meal-sharing` repo! + +### Adding frontend routes + +The routes for the application are defined below. In the previous homework you've added content to the `Home` component which is linked to the route `/`. +To add a new route, start by creating components to attach to the route in `/frontend/components`, then define the route path in the directory and choose which components to use in the page. +Alternatively, use Material UI to import pre-made components into your application. + +| Route | Description | +| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `/` | Add a page title and a sub title. Render **some** (not all!) of the meals returned by the API and a link (a button or something out of your creative decision) to see more, which will lead to the `/meals` page. Please add more to this page like footer, menu, logo, etc. You should have the meals part already by having worked on `MealsList` (and `Meal`) component in previous homeworks. | +| `/meals/{id}` | Render the meal with the specific `id`. Add a form to create reservations for the meal. | +| `/meals` | Render all the meals returned by the API with a link to their respective pages (`meals/3`). This page is very similar to the one in '/' route, except that it lists all meals returned by the API. | + +### /meals/{id} + +The `/meals/{id}` route should display the meal and have a form for making a reservation for that meal. The form should have `phonenumber`, `name` and `email`. When creating a new reservation with a form, use the `POST /api/reservations` route. + +❗ This form should only be shown if the meal does have available reservations! + +That means that we need to: + +- When the "book seat" button is clicked get the `phonenumber`, `name` and `email` from either the form or the individual inputs; +- Now create a [post request using fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Supplying_request_options) with the `phonenumber`, `name` and `email`. +- If the request is successful indicate to the user that the request went well. If it was unsuccessful show an error message. This we could do using `alert`. You could also explore [making a modal](https://dev.to/franciscomendes10866/how-to-create-a-modal-in-react-3coc). + +### Reviews + +Create the possibility for a person to leave a review for a meal. The essence is very similar to the reservations - there is a form that submits certain information to the `reviews` endpoint of the API. +Make a choice where and when to display the form - it could follow each meal, it could have a button that shows or hides it, or it could have its own route - your app, your decision! + +## Hand in homework + +Need to brush up on the homework hand-in process? + +Check [this resource](https://github.com/HackYourFuture-CPH/Git/blob/main/homework_hand_in.md) to remember how to hand in the homework correctly! + +## Feedback + +Finally, please give some feedback to the mentors and staff [here](https://forms.gle/t3FgysinXddDRJdM8). diff --git a/legacy/react/react2/week2/lesson-plan.md b/legacy/react/react2/week2/lesson-plan.md new file mode 100644 index 00000000..bd1c4a41 --- /dev/null +++ b/legacy/react/react2/week2/lesson-plan.md @@ -0,0 +1,128 @@ +# Lesson Plan + +## Contexts 2.2 Lecture (40 minutes) + +### Introduction to Context API (10 minutes) + +- **What is the Context API?** + + - Explain the purpose of the Context API in React + - Discuss the problems it solves (prop drilling, global state management) + +- **When to use Context API?** + + - Provide guidelines on when to use the Context API + - Discuss scenarios where Context API is useful (theming, localization, authentication, etc.) + +- **Benefits of using Context API** + - Highlight the benefits of using the Context API + - Discuss how it simplifies state management and component communication + +### Creating a Context (15 minutes) + +- **Setting up a Context** + + - Demonstrate how to create a new Context using the `createContext` function + - Explain the purpose of the default value in `createContext` + +- **Creating a Context Provider** + + - Show how to create a Context Provider component + - Discuss the role of the Provider in providing context values + +- **Providing value to Context** + - Demonstrate how to provide context values using the `value` prop of the Provider + +### Introduction to Reducers (15 minutes) + +- **What is a Reducer?** + + - Explain the concept of a reducer function in React + - Discuss the relationship between reducers and state management + +- **Why use Reducers?** + + - Highlight the benefits of using reducers for state management + - Discuss scenarios where reducers are useful (complex state updates, centralized state management) + +- **Reducer syntax and structure** + - Introduce the reducer function syntax (state, action) => newState + - Explain the purpose of actions and action types + - Demonstrate how to update state based on actions in a reducer + +## Contexts 2.2 Exercises (30 minutes) + +### 1. Implementing a Theme Context (15 minutes) + +- **Implementing a theme context using our own context provider** + + - Create a context for managing the application theme + - Implement a context provider component to provide the theme value + - Use the context in a component to consume the theme value + +- **Implementing a theme context using Material UI** + - Explore the [Material-UI theme provider](https://mui.com/material-ui/customization/theming/) and theme consumer + - Implement a theme context using Material + +### 2. Set up localization (15 minutes) + +- **Set up localization using Material UI** +- Use the [localization component](https://mui.com/material-ui/guides/localization/) with the theme context +- Provide language data to the Context +- Consume and display the language in a component + +## Contexts with Reducers 2.2 Lecture (20 minutes) + +### Combining Context and Reducers (20 minutes) + +- **Passing Reducer dispatch function via Context** + + - Explain how to pass the dispatch function from the reducer to components via Context + - Demonstrate how to create a context and provide the dispatch function as part of the context value + +- **Updating state using the dispatch function** + - Show how components can access the dispatch function from the context + - Demonstrate how to dispatch actions to update the state using the reducer + +## Contexts with Reducers 2.2 Exercises (30 minutes) + +### 3. Build a CounterContext with Reducer (15 minutes) + +- **Create a CounterContext** + + - Set up a new context for managing a counter state + +- **Implement a Reducer for increment and decrement actions** + + - Define a reducer function to handle increment and decrement actions + - Update the counter state based on the received actions + +- **Consume the CounterContext and update the count** + - Create a component that consumes the CounterContext + - Implement buttons or UI elements to dispatch increment and decrement actions + - Display the current count value from the context + +### 4. Create a TodoContext with Reducer (15 minutes) + +- **Set up a TodoContext with a Reducer** + + - Create a new context for managing a todo list state + - Define a reducer function to handle actions related to todos (add, remove, toggle) + +- **Implement actions for adding, removing, and toggling todos** + + - Define action types and action creators for adding, removing, and toggling todos + - Update the todo list state based on the received actions in the reducer + +- **Consume the TodoContext and display the todo list** + + - Create a component that consumes the TodoContext + - Render the todo list using the state from the context + +- **Use the TodoContext in a Next.js page** + + - Import and consume the TodoContext in a Next.js page component + +- **Add functionality to add and remove todos** + - Implement UI elements (input, buttons) to dispatch actions for adding and removing todos + - Use the dispatch function from the context to update the todo list state diff --git a/legacy/react/react2/week2/preparation.md b/legacy/react/react2/week2/preparation.md new file mode 100644 index 00000000..515d76e2 --- /dev/null +++ b/legacy/react/react2/week2/preparation.md @@ -0,0 +1,6 @@ +# Preparation + +- [Context](https://react.dev/learn/passing-data-deeply-with-context) (10 min) +- [Reducer](https://react.dev/learn/extracting-state-logic-into-a-reducer) (10 min) +- [Combining reducers with context](https://react.dev/learn/scaling-up-with-reducer-and-context) (15 min) +- [Material UI Crash Course](https://www.youtube.com/watch?v=3quQ6KNGUh0) (Optional - 45 min)