diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index bc8423f1a..000000000 Binary files a/.DS_Store and /dev/null differ diff --git a/README.md b/README.md index b1c137e21..fe796b869 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ Potential Topics-- 1. Learning Spring Data JPA 13. TinyMCE API with ReactJS 14. SQL + 15. TipTap 16. Tailwind diff --git a/Topics/Dev_Ops.md b/Topics/Dev_Ops.md index a50f25ab2..32ea03b12 100644 --- a/Topics/Dev_Ops.md +++ b/Topics/Dev_Ops.md @@ -1,3 +1,5 @@ ## Resources for Deploying Applications -### [Deploying Django to AWS](./Tech_Stacks/Deploying_Django_to_AWS.md) \ No newline at end of file +### [Deploying Django to AWS](./Tech_Stacks/Deploying_Django_to_AWS.md) + +### [Build an Android React Native App Using GitHub Actions](./Tech_Stacks/build-android-app-using-github-actions.md) diff --git a/Topics/Development_Process/Code Smells/Code_Smells.md b/Topics/Development_Process/Code Smells/Code_Smells.md new file mode 100644 index 000000000..e4b739dfd --- /dev/null +++ b/Topics/Development_Process/Code Smells/Code_Smells.md @@ -0,0 +1,178 @@ +# Code Smells + +## Table of Contents +1. [What is code smell?](#what-is-code-smell) +2. [Duplicate Code](#duplicate-code) +3. [Improper Names](#improper-names) +4. [Dead Code](#dead-code) +5. [Middle Man](#middle-man) +6. [Feature Envy](#feature-envy) +7. [Long Functions](#long-functions) +8. [Data Clumps](#data-clumps) +9. [Additional Resources](#additional-resources) + +### What is a code smell? + +Code smells are indicators of potential issues or weaknesses in software code. They are not bugs or errors, but rather patterns or practices that may lead to problems in the future. + +## Common Types of Code Smells and How They Can Harm your Code + +There are a vast number of code smells and they differ from project to project and developer to developer, and business to business. + +So, it is crucial to thoroughly understand the organization’s design and development standards before handling any code smell. + +Here are the most common code smells that developers usually encounter with: + +### Duplicate Code + +In simple terms, duplicate code happens when two code fragments look almost identical. Consider this piece of code: + +``` +def calculate_rectangle_area(length, width): + return length * width + +# Duplicate code +def calculate_square_area(side): + return side * side +``` + +In this example, the `calculate_square_area` function duplicates the functionality of the `calculate_rectangle_area` function but only for squares. This coding habit makes it harder to debug a program because any changes or bug fixes need to be applied to multiple places. Also, duplicated code makes the codebase harder to read and understand. Developers might need to analyze multiple sections of code that are essentially doing the same thing. + +### Improper Names + +If your variables, classes, and functions lack proper names, this can be an indicator that your code isn’t clean. For example, + +``` +def func(a, b): + return a + b +``` +This function is simple enough to understand despite its naming issue. However, imagine that we have a big function to perform some backend tasks for our program, +then it would be more problematic for other developers. Without additional context or comments, it's not immediately clear what the function is supposed to do. +This can lead to confusion for others who encounter this code later or who need to work with it. + +### Dead Code + +Dead code is code that’s in the application but not in use. Here is an example, + +``` +public class Calculator { + public int add(int a, int b) { + return a + b; + } + + // This method is never called, making it dead code + public int subtract(int a, int b) { + return a - b; + } +} + +``` + +The `subtract` method is never called from any part of the application. It remains in the codebase, occupying space and potentially causing confusion for developers who might assume it serves a purpose. + +### Middle Man + +This code smell refers to a situation where an object or method serves mainly as a pass-through or intermediary, delegating most of its functionality to another object or method without adding significant value or functionality of its own. This can introduce unnecessary complexity and reduce the clarity and efficiency of the codebase. + +``` +class DataManager: + def __init__(self, data): + self.data = data + + def process_data(self): + data_processor = DataProcessor() + return data_processor.process(self.data) + +class DataProcessor: + def process(self, data): + # Some complex data processing logic here + processed_data = data * 2 + return processed_data +``` + +In this example, the `DataManager` class serves as a middle man that merely delegates the data processing to the `DataProcessor` class. It doesn't add any additional functionality or logic of its own and exists primarily to pass data to another class. + +### Feature Envy + +This happens when a method accesses the data of another object more than its own data. Consider this piece of code: + +``` +class ShoppingCart: + def __init__(self): + self.items = [] + + def add_item(self, item): + self.items.append(item) + + def total_price(self, tax_rate): + total = 0 + for item in self.items: + total += item.price + total *= (1 + tax_rate) + return total + +class Item: + def __init__(self, name, price): + self.name = name + self.price = price + +class User: + def __init__(self): + self.shopping_cart = ShoppingCart() + + def calculate_total_price(self, tax_rate): + return self.shopping_cart.total_price(tax_rate) +``` + +The `User` class has a method calculate_total_price that calculates the total price of items in the user's shopping cart. However, instead of directly accessing the user's shopping cart and performing the calculation there, it invokes the `total_price` method of the `ShoppingCart` class. This leads to poor encapsulation and violate the principle of encapsulation, where each class should encapsulate its own behavior and data. + +### Long Functions + +Long functions is a code smell that occurs when a function or method is excessively long, containing a large number of lines of code. Long functions can be difficult to understand, maintain, and test. They often violate the Single Responsibility Principle, which states that a function should only have one reason to change. + +``` +def process_order(order): + # Step 1: Validate order data + if not order: + return None + # Step 2: Fetch product information + product_info = fetch_product_info(order.product_id) + # Step 3: Calculate total price + total_price = order.quantity * product_info.price + # Step 4: Apply discounts + if order.discount_code == 'DISCOUNT10': + total_price *= 0.9 + # Step 5: Apply taxes + total_price *= 1.15 # Assuming 15% tax rate + # Step 6: Generate invoice + invoice = generate_invoice(order, product_info, total_price) + # Step 7: Send confirmation email + send_confirmation_email(order.email, invoice) +``` + +In this example, the `process_order` function performs multiple steps, including validation, fetching product information, calculating total price, applying discounts and taxes, generating an invoice, and sending a confirmation email. The function is long and complex, which makes it difficult to understand and maintain. + +### Data Clumps + +Data clumps occur when multiple pieces of data go together. One easy way to spot a data clump is when one component doesn’t make sense in isolation but makes sense as a group. Here's an example to illustrate the data clumps: + +``` +def create_user(name, email, phone): + # Function to create a user using name, email, and phone + pass + +def update_user_email(user_id, new_email): + # Function to update user's email + pass + +def send_notification(email, message): + # Function to send email notification + pass +``` + +In this example, the `name`, `email`, and `phone` parameters are frequently passed together in various functions. This suggests that these pieces of data are closely related and should be put together in the same class. + + +# Additional Resources +1. [Refactoring Guru](https://refactoring.guru/refactoring/smells) +2. [What is a code smell?](https://linearb.io/blog/what-is-a-code-smell) diff --git a/Topics/Development_Process/Docker_AWS_ECR_ECS_CD.md b/Topics/Development_Process/Docker_AWS_ECR_ECS_CD.md new file mode 100644 index 000000000..9027f4085 --- /dev/null +++ b/Topics/Development_Process/Docker_AWS_ECR_ECS_CD.md @@ -0,0 +1,101 @@ +# CD for a Dockerized application using Github Actions, Amazon ECR and Amazon ECS + +## Introduction +Containerized applications are becoming more popular due to the consistency they provide accross different machines and portability to different cloud providers. It is becoming increasingly valuable to build applications with dockerization in mind. With that comes the need to streamline deployment of these containerized applications. + +## Pre-Requisites +- [Dockerizing an app](./Docker.md) +- [Github Actions](./Github_Actions.md) + +## Step 1 (Setting up your application & AWS): +- Essentially you want to follow the same steps as this tutorial [Deploy Node.js Docker AWS](./Deploy_Node.js_Docker_AWS.md), adjusting your dockerfile according to language and tools you are using for your application. The main goals are to + - Containerize your application + - Create an amazon ECR repository + - Create an ECS cluster, service as well as task definition + +**NOTE**: It's important that your ECR repository and ECS cluster are defined on the same AWS region otherwise you may have to sign into aws twice below + + +## Step 2 (Setting up the workflow -- triggers): +``` +on: + push: + branches: + - production +``` +- With the above code we ensure that the workflow created in this guide is run only on pushes to the "production" branch +- Generally you only want to deploy your application on pushes to some branch designated as your production branch to avoid wasting github actions minutes and deploying when development is underway + +## Step 2 (Setting up the workflow triggers): +Create a new job +``` +jobs: + deploy: + name: Deploy + runs-on: ubuntu-latest + environment: production + + steps: +``` +- We'll be creating a new job called deploy that runs on an ubuntu instance +- All subsequent steps will fall under the "steps:" section in the code block above + +## Step 3 (Checking out the repo) +``` +- name: Checkout + uses: actions/checkout@v4 +``` +- Create a new step for checking out the current repo. This ensures that in subsequent steps you have access to all code within your current repo + +## Step 4 (Signing into AWS) +``` +- name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@0e613a0980cbf65ed5b322eb7a1e075d28913a83 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: +- name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@62f4f872db3836360b72999f4b87f1ff13310f3a +``` +- For details on how to quickly set up your AWS credentials, view the following video: https://www.youtube.com/watch?v=gswVHTrRX8I +- From the above video, you should have recieved an access key as well as a secret access key which you should then set in your [Github Secrets](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions) +- Setting secrets ensures that you have access to your credentials within your workflow without explicitly writing them out in the workflow file +- We are using an action defined by someone else to aid us in signing into aws for subsequent steps + +## Step 5 (Building/tagging your image and pushing it to your ECR repo) +``` +- name: Build, tag, and push image to Amazon ECR + id: build-image + run: | + docker build -t /:latest + docker push /:latest +``` +- Just like how we build the docker image in order to run a container locally, we should build, tag and push our image to our ECR repository so that ECS can pull from it in a future step +- The `DOCKERFILE_FOLDER_PATH` is the path to the folder containing the dockerfile to build your application +- The `ECR_REGISTRY` and `ECR_REPOSITORY` can be retrieved from the repository URI +Screenshot 2024-03-17 at 9 41 59 PM + +## Step 6 (Deploying the application) +``` +- name: Deploy Amazon ECS task definition + uses: aws-actions/amazon-ecs-deploy-task-definition@df9643053eda01f169e64a0e60233aacca83799a + with: + task-definition: + service: + cluster: + wait-for-service-stability: true +``` +- Once again, using an existing action, we will deploy the app by specifying some additional information +- The task definition, ECS service and ECS cluster are defined as per [Deploy Node.js Docker AWS](./Deploy_Node.js_Docker_AWS.md) +- For `` you should link to that path of your aws task definition JSON file in your repository. If you don't have one in your repository you can generate one by visiting the task definitions page in Amazon ECS Screenshot 2024-03-17 at 9 30 22 PM + + +- `wait-for-service-stability` keeps the workflow from passing until the ECS service has become stable given the most recent deployment + +## Conclusion +Congrationations, you have reached the end of this tutorial! After a push to your production branch you should be able to sit back and watch your newest workflow deploy your app for you! + +## Reference +This guide is inspired by this github actions guide [Deploying to amazon elastic container service](https://docs.github.com/en/actions/deployment/deploying-to-your-cloud-provider/deploying-to-amazon-elastic-container-service) diff --git a/Topics/Development_Process/Vercel_Frontend_Deployment.md b/Topics/Development_Process/Vercel_Frontend_Deployment.md index 4705259d1..c603d5b32 100644 --- a/Topics/Development_Process/Vercel_Frontend_Deployment.md +++ b/Topics/Development_Process/Vercel_Frontend_Deployment.md @@ -5,6 +5,9 @@ ### [What is Vercel?](#what-is-vercel-1) ### [Why Deploy with Vercel?](#why-deploy-with-vercel-1) ### [How to Deploy on Vercel?](#how-to-deploy-on-vercel-1) +### [Deploying with Vercel CLI](#deploying-with-vercel-cli-1) +### [Security Best Practices for Deploying on Vercel](#vercel-security) +### [Search Engine Optimization (SEO) for Sites Deployed on Vercel](#vercel-seo) ### [Advanced Vercel Features](#advanced-vercel-features-1) ### [Useful Articles](#useful-articles-1) @@ -63,6 +66,147 @@ This section covers the steps to deploy a frontend project on Vercel: Vercel Step-by-Step Tutorial: Vercel's own documentation offers a comprehensive step-by-step tutorial that guides you through the process of using their platform. It's designed as an end-to-end guide for developers to create and deploy web applications​. (https://vercel.com/docs/getting-started-with-vercel) +## Deploying with Vercel CLI + +Deploying your project using the Vercel CLI offers flexibility and control over the deployment process. Follow these steps to deploy your frontend project with Vercel CLI: + +1. **Install Vercel CLI**: If you haven't already installed the Vercel CLI, you can do so by running the following command in your terminal: + +```bash +npm install -g vercel +``` + +2. **Login to Vercel**: Log in to your Vercel account using the following command: + +```bash +vercel login +``` + +select your method of authentation (Github, GitLab, Bitbucket, etc) and follow instructions on logging in +3. **Navigate to Project Directory**: Use the `cd` command to navigate to your project directory in the terminal: + +```bash +cd path/to/your/project +``` + +4. **Initialize Deployment**: Once you're in your project directory, initiate the deployment process by running: + +```bash +vercel +``` + +5. **Follow Deployment Prompts**: Vercel CLI will guide you through the deployment process with a series of prompts: + +- Choose the scope (personal account or team) for the deployment. +- Choose project name +- Confirm the project to deploy. +- Review and confirm deployment settings such as the framework (e.g Next.js, Create React App) and project settings (e.g Build Command, Development Command, Install COmmand, Output Directory) +- Note, Vercel will automatically detect your framework (e.g React, Vue, Angular) and determine the appropriate build settings based on the detected framework. +![](./assets/Vercel_CLI.png) + +6. **Monitor Deployment**: After confirming the deployment settings, Vercel CLI will start deploying your project. You can monitor the deployment progress directly in your terminal. + +7. **Access Deployment URL**: Once the deployment is complete, Vercel CLI will provide you with a URL where your project is hosted. You can visit this URL to access your deployed frontend application. + +8. **Additional Deployment Options**: Vercel CLI offers additional options for customizing your deployment process, such as setting environment variables, specifying deployment regions, and more. Refer to the Vercel CLI documentation for advanced usage. + +By following these steps, you can deploy your frontend project using Vercel CLI, leveraging its simplicity and flexibility for a seamless deployment experience. [For more information, see the Vercel documentation](https://vercel.com/docs/cli/deploy). + +### Adding Environment Variables + +Environment variables are an important part of the project.Here's how you can add environment variables using Vercel CLI: + +The `--build-env` option, shorthand `-b`, allows you to provide environment variables to the build step. Here's an example of how to use it: + +```bash +vercel --build-env KEY1=value1 --build-env KEY2=value2 +``` + +This command sets environment variables KEY1 and KEY2 with the respective values value1 and value2 during the build process. + +The --env option, shorthand -e, allows you to provide environment variables at runtime. Here's an example: + +```bash +vercel --env KEY1=value1 --env KEY2=value2 +``` + +This command sets environment variables KEY1 and KEY2 with the respective values value1 and value2 during runtime. + +For more CLI usages, refer to [Vercel documentation](https://vercel.com/docs/cli/deploy). + +## Security Best Practices for Deploying on Vercel + +When deploying applications on Vercel, ensuring the security of your frontend and its data is paramount. Here are key practices to help you safeguard your deployments: + +### Environment Variables +- Store sensitive information such as API keys, database URIs, and secret tokens in environment variables instead of hardcoding them into your application code. Vercel supports environment variables, making it easy to manage sensitive data securely. +- Always encrypt sensitive information before storing it. Vercel encrypts environment variables at rest, but it's crucial to encrypt them before transmission or use additional layers of encryption for highly sensitive data. +- Limit access to environment variables to those who absolutely need it. Use Vercel's team management features to control who can view or modify environment variables. + +### HTTPS Enforcement +- Vercel automatically provides HTTPS for all deployments, ensuring data transmitted between your application and its users is encrypted. Always use HTTPS to protect your application from man-in-the-middle attacks. +- Consider implementing HTTP Strict Transport Security (HSTS) headers to prevent downgrade attacks and ensure secure connections. + +### Access Control +- Ensure that only authorized users can access your Vercel account and projects. Use strong, unique passwords and enable two-factor authentication (2FA) for an added layer of security. +- Use Vercel’s edge functions to implement rate limiting, protecting your application from brute force and denial-of-service attacks. + +### Security Headers +- Utilize HTTP security headers to add another layer of protection for your web applications against common vulnerabilities and attacks. This includes headers like Content Security Policy (CSP), X-Content-Type-Options, Strict-Transport-Security, and others. +- A CSP helps mitigate cross-site scripting (XSS) and data injection attacks. Define a CSP that specifies which domains are allowed to execute scripts, load resources, and so forth. +- Start with CSP in report-only mode to understand its impact on your application without blocking legitimate resources. + +### Regularly Update Dependencies +- Keep all your project dependencies up to date. This includes the libraries and frameworks your application uses. Outdated dependencies may contain security vulnerabilities that attackers can exploit. +- Example (update all dependencies in package.json): +```bash +npm update +``` + +### Learn more +- https://vercel.com/security + +## Search Engine Optimization (SEO) for Sites Deployed on Vercel + +Maximizing the visibility of your Vercel-deployed sites in search engine results is crucial for attracting traffic. Implement these SEO strategies to improve your site’s ranking: + +### Optimize Site Performance +- Vercel's Global CDN automatically ensures that your site is delivered quickly to users worldwide. Fast loading times improve user experience and SEO. +- Optimize images using next-gen image formats and ensuring images are optimally sized for the web to decrease load times. You can use tools like Next.js' Image component to automatically optimize images for speed. +- Use compression algorithms like Brotli to reduce the size of your HTML, CSS, and JavaScript files. + +### Improve User Experience (UX) +- Make sure your site is fully responsive and looks good on all devices, as mobile-friendliness is a ranking factor. +- Ensure your site is accessible to all users, including those with disabilities. This includes proper use of HTML semantics, alt tags for images, and ARIA labels where necessary. + +### Content and Metadata Optimization +- Proper use of meta tags (unique title and description) on each page can help search engines understand your content better. +- Implement structured data (using schema.org) to help search engines understand the context of your content, enabling rich snippets in search results. +- Use clear, descriptive URLs that include keywords relevant to your content. + +### Fast and Secure Connections +- Vercel provides SSL certificates for all deployments, ensuring secure and encrypted connections. A secure site is a ranking factor for Google. +- Minimize the use of redirects and ensure they are implemented correctly. Excessive redirects can slow down your site and negatively impact SEO. + +### High Quality Content +- Create high-quality, relevant content that answers the needs of your audience. Use appropriate keywords naturally within your content. +- Update Content Regularly. Keep your site fresh and updated with new content to signal to search engines that your site is active. +- Backlinks from reputable sites can significantly boost your site's authority and search ranking. Focus on creating valuable content that others want to link to. + +### Utilize Server-Side Rendering (SSR) or Static Site Generation (SSG) +- Use Next.js for your projects on Vercel to take advantage of SSR or SSG. These approaches can help ensure that your content is fully rendered and indexable by search engines when they crawl your site. + +### Sitemaps and Robots.txt +- Create and submit a sitemap to search engines to help them discover and index your pages. +- Use a robots.txt file to control which parts of your site should be crawled and indexed by search engines. + +### Monitor and Analyze Your SEO Performance +- Regularly monitor your site’s performance in search results with tools like Google Search Console. This can help you identify and fix any issues that might be affecting your ranking. +- Stay up-to-date with the latest best practices and search engine guidelines. + +### Social Media Integration +- Use social media to promote your content and create backlinks to your site, increasing traffic and engagement. + ## Advanced Vercel Features - **Custom Domains**: @@ -84,10 +228,11 @@ Each feature comes with its own set of practices and considerations. These resou At the end of this guide, you'll have a comprehensive understanding of Vercel's capabilities and be ready to utilize it for your frontend projects. +## Useful Articles Some useful article for using Vercel: 1. **Using Templates in Vercel**: This guide helps you to leverage popular frontend frameworks and maximize Vercel's features. It also details how Vercel can create a new repository with your chosen Git provider for easy project updates after deployment​. (https://vercel.com/docs/getting-started-with-vercel/template) 2. **Deploying Front-End Applications on Vercel**: This is a walkthrough for deploying front-end applications, especially focusing on static and Jamstack apps. It includes instructions for deploying Next.js JSS apps and highlights Vercel's support for Next.js. (https://doc.sitecore.com/xmc/en/developers/xm-cloud/walkthrough--deploying-your-front-end-application-to-vercel.html) 3. **Creating & Deploying React Apps to Vercel**: -If you're focused on React applications, Vercel provides a guide for deploying React sites. This documentation explains how to deploy your site with zero configuration and connect to your favorite APIs, databases, and content management systems. (https://vercel.com/guides/deploying-react-with-vercel) \ No newline at end of file +If you're focused on React applications, Vercel provides a guide for deploying React sites. This documentation explains how to deploy your site with zero configuration and connect to your favorite APIs, databases, and content management systems. (https://vercel.com/guides/deploying-react-with-vercel) diff --git a/Topics/Development_Process/assets/Vercel_CLI.png b/Topics/Development_Process/assets/Vercel_CLI.png new file mode 100644 index 000000000..303a2694a Binary files /dev/null and b/Topics/Development_Process/assets/Vercel_CLI.png differ diff --git a/Topics/Product_Management.md b/Topics/Product_Management.md index cf8d2c49c..f51eb76f1 100644 --- a/Topics/Product_Management.md +++ b/Topics/Product_Management.md @@ -57,6 +57,12 @@ Bezos laid the foundation for Amazon's business and management methodology in hi These principles illustrate Amazon's customer-centric culture and highlight the vital role of forward-thinking in product management. By consistently focusing on customer satisfaction and long-term value, Amazon demonstrates the effectiveness of a client-centered approach in product development and corporate strategy. You can read more about this in this [article](https://www.hustlebadger.com/what-do-product-teams-do/jeff-bezos-leadership-principles/#its-all-about-the-long-term). -1. Core Concepts in Product Management - 1. [Product Management vs Product Ownership](./Product_Management/Product_Management_vs_Product_Ownership.md) +------ + +------ + +### Core Concepts in Product Management: +1. [Product Management vs Product Ownership](./Product_Management/Product_Management_vs_Product_Ownership.md) +2. [Agile Product Development Methodologies](./Product_Management/Agile_Methodologies_Product_Management.md) +3. [User-Centered Design (UCD) Vs. Design-Driven Development (DDD)](./Product_Management/UCD_vs_DDD.md) diff --git a/Topics/Product_Management/Agile_Methodologies_Product_Management.md b/Topics/Product_Management/Agile_Methodologies_Product_Management.md new file mode 100644 index 000000000..775cb3d0a --- /dev/null +++ b/Topics/Product_Management/Agile_Methodologies_Product_Management.md @@ -0,0 +1,51 @@ + +# Introduction to Agile Product Development Methodologies + +## Table of Contents +- [Background](#back) +- [Agile Tools](#tools) +- [Importance for Product Managers](#pm) + + + +------ + +------ + +## Background +In today's dynamic tech landscape, where adaptability and efficiency reign supreme, Agile product development methodologies have become indispensable for Product Managers seeking to deliver exceptional user experiences. Agile methodologies offer a flexible and iterative approach to product development, enabling teams to respond swiftly to changing requirements and deliver value incrementally. + +## Understanding Agile Methodologies +### Basic Overview +Agile is a collaborative and iterative approach to software development, emphasizing flexibility, customer collaboration, and responsiveness to change. It prioritizes delivering working software in short cycles, allowing teams to gather feedback early and adapt their plans accordingly. + + +### Agile Tools (Lean, Kanban, MVC, Scrum) +Agile encompasses various frameworks and methodologies, each offering unique benefits and approaches to product development. +Provided are basic descriptions of each agile methodology. If you are interested in learning about these topics in more detail please click on them for in more in depth pages. +* [Lean](./../Software_Engineering/Lean.md): Lean principles focus on eliminating waste and maximizing value delivery. It emphasizes continuous improvement, customer focus, and minimizing work in progress. +* [Kanban](./../Software_Engineering/Kanban.md): Kanban is a visual framework for managing work, often used in Agile development. It emphasizes visualizing work, limiting work in progress, and maximizing flow. +* MVC (Minimum Viable Product): MVC is a strategy for developing products with the minimum set of features needed to satisfy early customers and provide feedback for future development. +* [Scrum](./../Software_Engineering/Scrum.md): Scrum is an Agile framework that emphasizes iterative development, regular inspection, and adaptation. It divides work into time-boxed iterations called sprints, with a focus on delivering a potentially shippable product increment at the end of each sprint. + +## Agile Product Planning & Prioritization +### [User Story Mapping](./../Software_Engineering/User_Stories.md) +User story mapping is a technique used to visualize and prioritize user requirements. It helps Product Managers identify user needs, prioritize features, and plan product releases effectively. + +### Roadmapping +Roadmapping involves creating a strategic plan for product development, outlining key milestones, features, and timelines. It helps Product Managers communicate product vision, align stakeholders, and make informed decisions about resource allocation and prioritization. + + + +------ + +------ + + + +## Importance for Product Managers +Agile methodologies offer Product Managers a structured approach to product development that prioritizes collaboration, flexibility, and responsiveness to customer needs. By embracing Agile principles, Product Managers can effectively lead cross-functional teams, adapt to changing market conditions, and deliver value incrementally to customers. Agile methodologies also enable Product Managers to foster a culture of continuous improvement and innovation, driving product excellence and customer satisfaction. + +In summary, Agile product development methodologies are essential tools for Product Managers seeking to deliver exceptional user experiences in today's fast-paced and competitive market. By understanding and leveraging Agile principles, Product Managers can effectively navigate the complexities of product development, drive innovation, and deliver value to customers consistently. + + diff --git a/Topics/Product_Management/Trello_Management_Techniques.md b/Topics/Product_Management/Trello_Management_Techniques.md new file mode 100644 index 000000000..8fa71b3d4 --- /dev/null +++ b/Topics/Product_Management/Trello_Management_Techniques.md @@ -0,0 +1,299 @@ +# Outline for Trello Use in Software Project Management + + +## Table of Content +### [Introduction](#Introduction) +### [Getting Started with Trello](#Getting-Started-with-Trello) +### [Setting up Your Trello Board](#Setting-up-Your-Trello-Board) +### [Best Practices for Managing Tasks](#Best-Practices-for-Managing-Tasks) +### [Enhancing Collaboration with Trello](#Enhancing-Collaboration-with-Trello) +### [Integrating Trello with Other Tools](#Integrating-Trello-with-Other-Tools) +### [References](#references) + + +## Introduction + +In the dynamic world of software development, effective project management stands as a cornerstone of success. +Among the plethora of tools available, Trello emerges as a remarkably intuitive and flexible platform designed +to streamline task organization and enhance team collaboration. With its visual boards, lists, and cards, Trello +offers a user-friendly interface that caters to the planning and execution needs of software projects of all sizes. + +This guide is tailored specifically for CSC301 students and anyone interested in harnessing the power of Trello to +optimize their project management practices. Our objective is to provide a comprehensive overview of Trello's +capabilities, from setting up your first board to employing advanced features that facilitate seamless collaboration +among team members. Whether you're undertaking a group project, managing assignments, or coordinating with a +development team, this guide aims to equip you with the knowledge and skills to leverage Trello effectively, +ensuring your projects are not only well-organized but also completed efficiently and successfully. + +By the end of this guide, you'll have a solid foundation in utilizing Trello for software project management, +enabling you to navigate your projects with greater ease and confidence. + +![trello logo](https://res.cloudinary.com/dlyqagele/image/upload/v1710100888/CSC301/thnkp9etom0ogplpegxx.png) + +## Getting Started with Trello + +To effectively utilize [Trello](https://www.trello.com) for your software project management needs, familiarizing yourself with the platform's +basics is essential. This section will guide you through the initial steps of getting started with Trello, from +signing up to navigating its interface efficiently. + +### Signing Up for Trello: + +
    +
  • Begin by visiting the Trello website and signing up for a new account. You can sign up using your email address + or directly through your Google or Microsoft account for added convenience.
  • +
  • Once your account is created, Trello will prompt you to create your first board, which is your workspace for + organizing tasks and projects.
  • +
+ +### Understanding the Trello Interface +![trello_board](https://res.cloudinary.com/dlyqagele/image/upload/v1710279742/CSC301/hgtczrtw4uiqrgd5fbhx.png) +
    +
  • Boards: The heart of Trello, boards are where your project’s tasks (or cards) are visually + organized. Each board represents a project or a significant component of your work.
  • +
  • Lists: Within each board, you can create lists to categorize tasks based on their status, such + as "To Do," "In Progress," and "Completed." Lists help in tracking the progress of your project.
  • +
  • Cards: The basic unit of tasks within Trello. You can add cards to your lists, representing + individual tasks or items that need attention. Cards can be moved between lists as their status changes.
  • +
  • Features for Collaboration: Trello allows you to invite team members to your board, + assign tasks to specific individuals, and communicate through comments on cards. It's a centralized + space for your team to collaborate and stay updated on the project's progress.
  • +
+ +### Navigation Tips: + +
    +
  • Utilize the menu options on the right side of the board to access board settings, add team members, + and integrate with other apps.
  • +
  • Explore keyboard shortcuts in Trello to speed up your workflow. Trello offers a variety of shortcuts + for common actions, which can enhance your efficiency.
  • +
+ +## Setting up Your Trello Board + +A well-organized Trello board is pivotal for effective project management. This section outlines step-by-step +instructions to create a Trello board specifically designed for your software project, and how to utilize lists and +cards to maintain an organized workflow. + +### Creating a Trello Board +![trello_board_create](https://res.cloudinary.com/dlyqagele/image/upload/v1710281807/CSC301/sv0j29smgio624khfcui.png) +

1. Navigate to Your Dashboard: Log into your Trello account, and on the dashboard, click the "Create" + button on the top left corner of the screen, then select "Create Board".

+ +

2. Board Configuration: Assign a name to your board that reflects the project or task theme it will + manage. Choose a background color or image for visual distinction.

+ +

3. Privacy Settings: Decide on the board's visibility. You can set it as private (visible to you and + anyone you invite), workspace (if you're part of a Trello team), or public (visible to anyone with the link).

+ +

4. Create the Board: Click “Create” after configuring the settings. Your new board is now ready + for customization and task management.

+ +![trello_board_create](https://res.cloudinary.com/dlyqagele/image/upload/v1710281966/CSC301/khn0cfhwwf528rgnnktc.png) +### Setting Up Lists + +Lists represent different stages or types of tasks in your project. Typical lists for a software project might include +"To Do", "In Progress", "Testing", and "Done". + +

1. Creating Lists: Click on the "Add a list" option on your board. Name the list according to the + phase of the task it represents and click "Save".

+ +

2. Organizing Lists: You can click and drag lists to rearrange them on your board. Arrange them in + a logical order that reflects your workflow.

+ +### Utilizing Cards +Cards are the individual tasks or items that need to be completed. They can be added to lists and moved between them as +they progress through different stages of your project. + +

1. Adding Cards: To add a new card, click on "Add a card" at the bottom of any list. Enter a + concise title for the task and click "Enter". You can open the card to add more details, such as descriptions, + checklists, due dates, attachments, and comments.

+ +

2. Moving Cards: As tasks progress from one stage to another, simply click and drag cards from + one list to another. This visual movement helps track the progress of tasks through your workflow.

+ +

3. Detailed Information: Each card can hold a significant amount of information, making it a + comprehensive tool for task management. You can assign cards to specific team members, add labels for easy + categorization, set deadlines, and more.

+ +### Tips for Effective Board Management + +
    +
  • Regular Updates: Keep your board up-to-date by regularly reviewing and adjusting cards and lists. + This ensures that the board accurately reflects the current status of your project.
  • +
  • Board Templates: Trello offers a variety of templates for different projects and purposes. + Exploring these templates can provide inspiration and possibly a jumpstart in setting up your board.
  • +
+ + + +## Best Practices for Managing Tasks + +Effective task management is crucial for the smooth operation and success of any project. In this section, +we explore best practices for managing tasks within Trello, focusing on categorization, assignment, prioritization, and +deadline setting to optimize project workflow and team productivity. + +### Categorizing Tasks Using Lists +![trello_tasks](https://res.cloudinary.com/dlyqagele/image/upload/v1710283639/CSC301/l3tsj0ku7of1n2bvyphj.png) +Lists are a versatile feature in Trello that can be used to categorize tasks into different stages or types, providing +a clear overview of project progress. Common categorizations include: + +
    +
  • To Do: Tasks that are yet to be started.
  • +
  • In Progress: Tasks that are currently being worked on.
  • +
  • Review: Tasks that require review or testing.
  • +
  • Done: Tasks that have been completed.
  • +
+ +Tips: +
    +
  • Customize your lists to reflect your specific project workflow. You might add lists for "Backlog," "Testing," or + "Awaiting Feedback" depending on your project's needs.
  • +
  • Use the board's flexibility to adapt to project changes. Lists can be added, removed, or renamed as your project + evolves.
  • +
+ +### Assigning Tasks to Team Members +![trello_assign_members](https://res.cloudinary.com/dlyqagele/image/upload/v1710283769/CSC301/js6jbzljpova5cw0cuyf.png) + +Proper task assignment ensures that every team member knows their responsibilities, leading to efficient task +completion. + +Tips: +
    +
  • To assign a task, add members to a card. Click on the card, then select "Members" and add the + appropriate team members.
  • +
  • Communicate task expectations and deadlines clearly when assigning tasks. Use the card's description and comment + features to provide detailed instructions and expectations.
  • +
+ +### Using Labels for Task Prioritization and Categorization +![trello_labels](https://res.cloudinary.com/dlyqagele/image/upload/v1710283878/CSC301/mit8qybmgdkqzl1w7ipf.png) + +Labels provide a visual cue for task prioritization and categorization, making it easier to sort and +identify tasks at a glance. + +Tips: +
    +
  • Create a color-coded labeling system. For example, use red for high priority, yellow for medium, + and green for low.
  • +
  • Labels can also categorize tasks by type (e.g., "Bug," "Feature," "Improvement") or by team + (e.g., "Frontend," "Backend," "UI/UX").
  • +
  • To add a label, open a card and select "Labels." You can choose from existing labels or + create new ones.
  • +
+ +### Setting Deadlines and Using the Calendar Feature +![trello_ddl](https://res.cloudinary.com/dlyqagele/image/upload/v1710284054/CSC301/yhfpbb0nwiplk3pnk4i9.png) + +Deadlines are critical for maintaining project momentum. Trello's calendar feature helps +in tracking these deadlines effectively. + +Tips: +
    +
  • Set due dates on cards to establish clear deadlines. Open a card, select "Due Date," and choose the + appropriate date and time.
  • +
  • Enable the Calendar Power-Up on your board to view all your tasks with due dates in a calendar format, offering + a monthly or weekly overview of project deadlines.
  • +
  • Use the calendar to identify potential bottlenecks or conflicts in your schedule, allowing you to adjust task + assignments and deadlines accordingly.
  • +
+ +## Enhancing Collaboration with Trello + +Collaboration is the cornerstone of any successful project, and Trello provides a suite of tools designed to foster +effective team integration and communication. This section delves into how you can use Trello to enhance collaboration +among team members, ensuring everyone is aligned and can contribute efficiently to the project's success. + +### Team Integration +![trello_team](https://res.cloudinary.com/dlyqagele/image/upload/v1710284257/CSC301/cu6jwrgk9ekythzhc3yv.png) + +Adding team members to your Trello board is the first step in fostering a collaborative environment. Here's how you +can do it: + +

1. Adding Members to a Board: On your board, click the "Invite" button or look for the "Add + Members" option. You can invite members by entering their email addresses or Trello usernames. Once invited, members + will have access to the board and can view, edit, or add cards, depending on the permissions you set.

+ +

2. Setting Permissions: It's important to set appropriate permissions for board members. Trello + allows you to specify whether members can add/edit cards, invite other members, or have administrative rights on + the board. Tailor these permissions to fit your team's needs and project requirements.

+ +

3. Promoting Active Collaboration: Encourage team members to actively participate by assigning + them tasks, asking for updates in card comments, and scheduling regular check-ins using the board as a reference + point. This keeps everyone engaged and ensures that tasks are progressing as planned.

+ +### Communication Tools + +Clear communication is essential for collaboration. Trello's features such as comments, attachments, and checklists can +significantly enhance the way your team communicates. + +

1. Comments: Use the comment section on each card to discuss task details, provide updates, or ask + questions. Tagging members in comments (using "@username") ensures they receive notifications, drawing their + attention to important messages.

+ +

2. Attachments: Attach files directly to cards to keep all relevant information in one place. + Whether it's design mockups, documents, or spreadsheets, attachments make it easy for team members to access and + review project materials.

+ +

3. Checklists: Break down tasks into smaller, actionable items using checklists. This not only + clarifies what needs to be done but also allows team members to mark off completed items, providing a clear visual + progress indicator.

+ +

4. Integration with Other Tools: Trello integrates with various third-party tools like Slack, + Google Drive, and GitHub. Leveraging these integrations can streamline workflows and centralize communications, + making it easier for your team to stay connected and informed across different platforms.

+ +## Integrating Trello with Other Tools + +Trello's flexibility extends to its ability to integrate with a wide range of software development tools, enhancing +your project management capabilities. This integration streamlines workflows and brings essential functionalities +directly into your Trello environment. + +### Popular Integrations: +#### Integrating with Development Tools: GitHub + + +

1. Enable the GitHub Power-Up:Navigate to your board's menu, select "Power-Ups," + find the GitHub Power-Up, and click "Add".

+

2. Connect Your GitHub Account: Once added, you'll need to connect your GitHub account by + following the prompts.

+

3. Usage: To attach GitHub links to a card, click on the card, select the "GitHub" option from + the Power-Up section, and then choose the commits, branches, or issues you wish to link.

+ + +### Integrating with Communication Platforms: Slack + +

1. Enable the Slack Power-Up: In your board's menu, find and add the Slack Power-Up.

+

2. Connect Your Slack Workspace: Follow the setup instructions to connect Trello + to your Slack workspace.

+

3. Usage: Configure notifications and select the Slack channel where you want Trello updates to + appear. You can also link cards and boards directly in Slack conversations.

+ + +### Integrating with Productivity Apps: Google Drive, Dropbox, and OneDrive + +

1. Enable the Power-Ups: For each service (Google Drive, Dropbox, OneDrive), add the respective + Power-Up through your board's menu.

+

2. Connect Your Accounts: After adding a Power-Up, connect your account for the service by + following the prompts.

+

3. Usage: To attach a file to a card, open the card, select the appropriate option from the + Power-Up section, and choose the file you want to attach.

+ +### Detailed Guides and Tutorials + +For those new to these integrations, here are links to detailed guides and tutorials that provide step-by-step +instructions: + +* GitHub Integration: [Trello GitHub Power-Up](https://trello.com/power-ups/55a5d916446f517774210004/github) +* Slack Integration: [Trello Slack Power-Up](https://trello.com/power-ups/55a5d917446f51777421000a/slack) +* Google Drive Integration: [Trello Google Drive Power-Up](https://trello.com/power-ups/55a5d916446f517774210006/google-drive) + + + +## Reference + +* https://trello.com/teams?utm_source=trello&utm_medium=inapp&utm_content=header-tips&utm_campaign=playbooks +* https://trello.com/guide +* https://trello.com/power-ups/55a5d916446f517774210004/github +* https://trello.com/power-ups/55a5d917446f51777421000a/slack +* https://trello.com/power-ups/55a5d916446f517774210006/google-drive \ No newline at end of file diff --git a/Topics/Product_Management/UCD_vs_DDD.md b/Topics/Product_Management/UCD_vs_DDD.md new file mode 100644 index 000000000..73ca2f18d --- /dev/null +++ b/Topics/Product_Management/UCD_vs_DDD.md @@ -0,0 +1,111 @@ +# User-Centered Design (UCD) Vs. Design-Driven Development (DDD) +------ + +------ +## Table of Contents +- [Understanding User-Centered Design (UCD)](#UCD) + - [Principles of UCD](#princUCD) + - [UCD in Project Management](#pmUCD) +- [Understanding Design-Driven Development](#DDD) + - [DDD Methodology](#methDDD) + +- [Similarities & Differences](#vs) + +- [Which should you use?](#summary) + +## Understanding User-Centered Design (UCD) + +### Introduction to UCD +User-Centered Design (UCD) is a cornerstone methodology in product development, focusing on understanding and addressing user needs, behaviors, and preferences. By prioritizing empathy, iteration, and thorough usability testing, UCD ensures the creation of intuitive and user-friendly products. For Product Managers, UCD serves as a fundamental principle, underscoring the essential role of user perspectives in guiding successful product outcomes. + + + +### Principles of UCD +The key principles of UCD when being utilized by a Product Manager can be outlined by the following. + +UCD principles focus on: +- Empathizing with users +- Iterative design and development +- Usability testing and feedback incorporation +- Prioritizing user needs and preferences + +Understanding the importance of each UCD principle is vital for Product Managers as they guide product development. Empathizing with users means truly understanding their needs and desires. Iterative design allows for continuous improvement based on user feedback. Usability testing helps identify issues and incorporate user insights for better products. Prioritizing user needs ensures resources are used where they matter most. By following these principles, Product Managers lead their teams towards creating products that truly resonate with users, fostering loyalty and success. + + + +### Role of UCD in Product Management +UCD plays a crucial role in product management by ensuring that products meet user expectations and deliver exceptional user experiences. It helps in: + +- Identifying user needs and pain points: By empathizing with users, product managers can uncover their underlying needs and pain points. Understanding these aspects enables the development of solutions that directly address user challenges, resulting in more meaningful and impactful products. +- Designing intuitive and accessible user interfaces: UCD emphasizes creating interfaces that are intuitive and easy to navigate. By focusing on user-centric design principles, product managers can ensure that the interface is intuitive for users, allowing them to accomplish tasks efficiently and with minimal friction. Additionally, UCD promotes accessibility, ensuring that the product is usable by individuals with diverse abilities. +- Iteratively improving product features based on user feedback: UCD encourages a continuous feedback loop, where product features are refined and enhanced based on user input. Product managers leverage user feedback to identify areas for improvement and prioritize feature updates accordingly. This iterative approach ensures that the product evolves in alignment with user needs and preferences, ultimately leading to greater user satisfaction and engagement. + + +------ + +------ + +## Understanding Design-Driven Development (DDD) + +### Introduction to DDD +Design-Driven Development (DDD) is a methodology that emphasizes the strategic use of design to drive innovation, differentiation, and competitive advantage in product development. It integrates design thinking, creativity, and user experience principles into the development process. + + +### Methodology of DDD +DDD methodology involves: +- Creative ideation and innovation +- Strategic use of design to differentiate products +- Integrating design thinking into product development +- Aligning product features with user expectations and market demands + +Understanding the methodology of DDD is crucial for Product Managers. It provides a structured approach to driving innovation and differentiation in product development. DDD encourages thinking creatively to come up with new ideas and solutions. It emphasizes using design strategically to make products stand out in the market. By integrating design thinking into the development process, DDD ensures that products meet user needs and preferences effectively. Lastly, DDD helps Product Managers align product features with user expectations and market demands, ensuring the success of their products in a competitive landscape. Overall, DDD equips Product Managers with the tools and strategies needed to drive product innovation and success. + +### Effects of DDD on Different Products +DDD has various effects on different products, including: +- Creating visually appealing and engaging user interfaces +- Differentiating products from competitors +- Driving innovation and creativity in product features +- Enhancing overall user experience and satisfaction + + +------ + +------ + +## Key Differences Between UCD and DDD + +### Similarities and Differences +- Both UCD and DDD prioritize user needs, but they differ in their approach to problem-solving and product development. +- UCD focuses on understanding user behaviors and preferences, while DDD emphasizes creative ideation and innovation. +- UCD aims for usability and accessibility, whereas DDD aims for innovation and differentiation. + +| UCD | DDD | +|-----------------|---------------| +| Empathizing with users to understand their needs, behaviors, and preferences throughout the product development process. | Creative ideation and innovation to drive differentiation and innovation.| +| Iterative design and development to continuously improve product features based on user feedback. | Strategic use of design to differentiate products and make them stand out. | +| Incorporating usability testing and feedback to identify and address usability issues for enhanced user satisfaction. | Integrating design thinking into product development to align with user needs. | +| Prioritizing user needs and preferences to ensure products meet user expectations and deliver exceptional experiences. | Aligning product features with user expectations and market demands for success. | + + +### Decision-Making for Product Managers +Product managers must consider various factors when choosing between UCD and DDD, including: +- Nature of the product and target audience +- Market demands and competitive landscape +- Project timelines and resource constraints + + + +## What should you use? +Understanding when to lean on each approach is key for Product Managers. When diving into uncharted territory or addressing new user needs, UCD shines brightest. Its focus on empathy and iteration ensures that we're in tune with users every step of the way. On the other hand, when we're looking to break new ground or create something truly innovative, DDD steps up to the plate. Its emphasis on creativity and strategic design helps us stand out in a crowded market. + +However, it's not always a black-and-white decision. Sometimes, a mix of both is the winning formula, or even neither (using completely different methodologies). For instance, when revamping an existing product, starting with UCD to understand user pain points can pave the way for innovative features guided by DDD. Similarly, in fast-paced environments where quick iterations are essential, starting with DDD's creative spark can fuel rapid innovation, followed by fine-tuning based on UCD principles. + +Ultimately, the choice between UCD and DDD, or a blend of both—depends on the specific context, including the project goals, user needs, and market dynamics. By carefully considering these factors, Product Managers can determine the best approach to drive success for their products. + + +## Resources +- More on UCD Basics - [Website Link](https://www.usability.gov/what-and-why/user-centered-design.html) +- More on DDD Basics - [Website Link](https://www.uxpin.com/studio/blog/design-driven-development/) +- DDD for Product Managers - [Website Link](https://www.linkedin.com/pulse/design-driven-leadership-product-management-ronke-majekodunmi-mba/) + + diff --git a/Topics/Software_Engineering.md b/Topics/Software_Engineering.md index b2cb5ef8d..b448221c0 100644 --- a/Topics/Software_Engineering.md +++ b/Topics/Software_Engineering.md @@ -23,3 +23,5 @@ Potential topics-- Guidelines for effectively handling bugs through a systematic life cycle and technical debt through proactive identification, documentation, and strategic repayment practices, emphasizing the importance of maintaining a resilient and sustainable software development ecosystem. #### [Ethics In Software Engineering](./Software_Engineering/Ethics_In_Software_Engineering.md) + +#### [Software Licenses](./Software_Engineering/Software_Licenses.md) diff --git a/Topics/Software_Engineering/OpenAI_On_Python.md b/Topics/Software_Engineering/OpenAI_On_Python.md new file mode 100644 index 000000000..6571592a8 --- /dev/null +++ b/Topics/Software_Engineering/OpenAI_On_Python.md @@ -0,0 +1,104 @@ +# Setting up OpenAI API in Python Project + +## Installing Python +To use the OpenAI library you first need to install Python. To test if you have Python installed, navigate to your Terminal or Command line: + +* MacOS: Open your Terminal. This can be found in the Applications folder or search for it using Spotlight. + +* Windows: Open your Command Prompt by searching "cmd" in the start menu. + +Now, in your command line enter: + +```bash +python +``` + +or + +```bash +python3 +``` + +depending on the version of Python installed on your device. + +If you enter into the Python interpreter, then Python is installed on your computer already and you can proceed. If you get an error message that says something like "Error: command python not found", you need to install Python. + +To download Python, go to the official Python website, where the latest version can be downloaded: https://www.python.org/downloads/. To use the OpenAI library you need to have at least Python 3.7.1 or newer. If this is your first time installing Python, follow the instructions in this guide: https://wiki.python.org/moin/BeginnersGuide/Download. + + + +# Using the OpenAI API in Python + +We will now go through the application of OpenAI in python. + +## Installation + +Firstly, you need to start by installing the OpenAI Python client library. To do so open your terminal and run the following command: + +```bash +pip install openai +``` + +## Authentication + +To use the OpenAI API, you must authenticate your requests with an API key: + +1. **Set up an environment variable** for your API key to keep it secure. Change 'your_api_key_here' with your personal key. + +```bash +export OPENAI_API_KEY='your_api_key_here' +``` + +2. **Load the API key** in your Python script from the environment variable: + +```python +import os +import openai + +openai.api_key = os.getenv("OPENAI_API_KEY") +``` + +This will import the required library with the correct key. + +## Making Your First API Call + +Now that you're set up, we can make an API call to generate some text. Here's a simple example: + +```python +response = openai.Completion.create( + engine="text-davinci-003", + prompt="In a quiet town,", + max_tokens=50 +) + +print(response.choices[0].text.strip()) +``` + +This example uses the `text-davinci-003` engine to generate text based on the prompt provided. + +## Advanced Usage + +OpenAI API supports a variety of advanced features and applications which can all be explored individually: + +- **Text Analysis:** Extract insights and analyze text data. +- **Language Translation:** Translate text between languages with high accuracy. +- **Summarization:** Condense long documents into short summaries. + +Each of these tasks can be accomplished by adjusting the parameters in your API requests according to the OpenAI documentations. + +## Best Practices + +- **Keep your API key secure.** Do not hard-code it into your scripts, this insures safety of your key. +- **Monitor your usage** to stay within your rate limits and budget. +- **Experiment with different engines** and parameters to achieve the best results for your specific application. + +## Conclusion + +The OpenAI API offers a powerful range of tools for developers looking to integrate advanced AI learning capabilities into their Python applications. By following the steps outlined in this guide, you can begin to explore the vast possibilities offered by AI. + +For more detailed information and advanced features, visit the [OpenAI API documentation](https://platform.openai.com/docs/). + +## References +OpenAI. (n.d.). Quickstart: Your first API call. from https://platform.openai.com/docs/quickstart?context=python +- OpenAI API Documentation: [https://platform.openai.com/docs/](https://platform.openai.com/docs/) +- Python Documentation: [https://docs.python.org/3/](https://docs.python.org/3/) diff --git a/Topics/Software_Engineering/Software_Licenses.md b/Topics/Software_Engineering/Software_Licenses.md new file mode 100644 index 000000000..426bcefd5 --- /dev/null +++ b/Topics/Software_Engineering/Software_Licenses.md @@ -0,0 +1,155 @@ +# Software Licenses + +## Table of Contents +1. [Introduction](#introduction) +2. [Why Are Software Licenses Important?](#why-are-software-licenses-important) + - [Importance of Licenses for Developers](#importance-of-licenses-for-developers) + - [Importance of Licenses for Users](#importance-of-licenses-for-users) +3. [Types of Software Licenses](#types-of-software-licenses) + - [Public Domain Licenses](#public-domain-licenses) + - [Permissive Licenses](#permissive-licenses) + - [Copyleft Licenses](#copyleft-licenses) + - [General Public License (GPL)](#general-public-license-gpl) + - [GNU Lesser General Public Licenses](#gnu-lesser-general-public-licenses) + - [Proprietary Licenses](#proprietary-licenses) +4. [How to Choose the Right License?](#how-to-choose-the-right-license) +5. [Cases of License Breach](#cases-of-license-breach) +6. [Conclusion](#conclusion) +7. [Sources and References](#sources-and-references) + + +## Introduction + +As software developers, it is important to know about the various licensing options that exist. A software license is a legal agreement that defines the terms under which software can be used, modified, and distributed. + + +## Why Are Software Licenses Important? + +Software licenses play a pivotal role in safeguarding the interests of all parties involved, from developers to end-users, ensuring lawful utilization of software. Understanding their importance is crucial for maintaining legal compliance. + +### Importance of Licenses for Developers + +Software licenses protect developers in various ways: + +- They protect intellectual property rights by ensuring that developers have control over the software and the code they created. This prevents unauthorized use and distribution. + +- They provide legal protection by clearly delimiting usage guidelines and enforcing legal boundaries. This legal framework allows developers to take legal action in case of infringement or misuse. + +- They offer revenue generation as they allow developers to monetize their work through the selling of licenses. + +### Importance of Licenses for Users + +Software licenses also protect the users. + +- They set permissions and restrictions for the user. In other words, these licenses define what the user can and cannot do with the software / code. + +- They protect users from potential infringment claims by providing legal boundaries. + +- They limit the users' legal liability. + + +## Types of Software Licenses + +There exists multiple types of software licenses. These vary generally in terms of restrictions and permissions given to the users. Licenses typically fall into two broader categories; free and open-source licenses and proprietary licenses which are more restrictive. + +### Public Domain Licenses + +A public domain license is the most open type of license that exists. As its name suggests, software that belongs to the public domain is available to all. This license places no restrictions on use and distribution. Software under this license is most of the time open-source, meaning that users or other developers can freely modify its code. + +### Permissive Licenses + +Permissive licenses are one of the most commonly-used software licenses. They are open-source but still have minimal restrictions regarding distribution and modification. These licenses allow users substantial freedom to use, modify, and redistribute the software. These novel changes and updates do not have to be disclosed to others. In other words, developers have the right to take the software under the permissive license, modify it, add their changes, and keep the new version to themselves or share it with others. Permissive licenses allow a collaborative environment while still requiring some restrictions to be met. For instance, permissive licenses require users to include the copyright notice as well as the license text. + +Some of the popular permissive licenses are the MIT License, the Apache License, and the Berkeley Source Distribution (BSD) License. Some well-known open source projects that use these licenses are: + +- MIT License: Python, Node.js, React, and JQuery +- Apache License: Kubernetes, Kotlin, and TypeScript +- BSD License: Flask, Flatter, FreeBSD (a Unix-like operating system) + + +Here is the MIT License: + +Copyright (YEAR) (COPYRIGHT HOLDER) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +### Copyleft Licenses + +Copyleft licenses are also known as reciprocal or restrictive licenses. A copyleft licensed code can be modified, redistributed, or incorporated in an existing proprietary project. However, these licenses require that the source code to all new works or adaptations are also distributed under the same license as the original project. Due to this requirement, these types of licenses are not commercial-friendly. Companies do not want to share and expose their source code to other users and specifically competitors, therefore they refrain from using software with copyleft licenses. + +#### General Public License (GPL) + +The most frequently used copyleft license in the industry is the General Public License (GPL) family of licenses. The GPL states that any software that uses code licensed under the GPL must also be licensed under the GPL. For this reason, the GPL is considered as a ‘strong copyleft’ license. + +Here is an image that demonstrates the specific condition of GPL: + +![GPL](https://static-assets.codecademy.com/Courses/open-source/large-software-project.svg) + +#### GNU Lesser General Public Licenses + +The GNU Lesser General Public License (LGPL) is a software license that is considered 'weak copyleft', meaning it imposes fewer restrictions on derivative works compared to the standard General Public License (GPL). It allows developers to use LGPL-licensed libraries in their own code without necessarily having to release the source code of their own components. This is the notion of dynamic linking. For example, developers can dynamically link LGPL-licensed libraries with proprietary software without requiring the latter to be open-source. However, if modifications are made to the LGPL-licensed libraries themselves, those modifications must be released under the LGPL. This flexibility enables developers to incorporate LGPL-licensed code into both open-source and proprietary projects. While the LGPL is commonly used for software libraries and frameworks, it can also be applied to other types of software. Overall, this type of license creates a balance between promoting openness and allowing for integration with proprietary software. + +### Proprietary Licenses + +We have mentioned multiple times these types of licenses. To give a proper definition, proprietary licenses, also known as commercial licenses, are the most restrictive types of licenses. It is the opposite of free and open source licenses. Software that falls under these licenses cannot be modified or distributed to the public community. The source code is considered a trade secret. Proprietary licenses provide the most legal protection to owners against unauthorised use of software. They fully protect the owners' intellectual property rights. To use a software that falls under this category of licenses, users have to sign a End-User License Agreement (EULA). For instance, Microsoft Windows is a software with proprietary license. The latter restricts users from actions like from reverse engineering, and distributing the software to multiple users. if you do not accept the EULA, then Microsoft prevents you from using its products. + + + +Here is a picture summarizing the various available types of software licenses: + +![Licenses](https://cdn.ttgtmedia.com/rms/onlineimages/5_types_of_software_licenses-f.png) + +## How to Choose the Right License? + +With so many possible options, it can be daunting to choose the license that is appropriate to your software, project, and team. + +Firstly, you should choose between the two big categories; whether you want your license to belong to the free and open source licenses or to the proprietary licenses. If you are not planning on commercializing your application, then it would be a better idea to opt for an open source license. + +Among the open source licenses, if you are comfortable with someone else taking your code, changing it and making it proprietary (close), then you should go for the popular option of permissive licenses. On the other hand, if you do not want this, then using a copyleft license might be the better choice. + +For more information, check this [website](https://choosealicense.com/) created by GitHub that further explains options available to you. + + +## Cases of License Breach + +As mentioned above, there exist many types of software licenses, especially open-source licenses. It is crucial to recognize that legal obligations persist despite the free and open nature of the software. Unfortunately, there have been instances where companies have disregarded these obligations, leading to legal disputes. Violating a software license, a binding legal document, can result in significant legal ramifications, ranging from public controversy to litigation. Here are two such notables situations: + + +### [Free Software Foundation, Inc. v. Cisco Systems, Inc. (2008)](https://www.fsf.org/news/2008-12-cisco-suit) + +In 2008, the Free Software Foundation filed a complaint against Cisco Systems claiming that various Cisco products under the Linksys brand had violated the licenses of many programs on which the FSF held a copyright. Most of the programs were licensed under the GNU General Public License (GPL) and so they allowed users like Cisco to use, modify, and distribute the software in condition that the redistributors shared their source code as well. The FSF accused Cisco of distributing licensed software without sharing source code with its customers. + +The FSF and Cisco came to a settlement. You can read more about the case [here.](https://www.fsf.org/news/2008-12-cisco-suit) + + +### [Software Freedom Conservancy and Tesla](https://www.theregister.com/2018/05/21/tesla_inches_toward_gpl_compliance/) + +In 2018, after multiple years of pressure from the Software Freedom Conservancy, Tesla released part of its open-source code as required under GNU General Public License (GPL). The company used some GPL-licensed software in the Tesla Model S but had failed to comply with the requirements of the copyleft license. + +To learn more about the situation, you can read it [here.](https://www.theregister.com/2018/05/21/tesla_inches_toward_gpl_compliance/) + + +## Conclusion + +In summary, even though the world of software licenses appears to be complicated, as software developers, it is important that we are aware of these existing licenses. By doing so, we ensure not only compliance with legal obligations but also the safeguarding of our own rights. Understanding the nuances of different licenses allows us to work in a collaborative and responsible coding environment. + +## Sources and References + +- [TechTarget](https://www.techtarget.com/searchcio/definition/software-license) +- [G2 Track](https://track.g2.com/resources/software-license) +- [Indeed](https://www.indeed.com/career-advice/career-development/types-of-software-license) +- [GitHub - Choose a License](https://choosealicense.com/) +- [Synopsys](https://www.synopsys.com/blogs/software-security/5-types-of-software-licenses-you-need-to-understand.html) +- [FOSSA](https://fossa.com/blog/all-about-permissive-licenses/) +- [codecademy](https://www.codecademy.com/article/choosing-an-open-source-license) +- [MIT License](https://opensource.org/license/mit) +- [MIT License Usage](https://tlo.mit.edu/understand-ip/exploring-mit-open-source-license-comprehensive-guide) +- [Apache License Usage](https://en.wikipedia.org/w/index.php?title=Category:Software_using_the_Apache_license&pageuntil=LLDB+%28debugger%29#mw-pages) +- [BSD License Usage](https://en.wikipedia.org/wiki/Category:Software_using_the_BSD_license) +- [Free Software Foundation, Inc. v. Cisco Systems, Inc. (2008)](https://www.fsf.org/news/2008-12-cisco-suit) +- [Software Freedom Conservancy and Tesla feud](https://www.theregister.com/2018/05/21/tesla_inches_toward_gpl_compliance/) diff --git a/Topics/Software_Engineering/logging_to_mysql.md b/Topics/Software_Engineering/logging_to_mysql.md new file mode 100644 index 000000000..e497a6b0d --- /dev/null +++ b/Topics/Software_Engineering/logging_to_mysql.md @@ -0,0 +1,210 @@ +# Implement Logging Process to MySQL for Functions + +## Introduction + +In this guide, we'll explore how to implement a logging process for software functions into a MySQL database. Logging is crucial for monitoring, debugging, and security purposes in software engineering. We'll cover the basics, the setup required, and provide a step-by-step example. + +## Prerequisites + +- Basic knowledge of programming (Python used in examples) +- Access to a MySQL database +- Familiarity with SQL queries + +## Step 1: Setting Up Your Environment + +Ensure you have Python and MySQL installed on your system. You'll also need the `mysql-connector-python` package for Python. + +```bash +pip install mysql-connector-python +``` + +## Step 2: Create a Logging Table in MySQL + +The `logs` table is essential for storing application log messages, which are crucial for debugging, monitoring application health, and understanding user actions. + +Execute the following SQL query in your MySQL database to create a table for logging: + +```sql +CREATE TABLE logs ( + id INT AUTO_INCREMENT PRIMARY KEY, + timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + level VARCHAR(10), + message TEXT +); +``` + +logs_table + +- **id** (INT): An auto-incremented integer serving as the primary key for each log entry. +- **timestamp** (TIMESTAMP): The date and time when the log entry was created, automatically set to the current timestamp. +- **level** (VARCHAR): A string indicating the severity of the log, such as INFO, WARNING, or ERROR. +- **message** (TEXT): The actual log message text, detailing the event or error reported. + +## Step 3: Implementing Logging in Python + +### Define the Logger + +Create a Python file, e.g., logger.py, and define a logger and a handler to insert logs into MySQL. + +```python +import logging +import mysql.connector +from mysql.connector import Error + +class MySQLHandler(logging.Handler): + def __init__(self, config): + super().__init__() + self.connection = mysql.connector.connect(**config) + self.cursor = self.connection.cursor() + + def emit(self, record): + try: + log_entry = self.format(record) + self.cursor.execute("INSERT INTO logs (level, message) VALUES (%s, %s)", (record.levelname, log_entry)) + self.connection.commit() + except Error as e: + print("Error logging to MySQL", e) +``` + +### Configure the Logger + +Configure the logger with the MySQL handler. + +```python +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) + +config = { + 'host': 'your_database_host', + 'database': 'your_database_name', + 'user': 'your_username', + 'password': 'your_password' +} + +mysql_handler = MySQLHandler(config=config) +logger.addHandler(mysql_handler) + +formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') +mysql_handler.setFormatter(formatter) +``` + +## Usage Example with the `users` Table + +In this example, we have a `users` table in our MySQL database designed to store user information such as IDs, names, and email addresses. +The table structure is as follows: + +- **id** (INT): A unique identifier for each user, auto-incremented. +- **name** (VARCHAR): The name of the user. +- **email** (VARCHAR): The user's email address, which is unique across all users. + +### Creating the `users` Table + +First, ensure that your MySQL database contains the `users` table. Use the following SQL query to create it if necessary: + +```sql +CREATE TABLE users ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(100) NOT NULL, + email VARCHAR(100) NOT NULL UNIQUE +); +``` + +users_table + +### Inserting Sample Data + +Insert some sample data into the `users` table to work with: + +```sql +INSERT INTO users (name, email) VALUES ('Alice Smith', 'alice@example.com'); +INSERT INTO users (name, email) VALUES ('Bob Jones', 'bob@example.com'); +``` + +users_sample_data + +### The `get_user_info` Function + +The `get_user_info` function is designed to retrieve a user's information from the database given their user ID. +It uses logging to indicate the function's outcome, such as successful information retrieval, attempts to retrieve non-existent users, and database connection errors. + +### Python Implementation + +Below is the updated Python script that includes the `get_user_info` function: + +```python +import logging +import mysql.connector +from mysql.connector import Error + +# Configure the logger and MySQLHandler as previously described + +def get_user_info(user_id): + """Retrieves user information by user_id from the database.""" + try: + conn = mysql.connector.connect(**config) + cursor = conn.cursor() + cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) + user_info = cursor.fetchone() + conn.close() + + if user_info: + logger.info(f"Retrieved information for user ID {user_id}: {user_info}") + return user_info + else: + logger.warning(f"User with ID {user_id} not found.") + return None + except Error as e: + logger.error(f"Error connecting to MySQL database: {e}") + return None + +# Example usage +user_id = 1 # Example user ID +user_info = get_user_info(user_id) +``` + +### Explanation + +This script attempts to retrieve information for a user by their ID. It logs: + +- An **info** level message if the information is successfully retrieved, + +https://github.com/learning-software-engineering/learning-software-engineering.github.io/assets/90298039/bd2777b4-93d8-490a-88fe-eacf04d570a1 + +- A **warning** if no user matches the provided ID, and + +https://github.com/learning-software-engineering/learning-software-engineering.github.io/assets/90298039/fadc999f-04c5-4488-89a4-60fabdcb1f59 + +- An **error** if there is a problem connecting to the database. + +https://github.com/learning-software-engineering/learning-software-engineering.github.io/assets/90298039/66d5602e-b31b-4558-8098-e2ff8d6cc741 + +This approach demonstrates practical logging usage within an application, providing insights into operational status and issues. + +## Example Use Case for Both Tables + +Consider an application where user actions are logged for security and auditing purposes. In this scenario, +the `logs` table captures the events, and the `users` table provides context about who triggered those events. +For example, if an unauthorized access attempt is made, the `logs` table would record the event's specifics, +while the `users` table could help identify or rule out which user(s) were involved. + +## Conclusion + +Implementing a logging process into MySQL allows developers to effectively monitor and debug their applications. +By following the steps outlined above, you can set up a robust logging system tailored to your project's needs. + +## References + +- [MySQL Connector/Python Developer Guide](https://dev.mysql.com/doc/connector-python/en/) +- [Logging facility for Python — Python 3.12.2 documentation](https://docs.python.org/3/library/logging.html) + +This document is structured to facilitate readability and understanding, featuring code blocks for SQL, bash, and Python +to illustrate the setup and implementation process for logging to MySQL. Remember to adjust the configuration details to match your environment. + + + + + + + + + diff --git a/Topics/Software_Tools.md b/Topics/Software_Tools.md index 39824d897..0646a5a7b 100644 --- a/Topics/Software_Tools.md +++ b/Topics/Software_Tools.md @@ -20,4 +20,9 @@ ## Text Editors ### [Introduction to Vim](./Software_Tools/vim.md) -### [Introduction to Visual Studio Code](./Software_Tools/VSCode.md) \ No newline at end of file +### [Introduction to Nano](./Software_Tools/nano/nano.md) +### [Introduction to Visual Studio Code](./Software_Tools/VSCode.md) +### [Introduction to Sublime](./Software_Tools/Sublime.md) + +## Python Libraries +### [Automate Tasks using PyAutoGui](./Software_Tools/PyAutoGUI/Automation_with_PyAutoGUI.md) diff --git a/Topics/Software_Tools/Automated_Deployment.md b/Topics/Software_Tools/Automated_Deployment.md index e0473eaaa..282defc9a 100644 --- a/Topics/Software_Tools/Automated_Deployment.md +++ b/Topics/Software_Tools/Automated_Deployment.md @@ -86,3 +86,6 @@ ____ - Deployment to Heroku: - https://github.com/marketplace/actions/deploy-to-heroku - https://devcenter.heroku.com/articles/git#for-an-existing-app + + - Deployment to AWS with docker: + - [Docker AWS (ECR ECS) Github Actions CD Pipeline](../Development_Process/Docker_AWS_ECR_ECS_CD.md) \ No newline at end of file diff --git a/Topics/Software_Tools/PromptEngineering.md b/Topics/Software_Tools/PromptEngineering.md new file mode 100644 index 000000000..293418d8c --- /dev/null +++ b/Topics/Software_Tools/PromptEngineering.md @@ -0,0 +1,71 @@ +# Introduction to Prompt Engineering + +# Table of Contents +- [Introduction to Prompt Engineering](#introduction-and-understanding) + - [Understanding Large Language Models (LLMs)](#understanding-large-language-models-llms) + - [How does it work](#how) +- [Application](#application) + - [Code Generation with LLM](#codegeneration) + - [Code Generation with Large Language Models](#code-generation-with-large-language-models) +- [Citations](#citations) + + + +# Introduction and Understanding + +## Understanding Large Language Models (LLMs) + + +### Introduction to LLMs: + +Large Language Models (LLMs) are at the forefront of artificial intelligence, driving innovations in natural language processing and beyond. These powerful models are trained on extensive datasets composed of diverse text from the internet, enabling them to grasp the complexities, subtleties, and varied patterns of human language. As a result, LLMs can generate text that's not only coherent and contextually relevant but also remarkably human-like in its composition. Most Common examples include Chatgpt, Copilot, etc. + + +### How does it work? + +#### Pre-training: +This foundational stage involves training the LLM on a vast corpus of text data. During pre-training, the model learns the general rules of language, including grammar, syntax, and semantics, without any specific task in mind. This broad understanding of language equips the model to tackle a wide range of text-based tasks. + +#### Fine-tuning: +After pre-training, LLMs can undergo fine-tuning on smaller, task-specific datasets. This process tailors the model's responses to perform well on particular tasks or understand the nuances of specialized domains, such as legal documents or medical literature. + +### Generative Capabilities: +LLMs are not just passive observers of language; they are active creators. Given a prompt or a start of a sentence, these models can generate text that follows logically and engagingly. This generative capability makes them invaluable for applications like content creation, where they can produce original articles, stories, and even poetry that mimics human writing styles. + + +### Examples and Demonstrations: +Imagine prompting an LLM with the sentence "The sunset over the ocean was a breathtaking sight," and the model continues with "as the hues of pink and orange painted a masterpiece in the sky, reflecting the day's end with a promise of renewal." This example showcases the model's ability to continue the narrative in a way that's contextually appropriate and stylistically coherent. + +Screenshot 2024-03-17 at 8 49 34 PM + + +# Application + + +## Code Generation with Large Language Models + +### Setting the Stage: +To guide the model, we use a System Message that sets the context: "You are a helpful code assistant that can teach a junior developer how to code. Your language of choice is Python. Don't explain the code, just generate the code block itself." + +### Basic Code Generation: +When tasked with generating basic code, such as creating a Python script to greet a user by name, LLMs analyze the structure and semantics of the prompt to construct a suitable code block. The model draws on patterns and examples it has learned during training to produce syntactically correct and functionally appropriate Python code that matches the task described in the prompt. + +Screenshot 2024-03-17 at 8 57 21 PM + + +### Completing Functions: +For completing partial functions, LLMs rely on their understanding of coding patterns and the specific requirements outlined in the prompt. Given the start of a function, the model predicts the most likely continuation based on its training, which includes analyzing countless code examples. This capability is akin to predicting the next word in a sentence but applied to the syntax and structure of code. + +### Code Explanation: +Explaining code involves the model interpreting the logic and function of a given code block and then describing its purpose and operation in natural language. This process requires the LLM to reverse-engineer the code, applying its understanding of programming concepts and language semantics to provide a clear and accurate explanation. + +### Debugging and Editing: +The potential for LLMs to assist in debugging and editing code lies in their ability to analyze code for syntactical and logical errors, drawing on examples and patterns from their training data. The model can suggest corrections or improvements by identifying inconsistencies or errors in the code and comparing them with known correct implementations. This capability is particularly valuable for identifying common mistakes and proposing optimized solutions. + + +## Citations +- [Prompting Guide](https://www.promptingguide.ai/) +- [McKinsey Explainers: What is Prompt Engineering?](https://www.mckinsey.com/featured-insights/mckinsey-explainers/what-is-prompt-engineering) + + + diff --git a/Topics/Software_Tools/PyAutoGUI/Automation_with_PyAutoGUI.md b/Topics/Software_Tools/PyAutoGUI/Automation_with_PyAutoGUI.md index 926da5064..94daae210 100644 --- a/Topics/Software_Tools/PyAutoGUI/Automation_with_PyAutoGUI.md +++ b/Topics/Software_Tools/PyAutoGUI/Automation_with_PyAutoGUI.md @@ -165,8 +165,119 @@ pyautogui.doubleClick() ``` ![sample_gif](./assets/move_folder.gif) + ## Keyboard Controls -Pending +Once familiar with mouse functions, exploring keyboard interactions becomes the next vital step. PyAutoGui offers various methods for keyboard input, enhancing automation capabilities. + +Some use cases where keyboard functionality in software engineering can be highly beneficial are: +- **Simulating user input:** Using keyboard functions like `write()` and `press()` allows developers to simulate user input, filling out forms with predefined data efficiently. +- **Keyboard Shortcuts for Navigation:** Many software applications rely on keyboard shortcuts for quick navigation and task execution. Implementing keyboard shortcuts using PyAutoGui's `hotkey()` function can enhance user productivity and streamline workflow in software development environments. +- **Integration Testing:** During integration testing, developers often need to simulate complex user interactions, including keyboard inputs. PyAutoGui's keyboard functions enable developers to programmatically trigger key presses, facilitating thorough testing of software systems under various scenarios. +- **Command-Line Interfaces (CLI):** Many software tools and utilities feature command-line interfaces (CLI) for interaction. PyAutoGui's keyboard functions can be utilized to automate CLI interactions, allowing developers to script and execute repetitive tasks with ease. + +We can write something using the `write()` keyword. This will simply type the argument that is passed into it, which is a string. + +```python +>>> pyautogui.write('Engineering!\n') # Prints 'Engineering' +>>> pyautogui.write('Engineering!', interval=0.25) # Similar to the move function, the second argument is + # the interval between pressing each button +``` +As an example, the above function gives the following output: + +Screenshot 2024-03-17 at 10 03 12 PM + +However, one may wonder what may happen if we inturrupt the program mid execution. For instance the following happens when we click the caps lock button while executing the above program with interval after printing the first 6 characters. + +Screenshot 2024-03-17 at 10 06 03 PM + +The keyboard just switched to caps lock after the point it was pressed. + +We may sometimes want to just click on a button on the keyboard, which is not a string, like the enter or the shift button. For this, we can use the `press()` function. + +```python +>>> pyautogui('shift') # Presses the shift button +``` +We can similarly use a range of buttons. For the full list, please see the documentation. + +Sometimes we may want to press more than one button at a time. For this we can use the `keyUp()` and the `keyDown()` function as done in the following: +```python +>>> pyautogui.keyDown('ctrl') # Press the ctrl button down +>>> pyautogui.press('p') # Press the 'p' button and release it +>>> pyautogui.keyUp('ctrl') # Lift the press from the ctrl button +``` + +To press multiple keys sequentially, pass a list of strings to `press()`: + +```python +>>> pyautogui.press(['tab', 'tab', 'tab']) # Presses 'tab' key thrice +>>> pyautogui.press('tab', presses=3) # Sets the number of presses +``` + +The `hold()` Context Manager: For holding a key conveniently within a context block, `hold()` function serves as a useful tool: + +```python +>>> with pyautogui.hold('ctrl'): + pyautogui.press(['tab', 'tab', 'tab']) +``` + +The `hotkey()` Function: To execute hotkeys or keyboard shortcuts efficiently, utilize the `hotkey()` function: + +```python +>>> pyautogui.hotkey('ctrl', 'shift', 'p') # Executes Ctrl + Shift + p +``` +These functionalities empower users with versatile keyboard interactions, facilitating seamless automation tasks. + + ## Message Box Functions -Pending \ No newline at end of file +PyAutoGui leverages PyMsgBox's message box functions, offering a cross-platform, pure Python solution for displaying JavaScript-style message boxes. These functions serve various purposes and provide flexibility in handling user interactions seamlessly. Here's an overview of the four message box functions provided: + +### The alert Function + +Displays a simple message box with customizable text and a single OK button. It returns the text of the button clicked on by the user. + +```python +pyautogui.alert(text='Text', title='Title', button='Button') +``` +Output: + +Screenshot 2024-03-17 at 10 15 58 PM + +The meaning of the arguments can be clearly understood when looking at the output. + +### The confirm Function + +Displays a message box with configurable text and buttons, typically OK and Cancel. Users can choose between the provided options, and it returns the text of the button clicked. + +```python +pyautogui.confirm(text='Text', title='Title', buttons=['OK', 'Cancel']) +``` +Output: + +Screenshot 2024-03-17 at 10 17 55 PM + + +### The prompt Function + +Shows a message box with text input field, along with OK and Cancel buttons. Users can input text, and it returns the entered text or None if Cancel was clicked. + +```python +pyautogui.prompt(text='Text', title='Title', default='Default') +``` +Output: + +Screenshot 2024-03-17 at 10 18 46 PM + +### The password Function + +Similar to the `prompt()` function, it displays a message box with a text input field. However, the typed characters are masked, typically with asterisks (*). It returns the entered text or None if Cancel was clicked. + +```python +pyautogui.password(text='', title='', default='', mask='*') +``` +Output: + +Screenshot 2024-03-17 at 10 19 35 PM + + +These functions empower users to handle various types of user interactions effectively within their Python scripts, enhancing the user experience and interactivity of their applications. diff --git a/Topics/Software_Tools/Sublime.md b/Topics/Software_Tools/Sublime.md new file mode 100644 index 000000000..9b47ac60c --- /dev/null +++ b/Topics/Software_Tools/Sublime.md @@ -0,0 +1,67 @@ +# Introduction to Sublime + +Sublime is a text editor, which was created by Jon Skinner, that is supported on Windows, macOS, and Linux. This text editor has several benefits such as being free of charge, offering fast typing recognition speed, and providing numerous convenient editing features. + +## Installation of Sublime +1. Go to the [Sublime website](https://www.sublimetext.com/3) to install the latest version of the editor. + + +2.
![install 1](https://github.com/learning-software-engineering/learning-software-engineering.github.io/assets/113051612/e7c84d4c-7d33-4afd-97d7-aead390a2994)
+2.1 Windows : Make sure to know if your computer is 64-bit or 32-bit. Click Windows or Windows 64 bit
+2.2 macOS : Make sure your computer is version is 10.7 or higher. Click OS X
+2.3 Linux : You can download it by clicking Linux repos or following these steps below if you are using Ubuntu.
+ ``` + wget -qO - https://download.sublimetext.com/sublimehq-pub.gpg | sudo apt-key add - + ``` + ``` + echo "deb https://download.sublimetext.com/ apt/dev/" | sudo tee /etc/apt/sources.list.d/sublime-text.list + + ``` + ``` + sudo apt update + sudo apt install sublime-text + ``` + +3. After downloading Sublime, you can lauch it by clicking the icon. Then, you will see this.
+![install 2](https://github.com/learning-software-engineering/learning-software-engineering.github.io/assets/113051612/30c78bfc-73f4-474a-a310-d0971ff7fefb) + + + + +## Sublime Features + + +* Command Palette + * This is an interactive list designed to execute different kinds of commands. + * Ctrl+Shift+P on Windows or Cmd+Shift+P on macOS + * For example, you can install packages like this
+ ![feature 1](https://github.com/learning-software-engineering/learning-software-engineering.github.io/assets/113051612/8021cad1-b930-4459-b768-164cd3da0eb3) + +* Distraction Free Mode + * This displays your files in full screen view, centering the text on your monitor while eliminating all other visual elements. + * Click View then Enter Distraction Free Mode + * It looks like this
![feature 2](https://github.com/learning-software-engineering/learning-software-engineering.github.io/assets/113051612/54006218-7ae8-4686-9386-debc16b7e784) + + +* Goto Anything + * This allows you to navigate files and line very quickly. + * Ctrl+P on Windows or Cmd+P on macOS + * You can jump to different lines like this
+ ![feature33](https://github.com/learning-software-engineering/learning-software-engineering.github.io/assets/113051612/fdb923a8-274a-4bd6-8d44-5bdc1b563bac) + + + +## Conclusion + +Sublime stands out among text editors due to its user friendly design, significant speed, and efficiency, being a flexible text editor for Windows, macOS, and Linux that increases productivity with features such as the Command Palette, Distraction Free Mode, and Goto Anything. These features make it an ideal tool for developers and writers who value a smooth workflow. Sublime provides a smooth coding environment that prioritizes user satisfaction and efficiency. + + + +## Resources + +[Sublime Guide](https://docs.sublimetext.io/guide/)
+[About Sublime](https://www.sublimetext.com/about#:~:text=Sublime%20Text%20was%20created%20by,of%20Sublime%20HQ%20Pty%20Ltd.)
+[Install Sublime on Linux](https://www.makeuseof.com/how-to-install-sublime-text-on-linux/)
+[Command Palette 1](https://www.tutorialspoint.com/sublime_text/sublime_text_command_palette.htm)
+[Command Palette 2](https://docs.sublimetext.io/guide/extensibility/command_palette.html#:~:text=Overview%20%E2%80%8B,sublime%2Dcommands%20files.)
+[Distraction Free Mode](https://www.sublimetext.com/docs/distraction_free.html) diff --git a/Topics/Software_Tools/cat.md b/Topics/Software_Tools/cat.md new file mode 100644 index 000000000..c8212ae32 --- /dev/null +++ b/Topics/Software_Tools/cat.md @@ -0,0 +1,109 @@ +# The 'cat' Command Guide + +## Introduction to the `cat` Command + +The `cat` (concatenate) command is a staple in Unix and Unix-like operating systems for displaying, concatenating, and writing file contents to the standard output. + +## Syntax + +```bash +cat [OPTION]... [FILE]... +``` + +- `[OPTION]`...: Modify the behavior of `cat`. +- `[FILE]`...: Files to be processed. Reads from stdin if no file or `-` is specified. + +## Common Options + +- `-n`, `--number`: Number all output lines. +- `-b`, `--number-nonblank`: Number non-empty output lines only. +- `-s`, `--squeeze-blank`: Squeeze multiple adjacent blank lines. +- `-E`, `--show-ends`: Display `$` at the end of each line. +- `-T`, `--show-tabs`: Display TAB characters as `^I`. + +## Displaying File Contents + +To display the contents of a file: + +```bash +cat file.txt +``` + +Screenshot 2024-03-11 at 11 28 56 PM + +## Concatenating Files + +To concatenate multiple files into one: + +```bash +cat file1.txt file2.txt > combined.txt +``` + +Screenshot 2024-03-11 at 11 49 17 PM + +## Creating Files + +To create a new file: + +```bash +cat > newfile.txt +``` + +## Appending to Files + +To append text to an existing file: + +```bash +cat >> existingfile.txt +``` + +Screenshot 2024-03-12 at 12 00 29 AM + +Screenshot 2024-03-12 at 12 01 00 AM + +## Viewing Non-Printing Characters + +To view end-of-line or tabs: + +```bash +cat -E file.txt +cat -T file.txt +``` + +## Reading Standard Input + +You can use cat without specifying a file to read from the standard input. This is useful for quickly creating file content from terminal input: + +```bash +cat > example.txt +Type your content here... +Press CTRL+D (EOF) to save and exit. +``` + +## Viewing Multiple Files + +cat can also be used to view the contents of multiple files sequentially on the terminal. This is a quick way to compare or merge files manually: + +```bash +cat file1.txt file2.txt file3.txt +``` + +Screenshot 2024-03-12 at 12 03 41 AM + +## Sort and Remove Duplicate Lines + +If you have a file with list items or entries that you want to sort and remove duplicates from, you can use cat in combination with other commands like `sort` and `uniq`. + +```bash +cat list.txt | sort | uniq > sorted_list.txt +``` + +Using `cat list.txt | sort | uniq > sorted_list.txt` streamlines the process of organizing data by automatically sorting the contents of `list.txt`, removing any duplicate entries, and saving the cleaned, ordered list to `sorted_list.txt`. This command sequence accelerates workflows by performing data cleanup and organization in a single step, eliminating the need for manual sorting and deduplication, thus saving time and reducing potential for error in data handling. + +## Conclusion + +The `cat` command is an essential tool for text processing in Unix/Linux environments, offering a wide range of functionalities from file display to concatenation and debugging. + +## Reference + +https://www.geeksforgeeks.org/cat-command-in-linux-with-examples/ diff --git a/Topics/Software_Tools/nano/nano.md b/Topics/Software_Tools/nano/nano.md new file mode 100644 index 000000000..85d72305f --- /dev/null +++ b/Topics/Software_Tools/nano/nano.md @@ -0,0 +1,38 @@ +# Introduction to Nano + +## **What is Nano?** +Nano is a text editor for Unix-like computing systems or operating environments using a command line interface. It is simple and user-friendly, making it great for people who are beginners to using command line interfaces. + +## **Installing Nano** +Nano text editor is pre-installed on macOS and most Linux distros. To check if it is installed on your system, type: + +```nano --version``` + +If you don’t have nano installed on your system, you can install it using your distribution’s package manager. + +#### Install Nano on Ubuntu and Debian +```sudo apt install nano``` + +#### Install Nano on CentOS and Fedora +```sudo yum install nano``` + +## Opening and Creating Files +To open an existing file or to create a new file, type nano followed by the file name: +```nano filename``` + +This will open a new editor window, and you can start editing the file. It should look something like this. +Screenshot 2024-03-17 at 8 02 28 PM + + +At the bottom of the window, there is a list of the most basic command shortcuts to use with the nano editor. All commands are prefixed with either ^ or M. ^ represents the Ctrl key. For example, the ^J commands mean to press the Ctrl and J keys at the same time. M represents the Alt key. To get a list of all commands, type Ctrl+g. + +To open a file, you must have read permissions to the file. + +If you want to open a file with the cursor on a specific line and character, use the following syntax: + +```nano +line_number,character_number filename``` + +If you do not include the character_number the cursor will be positioned on the first character. + +Additional Resources +https://www.nano-editor.org/dist/v2.2/nano.html diff --git a/Topics/System_Design.md b/Topics/System_Design.md index 10ff5a8b8..a14e384f8 100644 --- a/Topics/System_Design.md +++ b/Topics/System_Design.md @@ -10,7 +10,11 @@ ### [Introduction to Microservices Architecture](./System_Design/Intro_To_Microservices/Intro_To_Microservices.md) +### [Architecting a System to Handle 100k+ Requests](./System_Design/Handling_100K_Requests.md) + ### Design Patterns #### 1. [Behavioural Design Patterns](./System_Design/behavioral_design_patterns.md) +#### 2. [Creational Design Patterns](./System_Design/DesignPatterns/Creational_Design_Patterns.md) + diff --git a/Topics/System_Design/DesignPatterns/Creational_Design_Patterns.md b/Topics/System_Design/DesignPatterns/Creational_Design_Patterns.md new file mode 100644 index 000000000..1f40559e7 --- /dev/null +++ b/Topics/System_Design/DesignPatterns/Creational_Design_Patterns.md @@ -0,0 +1,379 @@ +# Creational Design Patterns + +## Table of Contents + +1. [Introduction](#intro) +2. [Types of Creational Design Patterns](#types) +3. [Simple Factory](#simple) +4. [Factory Method](#factmethod) +5. [Abstract Factory](#abstfactory) +6. [Singleton](#singleton) +7. [Builder](#builder) +8. [Further Reading](#further-reading) + +## Introduction + +As the name suggests, creational design patterns are standardized ways to deal with the creation and maintenance of objects in object-oriented programming. They are used to instantiate different classes of objects and their subclasses in the best way to achieve their intended purposes. + +There are 5 major types of creational patterns that are commonly used in software development. + +## Types of Creational Design Patterns + +### Simple Factory + +#### Usage + +A complex object needs to be created multiple times. + +The simple factory works by delegating the instantiation of an object class to a dedicated method. This allows the object to be hidden from the user endpoint, by preventing the need to directly instantiate (and thus access) the object. + +#### Structure + +A factory class is introduced in addition to the object class. The factory has a create method, whose purpose is to generate and return an instance of the object class. + +

+UML of Simple Factory design pattern +

+ +#### Benefits + +- Hides the object class creation behind a layer of abstraction. Can be used to simplify the object creation provided a few parts need to be built before instantiation, or adjustments need to be made after instantiation. + +#### Example + +Suppose you have a Burger class that allows you to make a burger using an initializer that accepts ingredients as input. + +``` +class Burger: + """ Create a burger""" + + def __init__(patty, bun, sauce, vegetables): + ... +``` + +However, you don't want the user to have to manually select ingredients, and you don't want them to know any of your secret burger recipes. To hide the recipes from the user's view and still allow them to have your trademark burgers, you can protect introduce a simple factory, which the user uses instead to create burgers in a simpler, and more secure, way. + +``` +class BurgerFactory: + """Order trademark burgers. """ + def static createBurger(burgerKey): + + if key == ...: + burger = Burger(...) + elif ...: + ... + ... + + return burger +``` + +### Factory Method + +#### Usage + +A singular class of objects needs to be produced multiple times, and in a dynamic way via subclasses of the object. + +The factory method design pattern introduces a class containing a singular create method that creates one class of objects (products). Extensions of the factory class are created as needed to override the default implementation (or abstraction) of the create method to produce different subclasses of the product. + +#### Structure + +A factory class containing one (abstract) create method that produces a product class of the required type. Implementations of the factory override the create method as required to output subclasses of the product. + +

+UML of Factory Method design pattern +

+ +#### Benefits + +- Allows variations of the product class to be easily created without having to define new calling behaviour in programs utilising the product and factory classes. + +#### Example + +Utilizing the burger analogy from Simple Factory, now consider a somewhat different, independent scenario: + +You are Louis Lassen, the man who invented the hamburger. You are very excited about your new invention, and you want to allow other people to also make hamburgers. You recognize that not everyone would want to use the same recipes you do. You don't want other chef to have to independently re-invent the hamburger, and you don't want to have to go back to your simple BurgerFactory to add a new else-if statement every single time someone comes up with a new burger recipe. You could resolve your dilemma by introducing a **BurgerFactoryMethod** - you tell them the general (abstract) method of creating a burger, and you let the chefs (your users) come up with their own burger recipes (methods) to make burgers without relying on you or creating conflict between different recipes. + +``` + +class AbstractBurger: + """ Create a burger""" + ... + +abstract class BurgerFactoryMethod: + """Typical procedure of creating a burger.""" + def abstract createBurger() -> AbstractBurger: + +``` + +Thanks to your efforts, both Mr. Ronald and Mr. King are inspired, and can easily create their own burger recipes as implementations of your abstract BurgerFactoryMethod. + +``` +class RonaldBurgerFactory extends BurgerFactoryMethod: + """Order Ronald's trademark burgers. """ + def createBurger() -> AbstractBurger: + ... + return ronburger + +class BigRon extends AbstractBurger: + """Ronald's trademark burger. """ + def __init__(patty, bun, sauce, vegetables): + ... +``` + +``` +class KingBurgerFactory extends BurgerFactoryMethod: + """Order King's trademark burgers. """ + def createBurger() -> AbstractBurger: + ... + return kingburger + +class KingBurger extends AbstractBurger: + """King's trademark burger. """ + def __init__(patty, bun, sauce, vegetables): + ... +``` + +(Once again, note carefully that each factory method class is only producing 1 object type using just one create method.) + +### Abstract Factory + +#### Usage + +when there are multiple related object classes that need to be separately instantiated using different creation processes. + +An abstract factory is a factory of factories: it is a design pattern that takes advantage of abstraction and inheritance to define a common public API for factories of a set of related subclasses of some parent class. This allows the user of the factory to define functions and creation behaviour for an extendible set of classes, each of which can have a different object construction process under the hood, without having to define if-else behaviour for every single subclass factory in dependent methods. As with all abstract classes, this allows extension and modularity as a result of not relying on the internal workings of specific factory classes relating to certain subclasses. + +Note that this differs from the factory method in that a singular abstract class is introduced to deal with the creation of _multiple_ related products, rather than a separate factory method being introduced for each product. + +#### Structure + +An abstract factory class contains multiple factory methods, each producing a different, but related, abstract class of objects. Implementations of the abstract factory implement these methods to produce (different) subclasses of the abstract object classes. + +

+UML of Abstract Factory design pattern +

+ +#### Benefits + +- By using an abstract factory, the user is able to avoid having to implement separate code for each different object factory necessary for their product. +- As with the factory method, the object creation system becomes highly extensible: if a new extension of an object is declared, the user can simply create another implementation of the abstract factory to produce it, without having to change the behavior of any other classes/functions that utilise the factory. + +#### Example + +Assume for a moment that you are Billy Ingram (founder of White Castle, the first restaurant to sell both hamburgers and fries). You've come up with a great fast food concept of selling burgers, fries and a soft drink. However, you know that you are not going to be the only one to have this concept. You can model this situation ideally using the Abstract Factory design pattern. + +``` +class AbstractBurger: + """ Create a burger""" + ... + +class AbstractFries: + """ Create fries.""" + ... + +class AbstractDrink: + """ Create a drink""" + ... + +abstract class AbstractFastFoodFactory: + """The generic menu of a burger restaurant.""" + def abstract createBurger() -> AbstractBurger: + + def abstract createFries() -> AbstractFries: + + def abstract createDrink() -> AbstractDrink: + +``` + +``` +class WhiteCastle extends AbstractFastFoodFactory: + """Order food from White Castle. """ + + def createBurger() -> AbstractBurger: + ... + return whiteburger + + def createFries() -> AbstractFries: + ... + return straightFries + + def createBurger() -> AbstractDrink: + ... + return cola + +class WhiteCastleBurger extends AbstractBurger: + """White Castle's trademark 5 cent slider. """ + def __init__(): + ... + +class StraightFries extends AbstractBurger: + """Classic, sliced fries. """ + def __init__(): + ... + +class Cola extends AbstractDrink: + """ A classic, caramel soft drink.""" + def __init__(): + ... + +``` + +``` +class McRonald extends AbstractFastFoodFactory: + """Order food from MacRonald. """ + + def createBurger() -> AbstractBurger: + ... + return bigRon + + def createFries() -> AbstractFries: + ... + return curlyFries + + def createBurger() -> AbstractDrink: + ... + return lemonade + +class BigRon extends AbstractBurger: + """The world famous McRon burger. """ + def __init__(): + ... + +class StraightFries extends AbstractBurger: + """Spring-like curly fries. """ + def __init__(): + ... + +class Lemonade extends AbstractDrink: + """ A sweet and sour drink with the refreshing taste of spring lemons.""" + def __init__(): + ... + +``` + +### Singleton + +#### Usage + +A class or resource needs to only have one central instance that is globally accessed across the program. + +A singleton achieves 2 purposes: +- it maintains exactly 1 instance of a given class across the entire program +- it provides a global access point to that class. + +It achieves these by hiding the default constructor of the original class, and then providing a static constructor for the class. The first time the constructor is called, it generates an instance of the class and caches it within a static variable. Further calls to the constructor return the cached instance rather than creating a new one. + +Note that this differs from the factory method in that a singular abstract class is introduced to deal with the creation of _multiple_ related products. + +#### Structure + +The simplest implementation of a singleton design pattern consists of the desired class, adjusted to contain an instance of itself, the default constructor hidden and a getInstance method that returns the cached instance if not null, and creates a new instance(storing in the cache) if the cache is null. If the original object should not be modified, the singleton class can store it in its static cache, and should be used to get instances of the object using the getInstance method call, rather than making direct instances of the object. + +

+UML of 2 different Singleton design patterns +

+ +#### Benefits + +- Maintain and access a central resource with a singular call to the singleton. + +#### Example + +Ronald's Burgers have hit it off, and have become a worldwide sensation. Ronald is very proud of his franchise, and wants to keep track of how many burgers, fries and drinks his franchise has sold around the world. Yet, there's an issue: how could he possibly have every single one of his restaurants access the same set of burger statistics, without accidentally creating a separate set of statistics everytime a different restaurant accesses the statistics? After asking a computer scientist, he learns that he can use a Singleton to achieve this. + +``` +class RonaldStatistics: + """ The global set of Ronald's Burgers statistics. Only one instance of this exists at any given moment.""" + _instance = None + + def private __init__(): + + def private __init__(burger_count, fries_count, drinks_count): + + def getInstance(): + if _instance == None: + burgers_sold = 0 + fries_sold = 0 + drinks_sold = 0 + _instance = RonaldStatistics(burgers_sold, fries_sold, drinks_sold) + + return _instance + + ... + +``` + +### Builder + +#### Usage + +A highly complicated and modular object needs to be created in a step-by-step process, multiple times. Some steps may differ between iterations. + +A builder is a design pattern that is deployed to automate the instantiation of objects that require a step-by-step process to deal with many nested parts. It works by splitting the creation of each nested part/step into a separate method within the builder class. A director class is also introduced in order to handle the ordering/calling of these steps for a chosen builder class. By taking advantage of instantiation, it is possible to extend a given builder class or director class and override one or more methods to partially alter the creation process without having to redo the entire creation process. + +#### Structure + +The builder design pattern typically consists of an abstract builder class containing the methods(steps) common to all building processes for the given family of products, concrete implementations of that class that override/implement methods of the abstract builder, and a director class that stores a builder object and controls the calling of methods for the process. + +

+UML of Builder design pattern +

+ +#### Benefits + +- Simplifies the creation process of complicated objects. +- Allows the adjustment of individual steps without having to rewrite the entire creation process. + +#### Example + +You are Warren Bechtel, a construction work director who has been hired for building multiple buildings in Cityville, including a Ronald's Burgers. All these buildings have the same components (walls, windows, roofs, etc) that each need to be created with their own procedure for each building type. Rather than manually creating each of the buildings from start to finish by hand, you can use the builder design pattern to abstract and automate much of the required process. + +``` +class BuildingDirector: + + _builder = None + + def build(): + ... + + def setBuilder(builder): + ... + +abstract class Builder: + + def buildWalls(): + + def buildWindows(): + + def buildRoof() -> Building: + + ... + + def getBuilding(): + +class McRonaldBuilder extends Builder: + + def buildWalls(): + ... + + def buildWindows(): + ... + + def buildRoof(): + ... + + def getBuilding() -> Building: + + +``` + +## Further Reading + +Refactoring Guru provides a detailed reference guide with examples for creational design patterns, as well as other design patterns that can be useful to implement in the right scenarios. + +[Refactoring Guru: Creational Patterns](https://refactoring.guru/design-patterns/creational-patterns) + +Source Making also provides a more technical description of the same: it can be useful to understand the structure of these design patterns. + +[Source Making: Creational Patterns](https://sourcemaking.com/design_patterns/creational_patterns) + diff --git a/Topics/System_Design/Design_Patterns/DPs.png b/Topics/System_Design/Design_Patterns/DPs.png new file mode 100644 index 000000000..339df6d85 Binary files /dev/null and b/Topics/System_Design/Design_Patterns/DPs.png differ diff --git a/Topics/System_Design/Design_Patterns/design_patterns.md b/Topics/System_Design/Design_Patterns/design_patterns.md new file mode 100644 index 000000000..137805ba2 --- /dev/null +++ b/Topics/System_Design/Design_Patterns/design_patterns.md @@ -0,0 +1,82 @@ +# Design Patterns: MVC, MVP, and MVVM + +## Introduction + +In software engineering, design patterns provide reusable solutions to common problems encountered during software development. Three widely used design patterns are Model-View-Controller (MVC), Model-View-Presenter (MVP), and Model-View-ViewModel (MVVM). Each pattern addresses the separation of concerns within an application's architecture, but they do so in distinct ways, reflecting different priorities schools of thought. + +## Model-View-Controller (MVC) + +### Overview +- MVC divides an application into three interconnected components: Model, View, and Controller. +- Model: Represents the data and business logic. +- View: Displays the user interface. +- Controller: Handles user input and updates the Model and View accordingly. + +### Use Cases +- Web development frameworks like Ruby on Rails, Django, and ASP.NET MVC. +- GUI applications where a clear separation between data, presentation, and user interaction is necessary. + +### Benefits +- Separation of concerns enhances maintainability and scalability. +- Promotes code organization and modularity. +- Supports parallel development by allowing developers to work independently on different components. + +### Drawbacks +- Complexity can increase with larger applications. +- The bidirectional communication between components can lead to tight coupling. +- Testing can be challenging due to dependencies between components. + +## Model-View-Presenter (MVP) + +### Overview +- MVP is a derivative of MVC, focusing on improving testability and modularity. +- Presenter acts as an intermediary between the View and the Model. +- View is passive and does not directly interact with the Model. + +### Use Cases +- Applications requiring extensive unit testing, as MVP facilitates testing by decoupling the View from the Model. +- GUI applications where modularity and testability are critical. + +### Benefits +- Enhances testability by separating concerns and reducing dependencies. +- Facilitates code reuse and modularity. +- Improves maintainability by isolating user interface logic from the business logic. + +### Drawbacks +- Can lead to increased complexity, especially in applications with complex user interfaces. +- Requires additional effort to implement compared to MVC. +- Requires a clear understanding of responsibilities to avoid violating the pattern. + +## Model-View-ViewModel (MVVM) + +### Overview +- MVVM is tailored for modern UI frameworks, such as WPF, Xamarin, and AngularJS. +- Introduces ViewModel as an abstraction of the View's state and behavior. +- ViewModel interacts with the Model to retrieve and manipulate data. + +### Use Cases +- Data-driven applications with complex user interfaces. +- Cross-platform development where code sharing between different platforms is essential. + +### Benefits +- Enables a highly decoupled architecture, allowing for independent development of View and ViewModel. +- Facilitates data binding, reducing boilerplate code and enhancing productivity. +- Promotes code reusability and maintainability by encapsulating UI logic in the ViewModel. + +### Drawbacks +- Learning curve for developers unfamiliar with reactive programming and data binding concepts. +- Overuse of data binding can lead to performance issues in large-scale applications. +- ViewModel can become bloated if not properly managed, impacting maintainability. + +## Conclusion +![Patterns](DPs.png) + +Understanding MVC, MVP, and MVVM design patterns is essential for creating robust, maintainable, and scalable software applications. Each pattern offers distinct advantages and trade-offs, making them suitable for different contexts and development scenarios. By leveraging these patterns effectively, developers can improve code quality, enhance testability, and streamline the development process. + +## Sources + +- [Wikipedia - Model–view–controller](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) +- [Wikipedia - Model–view–presenter](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter) +- [Wikipedia - Model–view–viewmodel](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel) +- [Microsoft Docs - MVVM](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/enterprise-application-patterns/mvvm) +- [Understanding MVC, MVVM, and MVP: A Comprehensive Comparison](https://blog.stackademic.com/understanding-mvc-mvvm-and-mvp-a-comprehensive-comparison-324fd6e3c730) diff --git a/Topics/System_Design/Handling_100K_Requests.md b/Topics/System_Design/Handling_100K_Requests.md new file mode 100644 index 000000000..edc08486c --- /dev/null +++ b/Topics/System_Design/Handling_100K_Requests.md @@ -0,0 +1,55 @@ +# Architecting a System to Handle 100k+ Requests + +## Motivation +When we build a project, we are often concerned with the product; what features does the user want? After we've identified the features to build, we come up with a specification and implement our solution accordingly. We test our code to ensure correctness before then finally shipping. + +But what happens after this? If we have tens or hundreds of thousands of users each making lots of requests, how do we know that our system can handle the load? This page aims to provide a high-level framework for designing such a system and provides additional resources for interested readers. + +We consider an app with three components: a client, an API, and a database. The database stores persistent information, our APIs serve requests for data from the database, and the client renders data for the user to interact with in some capacity. + + +## Vertical and Horizontal Scaling +![Vertical Scaling](./assets/vertical-scaling.png) +*Image from CloudZero* + +Suppose we have an influx of thousands of users, there are two ways we can think about scaling the system: vertically and horizontally. **Vertical scaling** refers to the resource capacity of our APIs; we can increase their capacity by increasing the amount of memory (RAM) and compute power (CPUs) available to our server. However, we can see that this approach will not scale beyond a certain limit simply from a physical and cost perspective. + +![Horizontal Scaling](./assets/horizontal-scaling.png) +*Image from CloudZero* + +So we also consider **horizontal scaling** which refers to increasing the number of servers we have hosting our APIs. We can have virtually infinite servers running to distribute the workload of all the requests we're receiving from the client. Naturally, we will need a way to direct traffic according to some logic so that the load is balanced amongst our servers. + +## Load Balancing +![Load Balancer](./assets/load-balancer.png) +*Image from LimeProxies* + +A **load balancer** is responsible for routing requests from our clients to an instance of our APIs. This will enable the horizontal scaling we discussed previously. Some load-balancing strategies include distributing requests across instances sequentially or routing requests to the instances with the least amount of traffic. A load balancer also improves the reliability of our system, if one of our servers goes down, we can reroute traffic to another server instead of having the entire system fail. Additionally, we can set up a load balancer to increase the number of instances when the number of requests exceeds the capacity of the current instances or to reduce the number of instances when we might expect less traffic. + + +## Database Scaling +![Primary-Replica Database](./assets/primary-replica.png) +*Image from Apurva Agrawal's Medium* + +We will focus on scaling relational databases in this section. There exist many techniques such as **replication**, **federation**, **sharding**, and so on. We will briefly touch on **replication** and defer to the sources below for more detailed information on the other techniques. **Replication** refers to the concept of replicating data from a primary database to replica databases such that any updates to the database requested by the client are first written to the primary before then being propagated to each replica. Then, the other clients and servers can read from any of the replicas to distribute the workload from all our requests. + + +## Caching +![Redis Cache](./assets/redis-cache.png) +*Image from Backendless* + +Another way we can reduce the load on our databases is by introducing a cache layer using something like [Redis](https://redis.io/). When a user makes a request for some data from the database, we store that information in the cache layer with some expiration time *t*. Any future requests made for that information within time period *t* are actually hitting the cache rather than the database. This reduces the workload of our database by handling some of it with the cache layer, and we can scale our cache layer as well by using distributed caching and storing data across multiple machines. + + + +## Content Delivery Networks (CDNs) +![CDN](./assets/cdn.png) +*Image from DigitalOcean* + +CDN servers keep a cache of our files (images, HTML/CSS, JS, ...) at data centers close in geographical proximity to users across the world. When user's make a request for data, it is retrieved from the server closest to the user. This again offloads some of the requests from the main server and helps with reducing errors by increasing redundancy. + + +## Sources + +This page was inspired by Alex Pareto's blog post [Scaling to 100k Users](https://alexpareto.com/scalability/systems/2020/02/03/scaling-100k.html), and drew information from High Scalability's [Guide to Scaling to 11 Million+ Users on AWS](https://highscalability.com/a-beginners-guide-to-scaling-to-11-million-users-on-amazons/), Linh Truong's page on [Building & Scaling to 100 Million Users](https://scholar.harvard.edu/linh/system-design), Anh T. Dang's Medium post on [Designing a System to Scale to 100 Million Users](https://levelup.gitconnected.com/how-to-design-a-system-to-scale-to-your-first-100-million-users-4450a2f9703d), and the Redis [Glossary](https://redis.com/glossary/) + +Images from [CloudZero Vertical Scaling](https://www.cloudzero.com/wp-content/uploads/2023/10/how-vertical-scaling-works-1.webp), [CloudZero Horizontal Scaling](https://www.cloudzero.com/wp-content/uploads/2023/10/how-horizontal-scaling-works-1.webp), [Apurval Agrawal's Medium Article](https://miro.medium.com/v2/resize:fit:1400/0*MfnjmNOUZ7Wd7BNS), [LimeProxies](https://limeproxies.netlify.app/blog/how-to-balance-traffic-without-server-getting-crashed), [Backendless](https://backendless.com/wp-content/uploads/2022/12/How-Redis-typically-works.png), [DigitalOcean](https://doimages.nyc3.cdn.digitaloceanspaces.com/CDN.png) \ No newline at end of file diff --git a/Topics/System_Design/assets/AbstractFactory.png b/Topics/System_Design/assets/AbstractFactory.png new file mode 100644 index 000000000..b87016e2f Binary files /dev/null and b/Topics/System_Design/assets/AbstractFactory.png differ diff --git a/Topics/System_Design/assets/Builder.png b/Topics/System_Design/assets/Builder.png new file mode 100644 index 000000000..182131c13 Binary files /dev/null and b/Topics/System_Design/assets/Builder.png differ diff --git a/Topics/System_Design/assets/Factory Method.png b/Topics/System_Design/assets/Factory Method.png new file mode 100644 index 000000000..80c3d73b5 Binary files /dev/null and b/Topics/System_Design/assets/Factory Method.png differ diff --git a/Topics/System_Design/assets/Simple Factory.png b/Topics/System_Design/assets/Simple Factory.png new file mode 100644 index 000000000..506f5ed5a Binary files /dev/null and b/Topics/System_Design/assets/Simple Factory.png differ diff --git a/Topics/System_Design/assets/Singleton.png b/Topics/System_Design/assets/Singleton.png new file mode 100644 index 000000000..6eb23c476 Binary files /dev/null and b/Topics/System_Design/assets/Singleton.png differ diff --git a/Topics/System_Design/assets/cdn.png b/Topics/System_Design/assets/cdn.png new file mode 100644 index 000000000..28d149026 Binary files /dev/null and b/Topics/System_Design/assets/cdn.png differ diff --git a/Topics/System_Design/assets/horizontal-scaling.png b/Topics/System_Design/assets/horizontal-scaling.png new file mode 100644 index 000000000..c3bb5c6d4 Binary files /dev/null and b/Topics/System_Design/assets/horizontal-scaling.png differ diff --git a/Topics/System_Design/assets/load-balancer.png b/Topics/System_Design/assets/load-balancer.png new file mode 100644 index 000000000..23d6b3426 Binary files /dev/null and b/Topics/System_Design/assets/load-balancer.png differ diff --git a/Topics/System_Design/assets/primary-replica.png b/Topics/System_Design/assets/primary-replica.png new file mode 100644 index 000000000..181945c54 Binary files /dev/null and b/Topics/System_Design/assets/primary-replica.png differ diff --git a/Topics/System_Design/assets/redis-cache.png b/Topics/System_Design/assets/redis-cache.png new file mode 100644 index 000000000..b05546623 Binary files /dev/null and b/Topics/System_Design/assets/redis-cache.png differ diff --git a/Topics/System_Design/assets/vertical-scaling.png b/Topics/System_Design/assets/vertical-scaling.png new file mode 100644 index 000000000..2f72eace4 Binary files /dev/null and b/Topics/System_Design/assets/vertical-scaling.png differ diff --git a/Topics/Tech_Stacks.md b/Topics/Tech_Stacks.md index 827389ef9..e8899059f 100644 --- a/Topics/Tech_Stacks.md +++ b/Topics/Tech_Stacks.md @@ -12,6 +12,8 @@ ### [FastAPI](./Tech_Stacks/FastAPI.md) +### [Embedded Javascript](./Tech_Stacks/EJS.md) + ### [Nuxt3](./Tech_Stacks/Nuxt3.md) ### [Building Apple Native Software Using Swift and SwiftUI](./Tech_Stacks/swift.md) @@ -176,3 +178,10 @@ ### [Introduction to ROBLOX Studio](./Tech_Stacks/ROBLOX_Intro.md) +### [Understanding Bluetooth in Mobile App Development](./Tech_Stacks/Bluetooth.md) + +### [Cross platform vs Native Mobile Development](./Tech_Stacks/Mobile_Development/content.md) + +### [Using Tiptap in a React CRUD App](./Tech_Stacks/Tiptap/Tiptap.md) + +### [Using KY - A versatile HttpClient](./Tech_Stacks/KY.md) diff --git a/Topics/Tech_Stacks/Cuda.md b/Topics/Tech_Stacks/Cuda.md new file mode 100644 index 000000000..a8e2288a5 --- /dev/null +++ b/Topics/Tech_Stacks/Cuda.md @@ -0,0 +1,267 @@ +# CUDA (Compute Unified Device Architecture) + +## Table of Contents: +#### [Introduction]() +#### [Installation]() +#### [A brief primer to GPU architecture]() +#### [Writing our first kernel]() +#### [Optimization techniques]() + +## Introduction: +CUDA, short for Compute Unified Device Architecture, is a proprietary toolkit offered for NVIDIA GPUs that takes advantage of the massive amount of parallelism GPUs offer. In today's landscape, algorithmic complexity and computational theory will only take us so far, and bringing down an algorithm from $O(n^2)$ to $O(n)$ runtime complexity for example will surely help us improve performance, but what if we could assign $n$ units to split up work on our algorithm at a massive scale? Additionally, what if we run into computational problems where there is no good solution? Like the traveling salesman problem? Or gradient descent in machine learning? Or matrix multiplication? Despite our best efforts in reducing these problems computational costs either theoretically or practically through optimization techniques at the CPU level, they are still too costly to perform at a large scale. This is where GPUs come into play. Instead of having one horse pulling a cart, what if you had a thousand chickens? Or ten thousand chickens? Maybe even a million chickens? GPUs are like the million chickens pulling a cart. By having poorer and less versatile performing cores at an individual level than CPUs, we are able to fit thousands, even tens of thousands of cores on a GPU which can compute parallel tasks at a massive scale. The key to doing this is by performing smaller, easy to compute tasks, at a huge parallel scale, compared to tasks that are relatively difficult on their own to compute which would be best fit by a CPU. + +## Installation: + +Note that since CUDA is a proprietary technology, you MUST have an NVIDIA GPU with a valid CUDA compute capability (see [here](https://developer.nvidia.com/cuda-gpus)). You can also install this on a machine with an NVIDIA GPU installed, such as a UofT lab machine, or a computer you can SSH into with an NVIDIA GPU. + +To install CUDA on your system, simply download the [CUDA Toolkit](https://developer.nvidia.com/cuda-downloads) onto your computer. Linux users can either install the executable directly from the NVIDIA website or they can use their favourite package manager to get it from the AUR, APT, and so on. Windows users can simply download the executable directly from the CUDA Toolkit website linked below: + +For example, on Ubuntu: +``` +sudo apt update +sudo apt install nvidia-cuda-toolkit +``` + +https://developer.nvidia.com/cuda-downloads + +Information retrieved from: + +https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html and +https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html + +## A brief (oversimplified) primer to GPU architecture: + +Let's assume our GPU is an NVIDIA GTX 1060. A GTX 1060 has 10 streaming multiprocessors, 15 blocks with a total of 1024 threads per block. What does this all mean? Each streaming multiprocessor (SM) contains a certain amount of blocks it can run. A block is an organization of threads, in our case a block contains up to 1024 threads. Threads are run concurrently across blocks, which get scheduled onto SMs. Each SM can handle a certain number of blocks concurrently. In our case, with 10 SMs, if we have 10 blocks, one per SM, each block would be computed in parallel by a separate SM. However, if the number of blocks exceeds 10, let's say 15 blocks, the SMs would need to context switch between multiple blocks, potentially reducing performance due to switching overhead. Keep in mind that all these performance specifications vary between GPU. Some GPUs support multiple blocks running on an SM without context switching. + +This concept is crucial in GPU optimization and is referred to as occupancy – the maximum number of blocks all the SMs on a GPU can handle simultaneously. Maintaining high occupancy is vital for achieving optimal GPU performance in various computing tasks. The concept of occupancy in GPU architecture resembles multithreading on a single-core CPU. In both cases, the goal is to maximize parallelism and throughput by executing multiple tasks concurrently. Just as a single-core CPU executes multiple threads by rapidly switching between them, GPUs with multiple SMs must efficiently manage blocks, ensuring that each SM is fully utilized without excessive context switching. + +Another important topic that will come up is GPU memory. Often referred to as device memory (whereas RAM is considered host memory), GPUs have built-in memory to avoid the slow bandwidth encountered with traditional RAM that the CPU communicates with. This GPU memory often referred to as VRAM is high-speed, high-throughput volatile memory that is meant for high-bandwidth operations. When executing GPU code, note that we must transfer elements such as arrays from traditional RAM onto our GPU memory. + +The following images below will help clear up any confusion about our GPU architecture. + +![image](https://docs.nvidia.com/cuda/cuda-c-programming-guide/_images/gpu-devotes-more-transistors-to-data-processing.png)*CPU vs GPU architecture. Notice how more cores are devoted to GPUs than CPUs, at the cost of less computational versatility.* + +![image](https://docs.nvidia.com/cuda/cuda-c-programming-guide/_images/automatic-scalability.png) +*CUDA programs can be divided into blocks which can then be assigned onto SMs by the compiler at runtime.* + +Source: https://docs.nvidia.com/cuda/cuda-c-programming-guide/ + +## Writing our first kernel: + +Note that the CUDA language is effectively a wrapper for C++, with additional runtime libraries provided by NVIDIA. This guide assumes that you are somewhat comfortable with C or C++. Lets start by launching a kernel, which is a specialized function that is executed in parallel by multiple threads on the GPU. In CUDA, this involves defining the kernel with the `__global__` qualifier, indicating it's meant to be run on the GPU. When kernels are launched, they spawn a large number of threads specified in the angular brackets like so, with the block size, and the threads per block being specified like so: `<<>>example_kernel(param1, param2, ...)`. Lets define a kernel that multiplies two arrays together and puts the result in another array. But first, we'll need to allocate some device memory. See the following: + +```cpp +#include +__global__ void multiply_floats(float *a, float *b, float *result, int n) { + int index = threadIdx.x + blockIdx.x * blockDim.x; + // Get the global thread index by calculating which block and thread inside each block we're in + + // Make sure we don't calculate over the array size + if (index < n) { + result[index] = a[index] * b[index]; + } +} + +int main() { + int n = 100000000; // Size of the arrays + float *a, *b, *result; // Pointers for host (CPU)arrays + float *d_a, *d_b, *d_result; // Pointers for device (GPU) arrays + size_t size = n * sizeof(float); + + // Allocate memory on the host + a = (float*)malloc(size); + b = (float*)malloc(size); + result = (float*)malloc(size); + + // Allocate memory on the device + cudaMalloc(&d_a, size); + cudaMalloc(&d_b, size); + cudaMalloc(&d_result, size); + + // Copy data from host to device + cudaMemcpy(d_a, a, size, cudaMemcpyHostToDevice); + cudaMemcpy(d_b, b, size, cudaMemcpyHostToDevice); + + // Define kernel launch configuration + int blockSize = 1024; + int numBlocks = (n + blockSize - 1) / blockSize; + + // Launch kernel + multiply_floats<<>>(d_a, d_b, d_result, n); + cudaDeviceSynchronize(); // Wait for GPU code (kernel) to finish + + // Copy result from device to host + cudaMemcpy(result, d_result, size, cudaMemcpyDeviceToHost); + + // Free device memory + cudaFree(d_a); + cudaFree(d_b); + cudaFree(d_result); + + // Free host memory + free(a); + free(b); + free(result); + + return 0; +} + +``` +This is a basic CUDA kernel for performing parallel computations on the GPU. This code snippet allocates memory on both the host and the GPU for these arrays, and also allocates memory on the GPU for the result array. After copying the data from the host to the GPU, it launches the `multiply_floats` kernel, specifying the number of blocks and threads per block. The kernel computes the element-wise multiplication of corresponding elements from a and b, storing the result in the result array. Finally, the result is copied back from the GPU to the host, and memory on both the host and the GPU is freed to prevent memory leaks. Lets call this file `multiply_floats.cu`. + + Using NVCC, the NVIDIA CUDA Compiler, which we installed earlier from the CUDA Toolkit, we can compile the CUDA program with ease. To compile the program, we simply invoke nvcc from the command line, specifying the source files as arguments. NVCC automatically detects CUDA code within the source files and compiles them into GPU machine code, while also compiling any C++ code present. + +```nvcc multiply_floats.cu -o multiply_floats``` + +We can then run `./multiply_floats` in our terminal to execute this program. + +## Optimization techniques: + +You may notice that running `multiply_floats` is a bit slow. Some of the major bottlenecks in CUDA kernel computations are: + +1. Transferring data from RAM to GPU memory +2. Access (read/write) times of GPU memory + +Lets speed up our `multiply_floats` kernel by minimizing the bottleneck of transferring data between RAM and GPU memory, as well as improving our read/write times. We can do the former through a technique called pinning the main memory. To speed up the `multiply_floats` kernel by minimizing the bottleneck of transferring data between RAM and GPU memory and improving read/write times, we can follow these steps: + + - Allocate Pinned Memory: Instead of using regular host memory, allocate pinned memory for the input and output data. Pinned memory ensures faster data transfers between the CPU and GPU. + - Instead of using `cudaMalloc` we can use the `cudaMallocHost` function to allocate memory on the host that is pinned. See below: + +![Image](https://developer-blogs.nvidia.com/wp-content/uploads/2012/12/pinned-1024x541.jpg) + + ```cpp +#include + +__global__ void multiply_floats(float *a, float *b, float *result, int n) { + int index = threadIdx.x + blockIdx.x * blockDim.x; + // Get the global thread index by calculating which block and thread inside each block we're in + + // Make sure we don't calculate over the array size + if (index < n) { + result[index] = a[index] * b[index]; + } +} + +int main() { + int n = 100000000; // Size of the arrays + float *a, *b, *result; // Pointers for host (CPU) arrays + float *d_a, *d_b, *d_result; // Pointers for device (GPU) arrays + size_t size = n * sizeof(float); + + // Allocate pinned memory on the host + cudaMallocHost((void**)&a, size); + cudaMallocHost((void**)&b, size); + cudaMallocHost((void**)&result, size); + + // Allocate memory on the device + cudaMalloc(&d_a, size); + cudaMalloc(&d_b, size); + cudaMalloc(&d_result, size); + + // Copy data from host to device + cudaMemcpy(d_a, a, size, cudaMemcpyHostToDevice); + cudaMemcpy(d_b, b, size, cudaMemcpyHostToDevice); + + // Define kernel launch configuration + int blockSize = 1024; + int numBlocks = (n + blockSize - 1) / blockSize; + + // Launch kernel + multiply_floats<<>>(d_a, d_b, d_result, n); + cudaDeviceSynchronize(); // Wait for GPU code (kernel) to finish + + // Copy result from device to host + cudaMemcpy(result, d_result, size, cudaMemcpyDeviceToHost); + + // Free device memory + cudaFree(d_a); + cudaFree(d_b); + cudaFree(d_result); + + // Free pinned host memory + cudaFreeHost(a); + cudaFreeHost(b); + cudaFreeHost(result); + + return 0; +} + +``` + +Another trick up our sleeves is using shared memory. Just as how CPUs have L1/L2/L3 caches, SMs on GPUs also have L1 caches. Since fetching from VRAM is slower than using an SM's L1 cache, we can improve read/write times by manually loading our arrays into the L1 caches on our SMs. See the following below: + +```cpp +#include + +__global__ void multiply_floats(float *a, float *b, float *result, int n) { + __shared__ float shared_a[1024]; + __shared__ float shared_b[1024]; + // We need to mark shared memory with the __shared__ qualifier + // so NVCC can recognize that it needs to be loaded into L1 caches + + int index = threadIdx.x + blockIdx.x * blockDim.x; + // Get the global thread index by calculating which block and thread inside each block we're in + + // Loop over array in strides of block size + for (int i = blockIdx.x * blockDim.x; i < n; i += blockDim.x * gridDim.x) { + // Load data into shared memory + int shared_index = threadIdx.x; // block-wise thread-index + if (i + threadIdx.x < n) { + shared_a[shared_index] = a[i + threadIdx.x]; + shared_b[shared_index] = b[i + threadIdx.x]; + } + __syncthreads(); // Synchronize threads in the block before computation + + // Compute element-wise multiplication + int local_index = i + threadIdx.x; + if (local_index < n) { + result[local_index] = shared_a[shared_index] * shared_b[shared_index]; + } + __syncthreads(); // Ensure all threads have finished computation before loading new data + } +} + +int main() { + int n = 100000000; // Size of the arrays + float *a, *b, *result; // Pointers for host (CPU) arrays + float *d_a, *d_b, *d_result; // Pointers for device (GPU) arrays + size_t size = n * sizeof(float); + + // Allocate pinned memory on the host + cudaMallocHost((void**)&a, size); + cudaMallocHost((void**)&b, size); + cudaMallocHost((void**)&result, size); + + // Allocate memory on the device + cudaMalloc(&d_a, size); + cudaMalloc(&d_b, size); + cudaMalloc(&d_result, size); + + // Copy data from host to device + cudaMemcpy(d_a, a, size, cudaMemcpyHostToDevice); + cudaMemcpy(d_b, b, size, cudaMemcpyHostToDevice); + + // Define kernel launch configuration + int blockSize = 1024; + int numBlocks = (n + blockSize - 1) / blockSize; + + // Launch kernel + multiply_floats<<>>(d_a, d_b, d_result, n); + cudaDeviceSynchronize(); // Wait for GPU code (kernel) to finish + + // Copy result from device to host + cudaMemcpy(result, d_result, size, cudaMemcpyDeviceToHost); + + // Free device memory + cudaFree(d_a); + cudaFree(d_b); + cudaFree(d_result); + + // Free pinned host memory + cudaFreeHost(a); + cudaFreeHost(b); + cudaFreeHost(result); + + return 0; +} +``` diff --git a/Topics/Tech_Stacks/EJS.md b/Topics/Tech_Stacks/EJS.md new file mode 100644 index 000000000..c63aa00c1 --- /dev/null +++ b/Topics/Tech_Stacks/EJS.md @@ -0,0 +1,124 @@ +# Embedded JavaScript (EJS): Simplifying Web Development with Dynamic Content + +Embedded JavaScript (EJS) is a powerful templating language that simplifies the process of dynamically generating HTML content. In this tutorial, we'll explore the basics of EJS and delve into some of the more advanced functionality that will enable you to create dynamic and interactive web pages. + +## Requirements + +EJS works seamlessly across various platforms, including Windows, Mac, and Linux, and is compatible with both Python 2 and 3. Ensure you have Python installed before proceeding. You can refer to the official Python website for installation instructions. This tutorial demonstrates examples using Python 3. + +## Introduction to Embedded JavaScript + +Embedded JavaScript (EJS) allows developers to embed JavaScript code directly within their HTML markup. Unlike other traditional templating languages, EJS leverages JavaScript's expressive syntax which allows for a seamless integration of the server-side logic with the client-side views. + +## What Can You Achieve with EJS? + +EJS empowers developers to accomplish a wide array of tasks, including: + +- **Dynamic Content Generation**: Effortlessly generate dynamic content by embedding JavaScript expressions within HTML templates. + +- **Conditional Rendering**: Implement conditional logic to selectively render content based on specified criteria + +- **Data Binding**: Bind server-side data to client-side views, facilitating the presentation of dynamic information to users. + +- **Iterative Rendering**: Iterate over data collections to dynamically generate HTML elements, enabling the creation of dynamic lists, tables, and more. + +## Installation + +Before using EJS, you need to install it. You can install EJS via npm, the Node.js package manager, using the following command: + +```bash +npm install ejs +``` + +## Getting Started + +To begin using EJS, create a new HTML file and import the EJS library: +```html + +``` + +## Basic Syntax and Usage +EJS employs a very simple but powerful syntax to embed JavaScript code within HTML markup. Below are some of the fundamental concepts: + +- **Interpolation: Use <%= %> tags to insert the result of a JavaScript expression into the HTML document. + +- **Conditional Statements: Use <% if (condition) { %> ... <% } %> blocks to implement conditional rendering based on specific conditions. + +- **Iterative Rendering: Use <% for (let item of items) { %> ... <% } %> constructs to iterate over data collections and generate dynamic content. + +## Advanced Features +Beyond the basics, EJS offers advanced features to further enhance your web development workflow: + +- **Partials: Convert your templates into modules by creating reusable partials which enables you to reuse your code and make it look more presentable, similar to React components + +- **Layouts: Define master layouts to encapsulate common page structures and streamline the creation of consistent user interfaces. + +- **Custom Functions: Extend EJS functionality by defining custom JavaScript functions and incorporating them into your templates. + +## Example Usage +In this section we see how some of these functionalities are used + +This is an example of a partial: +```html + + + + + + +``` + +This footer can be reused in any other pages by including this line whereever the footer is needed. + +```html +<%- include("partials/header") %> + +

<%= postHeader %>

+

<%= postContent %>

+ +<%- include("partials/footer") %> +``` + +In this example, we include the header, have some custom content, and then have the footer. This also shows how interpolation is used to display the variables postHeader and postContent which are passed in as JSON objects by the server. + +Below we see an example of iterative rendering: +```html +<% posts.forEach(function(post) { %> +

<%= post.title %>

+

+ <%= post.content.substring(0, 100) + " ..."%> + Read More +

+<% }) %> +``` + +It may also be a useful addition to see how the server is interacting with these pages, so some code examples are given below, note how the variables are passed in and used. + +```html +app.get("/", function (req, res) { + res.render("home", {homeStartingContent: homeStartingContent, posts: posts}) +}) +``` + +One of the key advantages of EJS can also be seen through the following code sample: +```html +app.get("/posts/:postName", function (req, res) { + + posts.forEach(function(post) { + if (_.lowerCase(post.title) === _.lowerCase(req.params.postName)) { + res.render("post", {postHeader: post.title, postContent: post.content}) + } + }) + +}) +``` + +In this example we can see that for each post in the database, we dynamically create a new page posts/postName, wherein each page has the same exact format, just the content is differed depending on the post itself. + + +## Learn More + +- **https://ejs.co/#install +- **https://www.digitalocean.com/community/tutorials/how-to-use-ejs-to-template-your-node-application diff --git a/Topics/Tech_Stacks/Framer_Motion.md b/Topics/Tech_Stacks/Framer_Motion.md new file mode 100644 index 000000000..ec767e575 --- /dev/null +++ b/Topics/Tech_Stacks/Framer_Motion.md @@ -0,0 +1,123 @@ +# Intro to Framer Motion, an Animation Library for React + +## Table of contents +### [Introduction & Prerequisites](#introduction-&-prerequisites) +### [Installation](#installation) +### [Framer Motion Basics](#framer-motion-basics) +- #### [The Motion Component](#motion) +- #### [Animation Props](#animation-props) +- #### [Transitions](#transitions) +- #### [Keyframes](#keyframes) +- #### [Variants](#variants) +### [Conclusion](#conclusion) +### [Resources](#resources) + + +## Introduction & Prerequisites +Framer Motion is a production-ready animation library designed for React. Framer Motion simplifies the process of adding animations by using unique components and props which act as an interface for adding animated properties to elements. + +This page will serve as a quick, easy, and informative guide to getting started with the Framer Motion animation library. It will cover the first time installation and set-up of Framer Motion, foundational knowledge of animation components & props, an overview of a few key modifiable values, and a couple of quick tricks. A list of resources will also be included at the end. + +Before starting with the Framer Motion library, you should have some familliarity with React (specifically the use of [props & components](https://legacy.reactjs.org/docs/components-and-props.html)) as well as basic knowledge of CSS. + +## Installation +Before using Framer Motion, you first need to have a React project set-up for you to add animations to. If you haven't made a React project before, you can follow the steps outlined in the [React documentation](https://react.dev/learn/start-a-new-react-project). Now that you've made your React project, we can now add Framer Motion. To do so, we first need to install the Framer Motion package: + +``` +npm install framer-motion +``` + +Then on any page where you want to use Framer Motion, add the following import statement to the top of the file: + +```jsx +import { motion } from "framer-motion" +``` + +And with that, you are ready to start using Framer Motion! + +## Framer Motion Basics + +### Motion +The `motion` components are the core elements of Framer Motion and serve as the foundation for animating HTML elements in your React components. The most basic of these is motion.div: +```jsx + +``` +By itself, a motion component won't do anything special. The real magic happens when you wrap other components within it. By passing animation props to your motion component, you can easily animate anything contained within. The most foundational of these props are `initial` and `animate`. + +### Animation Props +`inital` represents, as the name would suggest, the initial state of animation. You can think of this as the "starting position" for your element. If not specified, the initial state will just be the base properties of the element. `animate`, on the other hand, represents the final state of your animation. Framer Motion will automatically fill in the transitional states between when animating unless otherwise specified (which we will touch upon later). You fill in each respective state with the style arguments you wish to have. Take the following code: + +```jsx + +``` + +We will assume that there is some associated CSS code such that defining `className="box"` will present a box on screen. Initially, the box will start at an x position of -300px, but will automatically be animated to progress towards an end x position of 300px as defined in `animate`. See a possible result below: + +![Alt Text](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExMnhseHZsd2hhMm12MHp6eXZrZWxoYzJhOGxhbTlyeG5oN3JtMWttOCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/iMKcGg169M6KYnd2bF/giphy.gif) + +There are many other properties you can animate, such as opacity and scale. + +### Transitions +You may notice that the animation above seems a little bland. To fix this, we can add a `transition` prop, which defines how Framer Motion should progress between states. Framer Motion has a few pre-defined transitions which you are able to easily implement in your animations. For example, `easeIn` will cause the animation to start more gradually. You can also specify a duration for how long you want the animation to take. You may find more about transitions and any pre-defined values [here.](https://www.framer.com/motion/transition/) See a possible implementation below: + +```jsx + +``` + +![Alt Text](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExaWE1NzAzanZxNG0yNHVmZXdiMnJlaHlkczlwaTBzaHZucGV6djZnMCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/gCQUqgks3CufcJIC2k/giphy.gif) + +### Keyframes +Keyframes provide a way to define specific states of an animation at different points in time. By specifying keyframes, you are able to exert more control over the fine details of an animation sequence or create more complex animations. To specify keyframes, simply pass in an array of your desired values as an argument to your animation prop. Note that every value in a keyframe array must be of the same type (i.e., number, px, vw, etc.): + +```jsx + +``` + +![Alt Text](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExdG41NTRqbzRzMW95YjF2OW5qanYxOWwxZnphNHo2N3FpZjh4bDUwdSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/wtzfpkMVNsJ2n3d81r/giphy.gif) + +### Variants +Variants essentially allow you to externally define some set of animation properties as a variable or constant that you can then apply to multiple components as desired. This can help prevent a lot of repetitive code and allows you to easily reuse animations. You can loosely think of variants as a dictionary where each key represents an associated set of animation values: + +```jsx + const example_variants = { + big: { scale: 2 }, + small: { scale: 0.5 }, + }; + return ( + + ); +``` + +![Alt Text](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExNjQyNXZmMGdkdGE4cmNla2dlcTNuZGJnNGc0aDJsdHcyOWhpamM4YiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/y1kKmiZIGg4OE5uu7e/giphy.gif) + +## Conclusion +With this, you should have a good grasp on the basics of Framer Motion! Much like CSS, there are a ton of options as far as customizability goes, so it is highly recommended to read the documentation and to experiment in order to see the full scope of the Framer Motion library. Happy Animating! + +## Resources +- [Framer Motion Documentation](https://www.framer.com/motion/) +- [Framer Motion Crash Course Video](https://www.youtube.com/watch?v=znbCa4Rr054) +- [Transitions in Framer](https://www.framer.com/motion/transition/) + + diff --git a/Topics/Tech_Stacks/Mobile_Development/android.pdf b/Topics/Tech_Stacks/Mobile_Development/android.pdf new file mode 100644 index 000000000..81ef9a329 Binary files /dev/null and b/Topics/Tech_Stacks/Mobile_Development/android.pdf differ diff --git a/Topics/Tech_Stacks/Mobile_Development/content.md b/Topics/Tech_Stacks/Mobile_Development/content.md new file mode 100644 index 000000000..84ce9213e --- /dev/null +++ b/Topics/Tech_Stacks/Mobile_Development/content.md @@ -0,0 +1,161 @@ +# Introduction to Cross Platform vs Native Mobile Development +![cpVnative](img1.png) + +## Table of Contents +1. [Cross-Platform Development Frameworks](#cross-platform-development-frameworks) +2. [Advantages and Challenges of Cross-Platform Development](#advantages-and-challenges-of-cross-platform-development) +3. [Popular Cross-Platform Development Tools and Frameworks](#popular-cross-platform-development-tools-and-frameworks) +4. [Native Mobile Development](#native-mobile-development) +5. [Advantages and Challenges of Native Development](#advantages-and-challenges-of-native-development) +6. [Comparing Performance and User Experience](#comparing-performance-and-user-experience) +7. [Examples of Products](#examples-of-products) +8. [Developer Resources](#developer-resources) +9. [References](#references) + +## Cross-Platform Development Frameworks + +Cross-platform development for mobile involves creating applications that can run seamlessly across multiple operating systems, such as iOS and Android, utilizing a single codebase. Through cross-platform frameworks, developers gain the ability to streamline the development process by writing code once and deploying it across various platforms. CSC301 students can benefit greatly from understanding cross-platform development as it is easier to implement for multiple famous platforms such as iOS and Android. According to Stack Overflow's Developer Survey 2021, React Native was ranked among the top frameworks loved by developers. Students with existing knowledge in web can easily start-off with React Native providing them with a clear transition. + +## Advantages and Challenges of Cross-Platform Development + +### Advantages + +1. Faster development and deployment times compared to native development +2. Cost-effectiveness due to code reuse across multiple platforms +3. Simplified maintenance and updates with a single codebase +4. Greater reach by targeting multiple platforms simultaneously + +### Challenges + +1. Performance limitations compared to native development +2. Platform-specific nuances and limitations may require workarounds +3. Dependency on third-party frameworks and libraries, which may introduce compatibility issues +4. Limited access to platform-specific features and APIs may restrict functionality + +## Popular Cross-Platform Development Tools and Frameworks +According to different skill-set of CSC301 Students they can choose either framework for developing their application. A thorough breakdown is as follows: +### React Native +- **Description:** Developed by Facebook, allows building native-like apps using JavaScript and React. +- **Features and Benefits:** + - Wide community support and extensive ecosystem of libraries and components. +- **Key Differences:** + - Utilizes JavaScript and React for cross-platform development. Notable for its large community. +- **Companies Using:** + - Facebook, Instagram, Airbnb + +### Flutter +- **Description:** Developed by Google, offers a fast and expressive way to build native apps for iOS and Android from a single codebase. +- **Features and Benefits:** + - Layered architecture with customizable widgets for building UIs, Hot reload feature. +- **Key Differences:** + - Utilizes Dart programming language and features a layered architecture with customizable widgets. +- **Companies Using:** + - Alibaba, Google Ads, Reflectly + +### Xamarin +- **Description:** Acquired by Microsoft, allows building native apps for iOS, Android, and Windows using C# and .NET. +- **Features and Benefits:** + - Integration with Visual Studio and support for native APIs, Code sharing across platforms. +- **Key Differences:** + - Utilizes C# and .NET for cross-platform development. Offers deep integration with Visual Studio. +- **Companies Using:** + - UPS, Honeywell, Olo + + +## Native Mobile Development + +Native mobile development for iOS and Android involves creating applications specifically tailored for each platform using their respective programming languages and frameworks. For iOS, developers typically use Swift while for Android, Kotlin or Java are commonly employed. Notable IDEs for native development include Xcode for iOS and Android Studio for Android, providing robust toolsets for designing, debugging, and deploying applications. Understanding native development will help CSC301 students with the ability to harness platform specific capabilities fully, delivering high-performance, feature-rich mobile applications tailored to partners' needs. + +### Advantages and Challenges of Native Development + +#### Advantages + +1. **Performance**: Native apps typically offer superior performance compared to cross-platform alternatives as they are optimized for specific platforms, leveraging platform-specific features and APIs. +2. **Seamless Integration**: Native apps seamlessly integrate with the device ecosystem, providing a cohesive user experience consistent with the platform's design guidelines and user expectations. +3. **Optimized User Interface**: Native development enables developers to create highly responsive and intuitive user interfaces that align closely with the platform's design principles, enhancing user engagement and satisfaction. + +#### Challenges + +1. **Platform Dependency**: Developing separate codebases for iOS and Android requires additional time and resources compared to cross-platform development, as developers need to maintain platform-specific codebases and implement platform-specific features separately. CSC301 students need people with both domain knowledge otherwise, they won't be able to fulfill partner's requirement. +2. **Learning Curve**: Learning platform-specific languages and frameworks, such as Swift for iOS and Kotlin for Android, may require additional time and effort, especially for developers new to mobile development. +3. **Release Cycle**: Releasing updates and new features simultaneously across multiple platforms may pose challenges due to differences in release processes and approval times between app stores. This can be seen as a challenge for CSC301 students who have limited time for releasing a product. + + +Native Mobile development also allows ease to follow platform-specific design guidelines. These guidelines provide developers with insights into the user interface (UI) and user experience (UX) expectations specific to each platform, ensuring that applications look and feel native to the respective operating systems. + +## Comparing Performance and User Experience + +### Performance considerations in cross-platform vs native development + +- **Cross-platform Development**: + - Performance may be impacted due to additional layers of abstraction and interpretation required by cross-platform frameworks. + - Execution speed and resource consumption may vary depending on the framework used and the complexity of the application. +- **Native Development**: + - Native apps generally offer better performance as they directly access platform-specific APIs and optimizations. + - Optimized for the specific hardware and software of each platform, leading to faster execution and responsiveness. + +### Testing Environments + +- **Cross-platform Development**: + - Testing across multiple platforms can be streamlined using cross-platform testing frameworks. + - Ensuring compatibility and consistency across different devices and OS versions is crucial. This can be little challenging for CSC301 students as they have to write tests that ensure logic as well as rendering in their corresponding platform. +- **Native Development**: + - Testing typically involves separate testing environments for each platform (iOS and Android). + - Integration Testing and Unit Testing for common for Android and iOS Development which are highly useful for CSC301 students and for developers in large. + +### Long-term implications for scalability and codebase maintenance + +- **Cross-platform Development**: + - Codebase maintenance is simplified as changes are applied universally across platforms. + - Scalability may be limited by the capabilities and constraints of the chosen cross-platform framework. This is one of the biggest advantages as down the line partner's platform may stop working if the libraries for cross-platform language are no longer supported. +- **Native Development**: + - Scalability can be optimized for each platform individually, allowing for greater flexibility and performance optimization. + - Maintenance efforts may increase with separate codebases for iOS and Android, but platform-specific optimizations can lead to better long-term scalability. This point needs to be ensured during handover of the project so that future CSC301 students can take over and build more features upon the existing codebase. + +### Hybrid Mobile Application Approach + +Hybrid app development approaches involve leveraging web technologies (HTML, CSS, JavaScript) within native app frameworks. One common approach is using web views within native apps, where web content is displayed within a native app container. Popular frameworks for hybrid app development include Apache Cordova/PhoneGap and Ionic. However, hybrid approaches may sometimes face performance and user experience challenges compared to fully native apps. + +## Examples of Products + +- **Cross-platform Development**: + - React Native: Facebook, Instagram, Airbnb + - Flutter: Alibaba, Google Ads, Reflectly +- **Native Development**: + - iOS Apps: Instagram, Airbnb, Spotify + - Android Apps: Google Maps, Instagram, WhatsApp + + +## Developer Resources + +Finally, for CSC301 students to get started with the development process, here are some of the resources they could refer to: + +- **Documentation and Tutorials:** +This is great for students who need quick access to doucmentations + - [React Native Documentation](https://reactnative.dev/docs/getting-started) + - [Flutter Documentation](https://flutter.dev/docs) + + +- **Video Tutorials:** This is recommended for students who want to get started using online Tutorials or Books + - [The Net Ninja - React Native Tutorial for Beginners](https://www.youtube.com/playlist?list=PL4cUxeGkcC9ixPU-QkScoRBVxtPPzVjrQ) + - [Academind - Flutter & Dart - The Complete Guide [2021 Edition]](https://www.udemy.com/course/learn-flutter-dart-to-build-ios-android-apps/) + +- **Development Tools:** + - [Visual Studio Code](https://code.visualstudio.com/) + - [Android Studio](https://developer.android.com/studio) + - [Xcode](https://developer.apple.com/xcode/) + +These resources provide a comprehensive starting point for CSC301 students to learn, practice, and excel in the development process. Here are the roadmap that they can follow. This provides an illustration of the all the branches of knowledge that one need to fully understand the concepts and topics behind each of the development process: + +[Android Roadmap](android.pdf) + +[React Native Roadmap](react-native.pdf) + + + +## References +Ahmed, Kamran. “Learn to Become a Modern React Native Developer.” Roadmap.Sh, 27 June 2023, [roadmap.sh](https://roadmap.sh/). Accessed 17 Mar. 2024. + +“Should I Choose Cross-Platform Mobile App Development over Native Apps?” TechAhead, 7 May 2023, [www.techaheadcorp.com/blog/cross-platform-app-development-over-native-apps/](www.techaheadcorp.com/blog/cross-platform-app-development-over-native-apps/) Accessed 17 Mar. 2024. + +Schmitt, Jacob. “Native vs Cross-Platform Mobile App Development.” CircleCI, 24 Aug. 2022, [circleci.com/blog/native-vs-cross-platform-mobile-dev/](circleci.com/blog/native-vs-cross-platform-mobile-dev/). Accessed 17 Mar. 2024. \ No newline at end of file diff --git a/Topics/Tech_Stacks/Mobile_Development/img1.png b/Topics/Tech_Stacks/Mobile_Development/img1.png new file mode 100644 index 000000000..66532b162 Binary files /dev/null and b/Topics/Tech_Stacks/Mobile_Development/img1.png differ diff --git a/Topics/Tech_Stacks/Mobile_Development/react-native.pdf b/Topics/Tech_Stacks/Mobile_Development/react-native.pdf new file mode 100644 index 000000000..8c65a27d9 Binary files /dev/null and b/Topics/Tech_Stacks/Mobile_Development/react-native.pdf differ diff --git a/Topics/Tech_Stacks/PDFKit.md b/Topics/Tech_Stacks/PDFKit.md new file mode 100644 index 000000000..4e638fd60 --- /dev/null +++ b/Topics/Tech_Stacks/PDFKit.md @@ -0,0 +1,164 @@ +# Introduction to PDFKit +## Table of Contents +- [Introduction](#introduction) +- [Getting Started](#getting-started) + - [Installation](#installation) + - [Basic Usage](#basic-usage) +- [Features](#features) + - [Text](#text) + - [Images](#images) + - [Vector Graphics](#vector-graphics) + - [Annotations](#annotations) +- [Advanced Usage](#advanced-usage) + - [Custom Fonts](#custom-fonts) + - [Multipage Support](#multipage-support) + - [Performance](#performance) +- [Conclusion](#conclusion) +- [References](#references) + +## Introduction + +PDFKit is a powerful PDF document generation library for Node.js and the browser. It enables developers to create complex PDFs from scratch or manipulate existing PDF documents. PDFKit provides an extensive set of features, including text, images, vector graphics, and more, making it suitable for a wide range of applications, from dynamic invoice generation to creating ebooks and reports. + + +## Getting Started + +### Installation + +To use PDFKit in your project, you first need to install it through npm, Node.js's package manager. Open your terminal and run: + +```bash +npm install pdfkit +``` + +### Basic Usage + +Here's a simple example of generating a PDF document with PDFKit: + +```javascript +// Import PDFKit +const PDFDocument = require('pdfkit'); +const fs = require('fs'); + +// Create a document +const doc = new PDFDocument(); + +// Pipe the document to a blob +doc.pipe(fs.createWriteStream('output.pdf')); + +// Add some content +doc.fontSize(25).text('Hello, World!', 100, 100); + +// Finalize the document and end the stream +doc.end(); +``` + +This code creates a PDF file named `output.pdf` with the text "Hello, World!". + +## Features + +### Text + +PDFKit allows you to add text with various styles and alignments. You can customize the font size, color, and type. +```javascript +// Add custom styled text +doc.fontSize(18) // Set font size + .font('Times-Roman') // Set font type + .fillColor('blue') // Set text color + .text('Hello, World!', 100, 100); // Add text at position (x: 100, y: 100) +``` +![Output of code snippet](./PDFKit_Graphics/image1.png) + + +### Images + +Adding images to your PDF is straightforward. PDFKit supports JPEG and PNG formats. You can control the positioning and scaling of images. +```javascript +// Add an image +const imagePath = 'path/to/image.png'; // Path to your image +doc.image(imagePath, 50, 150, { width: 300, height: 150 }); // Position (x: 50, y: 150) and scale to width 300, height 150 +``` +![Output of code snippet](./PDFKit_Graphics/image2.png) + +### Vector Graphics + +PDFKit excels at drawing shapes and paths, enabling you to add lines, circles, and arbitrary paths to your documents. +```javascript +// Draw a line +doc.moveTo(100, 200) // Start point + .lineTo(300, 200) // End point + .stroke(); + +// Draw a circle +doc.circle(100, 300, 50) // Center (x: 100, y: 300), Radius: 50 + .fill('red'); // Fill color + +// Arbitrary path (drawing a triangle here) +doc.moveTo(100, 350) // Start at this point + .lineTo(150, 400) // Line to this point + .lineTo(50, 400) // Line to this point + .closePath() // Connect end to start + .stroke(); // Stroke the path +``` +![Output of code snippet](./PDFKit_Graphics/image3.png) + +### Annotations + +You can include links, notes, and highlights in your PDF files, making it perfect for interactive documents. +```javascript +// Set the font size and fill color, then add text at position (x: 20, y: 20) +doc.fontSize(25) + .fillColor('blue') + .text('This is a link!', 20, 20); + +// Measure the width and height of the string 'This is a link!' to use in annotations +const width = doc.widthOfString('This is a link!'); +const height = doc.currentLineHeight(); + +// Add an underline beneath the text and a hyperlink annotation that links to 'http://google.com/' +// The underline and link cover the area defined by the text's width and height +doc.underline(20, 20, width, height, {color: 'blue'}) + .link(20, 20, width, height, 'http://google.com/'); + +// Set the fill color to red, then add a highlight annotation behind the text 'Hello World!' +// Following this, the text 'Hello World!' is added. +// The highlight covers the width of 'Hello World!' text and a fixed height of 25 units starting from the current document position (doc.y) +doc.fillColor('red').highlight(20, doc.y, doc.widthOfString('Hello World!'), 25).text("Hello World!"); + +``` +![Output of code snippet](./PDFKit_Graphics/image4.png) + +## Advanced Usage + +### Custom Fonts in PDFKit + +PDFKit's support for custom fonts including TrueType (.ttf), OpenType (.otf), WOFF, and SVG formats opens up a wide array of typographic possibilities, making your documents visually appealing and tailored to your branding or design requirements. To use a custom font in PDFKit, you first need to have the font file accessible in your project. Here's a brief guide: + +1. **Obtain the Font**: Ensure you have the correct format of the font you wish to use. If the font isn't freely available, you may need to purchase it from a type foundry or a font marketplace. +2. **Include the Font in Your Project**: Place the font file in a directory accessible to your PDFKit script. +3. **Load the Font into PDFKit**: Use the `font()` method to load your custom font. For example, `doc.font('path/to/your/font.ttf')` sets the current font to your custom font. + +For more detailed instructions and examples, the PDFKit documentation is a valuable resource. The official [PDFKit website](https://pdfkit.org/) and its GitHub repository contain extensive guides and examples on how to integrate custom fonts. + +### Multipage Support + +PDFKit automatically handles page creation and management, allowing for dynamic document generation that spans multiple pages. + +### Performance + +When generating large or complex PDF documents with PDFKit, the library's performance optimizations become crucial. PDFKit is designed to handle vector graphics efficiently and manage memory usage to keep the generation process swift. For complex documents that include high volumes of data, intricate vector graphics, or numerous pages, PDFKit employs techniques like streamlining the rendering processes and optimizing data storage during generation. + +To showcase complex document generation and the impact of PDFKit's optimizations, a practical approach would be to review case studies or tutorials that highlight these aspects. Searching for "PDFKit complex document example" or "PDFKit performance optimization tutorial" in your search engine should yield comprehensive guides and video demonstrations created by the community. These resources can illustrate how PDFKit handles complex document scenarios, from dynamic data visualization to generating extensive reports. + +By delving into these resources, you'll gain a clearer understanding of how to leverage PDFKit's custom font capabilities and performance optimizations in your projects. Whether you're aiming to enhance the visual appeal of your documents with unique typography or ensure smooth and efficient generation of complex PDFs, PDFKit offers the flexibility and power to meet these needs. + + + +## Conclusion + +PDFKit is a versatile tool for PDF generation, offering a broad set of features for creating complex documents. Its ability to work both in Node.js environments and the browser makes it an excellent choice for a variety of applications. Whether you're generating reports, invoices, or custom documents, PDFKit provides the flexibility and power needed to create high-quality PDFs. + +## References + +- PDFKit Official Website: [http://pdfkit.org/](http://pdfkit.org/) +- GitHub Repository: [https://github.com/foliojs/pdfkit](https://github.com/foliojs/pdfkit) diff --git a/Topics/Tech_Stacks/PDFKit_Graphics/image1.png b/Topics/Tech_Stacks/PDFKit_Graphics/image1.png new file mode 100644 index 000000000..3d59c43e8 Binary files /dev/null and b/Topics/Tech_Stacks/PDFKit_Graphics/image1.png differ diff --git a/Topics/Tech_Stacks/PDFKit_Graphics/image2.png b/Topics/Tech_Stacks/PDFKit_Graphics/image2.png new file mode 100644 index 000000000..98703f50c Binary files /dev/null and b/Topics/Tech_Stacks/PDFKit_Graphics/image2.png differ diff --git a/Topics/Tech_Stacks/PDFKit_Graphics/image3.png b/Topics/Tech_Stacks/PDFKit_Graphics/image3.png new file mode 100644 index 000000000..20cd48660 Binary files /dev/null and b/Topics/Tech_Stacks/PDFKit_Graphics/image3.png differ diff --git a/Topics/Tech_Stacks/PDFKit_Graphics/image4.png b/Topics/Tech_Stacks/PDFKit_Graphics/image4.png new file mode 100644 index 000000000..71aa70081 Binary files /dev/null and b/Topics/Tech_Stacks/PDFKit_Graphics/image4.png differ diff --git a/Topics/Tech_Stacks/React_Native_and_Expo.md b/Topics/Tech_Stacks/React_Native_and_Expo.md new file mode 100644 index 000000000..7074393a9 --- /dev/null +++ b/Topics/Tech_Stacks/React_Native_and_Expo.md @@ -0,0 +1,155 @@ +# Mobile App Development with React Native and Expo + +## Relevant Articles +You might also want to check out the following articles: +- [Apple App Store Deployment](https://learning-software-engineering.github.io/Topics/Development_Process/App_Store_Deployment.html) +- [Creating Your First iOS App](https://learning-software-engineering.github.io/Topics/Tech_Stacks/iOS.html) + + +## Why React Native and Expo Over Native Development? + +React Native and Expo offer a compelling alternative to native development for both iOS and Swift and Android with Java/Kotlin, especially for teams looking for rapid development and cross-platform capabilities. + +### Key Advantages: + +- **Cross-Platform Efficiency**: Single codebase for both iOS and Android, reducing development time and resources. +- **Fast Iteration**: Features like hot reloading allow for real-time feedback, speeding up the development process. +- **Accessibility**: Utilizes JavaScript, one of the most widely used languages, lowering the barrier to entry for web developers transitioning to mobile development. +- **Rich Ecosystem**: Large community support with extensive libraries and tools to accelerate development. +- **Simplified Development**: Expo provides an extra layer of simplicity and convenience, offering managed services and a range of APIs out of the box. + +### Native iOS (Swift) and Android (Java/Kotlin) Development: + +Native development involves using platform-specific languages and tools: Swift (or Objective-C) for iOS and Java or Kotlin for Android. Each platform has its own IDE, Xcode for iOS and Android Studio for Android, offering deep integration with their respective ecosystems. + +#### Pros: +- **Performance**: Native code is generally more performant and responsive, especially for graphic-intensive applications. +- **Platform Features**: Immediate access to the latest platform-specific features and capabilities. +- **UI/UX**: Easier to adhere to platform-specific UI/UX guidelines for a more authentic user experience. + +#### Cons: +- **Resource Intensive**: Requires developing and maintaining separate codebases for each platform, increasing time and cost. +- **Steep Learning Curve**: Each platform has its own set of technologies and tools that developers must learn. + +## Introduction to React Native + +React Native is an open-source mobile application framework created by Facebook, Inc. It allows developers to use React, a JavaScript library for building user interfaces, to develop native mobile apps for iOS and Android platforms. React Native enables developers to write their application's UI components in JavaScript and automatically renders them as native platform widgets. + +### Comparing React Native to React + +While both React and React Native are developed by Facebook and share a common design philosophy, there are significant differences between them: + +- **React** is a JavaScript library for building fast and interactive user interfaces for web applications. It operates on the virtual DOM to optimize rendering and improve app performance. +- **React Native**, on the other hand, is a framework for building native mobile apps using React. Instead of targeting the browser, it targets mobile platforms. React Native uses native components as building blocks, offering a more authentic mobile user experience than web views. + +React Native offers the advantage of **Learn Once, Write Anywhere**, enabling developers to use React's framework and write an app that runs on both iOS and Android platforms, significantly reducing development time and cost. + +## Introduction to Expo + +Expo is an open-source platform for making universal native apps for Android, iOS, and the web with JavaScript and React. It provides a set of tools and services built around React Native and native platforms that help you develop, build, deploy, and quickly iterate on iOS, Android, and web apps from the same JavaScript/TypeScript codebase. + +Expo simplifies the development process by removing the need for native code compilation, providing a rich library of pre-made components, and enabling developers to preview changes in real-time across multiple devices. + +## Comparing Native iOS Development in Xcode with React Native and Expo + +Developing native iOS applications involves a different set of tools, languages, and frameworks compared to cross-platform development with React Native and Expo. The primary tool for native iOS app development is Xcode, Apple's integrated development environment (IDE), which provides a comprehensive suite of software development tools for macOS, iOS, watchOS, and tvOS. + +### Development Environment and Languages + +- **Native iOS Development**: + - **Xcode** is the central tool for iOS app development, offering a rich set of features such as Interface Builder for designing UIs, simulators for testing, and debugging tools. + - **Swift** (or Objective-C) is the primary programming language for native iOS apps. Swift is a modern, fast, and type-safe language that offers various features to make iOS app development efficient and safe. + - Developers have direct access to iOS SDKs and can use native APIs and UI components, ensuring optimal performance and a look-and-feel that matches the platform conventions. + +- **React Native and Expo Development**: + - **Expo and React Native CLI** are key tools, with Expo offering a simplified environment ideal for beginners and faster development cycles. + - **JavaScript** or **TypeScript** is used for development, making it accessible to a wider range of developers familiar with web development. + - React Native translates these JavaScript components into native platform components, allowing for a single codebase for both iOS and Android platforms but potentially limiting access to some native APIs and components compared to Xcode. + +### Workflow and Productivity + +- **Native iOS Development**: + - The development workflow is typically more focused on a single platform, allowing for deeper integration with the iOS ecosystem. + - Xcode provides a comprehensive suite of development tools, including advanced debugging, performance testing tools, and seamless integration with Apple's app distribution platform, App Store Connect. + - UI design can be more precisely tailored to iOS, using Storyboards or SwiftUI, to closely adhere to Apple's Human Interface Guidelines. + +- **React Native and Expo Development**: + - Offers a faster development cycle, especially when using Expo, due to features like hot reloading, which allows developers to see changes in real-time without recompiling the entire app. + - While React Native can access native functionalities via bridges, there may be limitations or additional work required to expose certain native features or third-party SDKs not supported out-of-the-box. + - The community provides numerous third-party libraries to help bridge gaps in functionality, but reliance on these can sometimes introduce complexity or maintenance issues. + +### Performance and Capabilities + +- **Native iOS Development**: + - Can achieve optimal performance and take full advantage of the latest iOS features and capabilities as soon as they are released by Apple. + - Offers more control over app size, performance optimization, and can more easily implement advanced animations or graphical effects. + +- **React Native and Expo Development**: + - Generally offers good performance for most applications, but high-performance or graphically intensive apps may not perform as well as their native counterparts. + - React Native apps might have a larger minimum app size due to the inclusion of JavaScript engines and the React Native framework itself. + +### Conclusion + +Choosing between native iOS development with Xcode and cross-platform development with React Native and Expo depends on various factors such as the project requirements, team expertise, and development timeline. Native development provides the best performance and user experience for iOS apps but requires more platform-specific knowledge. React Native and Expo offer a more flexible and efficient development process, especially for teams targeting multiple platforms or those with a background in JavaScript web development. + + +## Getting Started + +### Prerequisites + +- Node.js (LTS version) +- npm (Node Package Manager) or Yarn +- Expo CLI +- Code editor (e.g., Visual Studio Code) + +### Installation Steps + +1. **Install Node.js and npm**: Download and install the latest Long-Term Support (LTS) version of Node.js from [Node.js official website](https://nodejs.org/), which includes npm. + +2. **Install Expo CLI**: + Open your terminal and run the following command to install Expo CLI globally: + ``` + npm install -g expo-cli + ``` + +3. **Initialize a New React Native Project**: + Create a new project using Expo CLI by running: + ``` + expo init MyReactNativeApp + ``` + Follow the prompts to choose a template and configure your project. + +4. **Start the Development Server**: + Navigate into your project directory and start the development server: + ``` + cd MyReactNativeApp + expo start + ``` + This will start the Metro Bundler, which is the JavaScript bundler for React Native. + +5. **Preview Your Application**: + - **iOS Simulator**: Press `i` in the terminal or run `expo start --ios`. + - **Android Emulator**: Press `a` in the terminal or run `expo start --android`. + +6. **Developing Your App**: + Now that you have your development environment set up, you can start coding! Edit the `App.js` file and see the changes instantly on your simulator or device. + +7. **Building and Deploying**: + When you're ready to deploy your app to production, Expo provides commands to build standalone binaries for the App Store and Google Play. Run the following command for iOS: + ``` + expo build:ios + ``` + And for Android: + ``` + expo build:android + ``` + +## Conclusion + +This guide has introduced you to React Native and Expo, two powerful tools for developing iOS apps with JavaScript and React. By leveraging these technologies, you can significantly streamline the development process and create high-quality, native applications for both iOS and Android platforms. Happy coding! + +### References + +- React Native: [React Native Official Documentation](https://reactnative.dev/docs/getting-started) +- Expo: [Expo Official Documentation](https://docs.expo.dev/) +- Node.js: [Node.js Official Website](https://nodejs.org/) diff --git a/Topics/Tech_Stacks/Tiptap/Tiptap.md b/Topics/Tech_Stacks/Tiptap/Tiptap.md new file mode 100644 index 000000000..b23df9581 --- /dev/null +++ b/Topics/Tech_Stacks/Tiptap/Tiptap.md @@ -0,0 +1,360 @@ +# A Guide on using Tiptap in a React CRUD app. + +## What Is Tiptap + +Tiptap, one of the leading open-source dev tools for rich content editors is trusted by many companies like Substack, AxiosHQ, and GitLab.[^1] + +They have accumulated over 2 million downloads[^1] with their cool products such as Tiptap Content AI and Tiptap Collaboration. + + +![Untitled design (4)](https://github.com/AshkanAleshams/learning-software-engineering.github.io/assets/90326959/f56018c2-e7ef-478f-95d2-de19838cc1c7) + + +However, for this guide, we will focus on the Tiptap Editor. + +Tiptap Editor is a headless toolkit for building rich text WYSIWYG editors for Vue.js and React.js applications. Giving the user the complete freedom to fashion their own editor interface using customizable building blocks. +It offers sensible defaults, an extensive array of extensions, and an intuitive API for tailoring every facet to the user's preferences. + + + +## Why Use Tiptap + +If you are looking for a powerful text editor for web applications, Tiptap is a great option to consider. Being open-source and built on the well-regarded ProseMirror library,[^3] Tiptap offers a solid foundation. It features real-time collaboration and boasts a rich library of [community extensions](https://github.com/ueberdosis/awesome-tiptap#community-extensions) that includes an extension that enables Markdown support. Starting with Tiptap is easy thanks to its free tier, but for those needing advanced features like AI integration and document commenting, [paid plans](https://tiptap.dev/pricing) are available, making Tiptap a versatile solution for diverse project needs. + +## Relevant Links +For comprehensive resources related to Tiptap Editor, consider the following links: + +- **Tiptap Official Website**: Detailed information on features and how to get started with Tiptap. [Visit Tiptap](https://tiptap.dev) + +- **Documentation and Examples**: Access to extensive documentation and practical examples for using Tiptap. [Explore the docs](https://tiptap.dev/docs) and [View examples](https://tiptap.dev/examples) + +- **GitHub Repository**: The source code and contribution guidelines are available on GitHub. [Check out the repository](https://github.com/ueberdosis/tiptap) + +- **Guide and Tutorials on GitHub**: A detailed guide offering insights into configuring the editor, working with extensions, and more. [Read the guide](https://github.com/ueberdosis/tiptap/blob/main/docs/guide.md) + +- **Community Discussions**: Engage with the Tiptap community on GitHub for help and discussions. [Join the conversation](https://github.com/ueberdosis/tiptap/discussions) + + +## Requirements + +There are multiple methods to install Tiptap, each tailored to a specific use case. Detailed integration guides for different project types can be accessed [here](https://tiptap.dev/docs/editor/installation). In this article, we'll focus on creating a React project integrated with Tiptap, so you'll need Node.js and npm; if you don't have them installed, follow [this guide](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) to install them. + +## Intro to Tiptap in React + + + +**1. Create a project** + +You may use any other method of creating a React app if you wish, but +[Tiptap Create React App template by @alb](https://github.com/alb/cra-template-tiptap) is the quickest way. + +``` +npx create-react-app my-tiptap-project --template tiptap + +``` + +This will also install the dependencies for you! + + +**2. Run the project** + +Start your React application to see Tiptap in action. +``` +cd my-tiptap-project + +npm start +``` + +**3. Add a menu bar** + +Improve your editor by adding a menu bar to Tiptap.jsx. + +Each button in the menu bar example code below takes three arguments. Taking the bold button as an example: +- The [`onClick`](https://react.dev/learn/responding-to-events#adding-event-handlers) function makes the editor toggle any selected text between bolded and non-bolded modes. +- The [`disabled`](https://www.w3schools.com/tags/att_button_disabled.asp) argument determines whether the bold button should be faded out because the selected text cannot be bolded. +- The [`className`](https://legacy.reactjs.org/docs/faq-styling.html) is `is-active` or blank depending on whether the selected text is bolded. If the `is-active` `className` is present, the bold button in the menu bar will be emphasized. + +Here is the code sourced from [here](https://tiptap.dev/docs/editor/installation/react): + + + ```` + import { Color } from '@tiptap/extension-color' + import ListItem from '@tiptap/extension-list-item' + import TextStyle from '@tiptap/extension-text-style' + import { EditorProvider, useCurrentEditor } from '@tiptap/react' + import StarterKit from '@tiptap/starter-kit' + import React from 'react' + + const MenuBar = () => { + const { editor } = useCurrentEditor() + + if (!editor) { + return null + } + + return ( + <> + + + + + + + + + + + + ) + } + + const extensions = [ + Color.configure({ types: [TextStyle.name, ListItem.name] }), + TextStyle.configure({ types: [ListItem.name] }), + StarterKit.configure({ + bulletList: { + keepMarks: true, + keepAttributes: false, + }, + orderedList: { + keepMarks: true, + keepAttributes: false, + }, + }), + ] + + const content = ` +

+ Hi there, +

+

+ Isn’t that great? And all of that is editable. But wait, there’s more. Let’s try a code block: +

+
body {
+  display: none;
+  }
+

+ I know, I know, this is impressive. It’s only the tip of the iceberg though. Give it a try and click a little bit around. Don’t forget to check the other examples too. +

+ + ` + + export default function Tiptap () { + return ( + } extensions={extensions} content={content}> + ) + } + ```` + + + +**4. Install new dependencies** + +Install tiptap/extension-color and tiptap/extension-text-style packages. +``` +npm install @tiptap/extension-color @tiptap/extension-text-style +``` + +**5. Enjoy Your new editor** +``` +npm start +``` + +**6. Use the output from the editor** + +At the bottom of Tiptap.jsx, add an `onUpdate` prop to the EditorProvider, using the `getHTML()` and `getJSON()` method on the editor object to retrieve the HTML and JSON representations, respectively, of the content in the editor when the user changes it and print it to the browser's console. + ```javascript + export default function Tiptap () { + return ( + } extensions={extensions} content={content} onUpdate={({ editor }) => { + const json = editor.getJSON(); + const html = editor.getHTML(); + console.log(json); + console.log(html); + }}> + ) + } + ``` + +## Example with Markdown Editor in React + +By default, Tiptap doesn't support input from or output to Markdown files.[^4] However, there is a community-developed npm package called `tiptap-markdown` that extends Tiptap to enable this. We'll go through the installation of this package and the creation of a simple editor that uses it. + +**1. Install `tiptap-markdown`** + +We'll continue with the React project we created above. Install the [`tiptap-markdown`](https://www.npmjs.com/package/tiptap-markdown) package using npm: +``` +npm install tiptap-markdown +``` + +**2. Import the package** + +Make a copy of Tiptap.jsx called Markdown.jsx. Add this import to the top of the file: +``` +import { Markdown } from 'tiptap-markdown'; +``` + +**3. Edit the editor** + +In Markdown.jsx, add `Markdown` to the list of extensions used by the Tiptap editor. Since the input file format has changed from HTML to Markdown, we'll change the initial content as well: +```` +const extensions = [ + [...keep the existing extensions...] + Markdown, +] + +const content = ` +## Hi again, +Here is a Markdown version! +\`\`\`css +body { +display: none; +} +\`\`\` +` +```` + +**4. Render the new editor** + +At the top of App.js, import the new Markdown editor from Markdown.jsx: +``` +import Markdown from './Markdown'; +``` + +Finally, render the new Markdown editor below the existing editor in App.js: +``` +const App = () => { + return ( +
+ + +
+ ); +}; +``` + +**5. See both editors in action** +``` +npm start +``` + +**6. Use the output from the Markdown editor** + +At the bottom of Markdown.jsx, add an `onUpdate` prop to the EditorProvider, using the `getMarkdown()` method on the editor object to retrieve the Markdown representation of the content in the editor when the user changes it and print it to the browser's console. + ```javascript + export default function Tiptap () { + return ( + } extensions={extensions} content={content} onUpdate={({ editor }) => { + const new_markdown = editor.storage.markdown.getMarkdown(); + console.log(new_markdown); + }}> + ) + } + ``` + +![Untitled design (5)](https://github.com/AshkanAleshams/learning-software-engineering.github.io/assets/90326959/51e0072e-776b-41bb-9360-4307c56e45c5) + + +## Citations + +https://tiptap.dev/blog/insights/tiptap-seriesseed + +https://tiptap.dev/product/editor + +https://tiptap.dev/docs/editor/introduction + +https://tiptap.dev/docs/editor/installation/react + +https://github.com/alb/cra-template-tiptap + +https://tiptap.dev/product/editor + +https://tiptap.dev/docs/editor/guide/output + +[^1]: [Tiptap Seriesseed - Insights](https://tiptap.dev/blog/insights/tiptap-seriesseed) +[^2]: [Tiptap Editor - Product](https://tiptap.dev/product/editor) +[^3]: [Tiptap Editor - Introduction](https://tiptap.dev/docs/editor/introduction) +[^4]: [Tiptap Editor - Output](https://tiptap.dev/docs/editor/guide/output) diff --git a/Topics/Tech_Stacks/Unity UI Toolkit.md b/Topics/Tech_Stacks/Unity UI Toolkit.md new file mode 100644 index 000000000..5cff179f3 --- /dev/null +++ b/Topics/Tech_Stacks/Unity UI Toolkit.md @@ -0,0 +1,55 @@ +# Introduction to Unity UI Toolkit + +## Table of Contents +#### [Introduction](#introduction-1) +#### [Get Started](#get-started-1) +#### [UI Toolkit vs. Unity UI](#ui-toolkit-vs-unity-ui-1) +#### [Additional Resources](#additional-resources-1) + +## Introduction + +UI Toolkit is a collection of features, resources and tools for developing user interface(UI) in Unity. It offers toolkit to build not only UI for games and applications, but also extentions for Unity Editor and debugging tools. + +This tutorial assumes basic understanding of Unity(see [Introduction to Unity Basics](/Unity_Intro.md)), and some intuition about Unity UI(see [A Beginner's Guide for Unity UI Design](/Unity_UI.md)) + +In this tutorial, we will explain some basics of UI Toolkit, make sure you make the right choice between Unity UI and UI Toolkit for your next Unity project. + + +## Get Started + +Here we have a project completely fresh, the editor version is 2022.3.18f1 for your reference. + +Now we create a UIDocument object in the scene. Like a Canvas object in Unity UI, a UIDocument is what the scene refers to as a placeholder for UI that is going to be displayed on the screen. + +![Created UIDocument in Scene](Unity%20UI%20Toolkit/Created%20UIDocument%20in%20Scene.png) + +Then create a UIDocument in the assets folder. Despite the same name, this is the source asset, which is the actual contents of the UI. + +![Created UIDocument in Assets](Unity%20UI%20Toolkit/Created%20UIDocument%20in%20Assets.png) + +Remember to drag your UI contents into its placeholder in the inspectore. This will link them together so that the editor knows which UI to display in this scene. + +![Select Source Asset](Unity%20UI%20Toolkit/Select%20Source%20Asset.png) + +Double-click the UI contents in the assets folder. This is the UI Builder interface, where the entire interface is dedicated to adjust the details of the UI. + +![UI Builder](Unity%20UI%20Toolkit/UI%20Builder.png) + +If you want to know more about using UI Toolkit, see [Unity UI Toolkit Beginner's Guide](https://www.youtube.com/watch?v=0mYtI21Fmg4&list=PLgCVPIIZ3xL_FVLhDrC3atsy8CiZzAMh6) if you want to learn it thoroughly, or [Unity UI Toolkit in 5 Minutes](https://www.youtube.com/watch?v=yUXFHAOXhcA) if you already had much experience with Unity. + +## UI Toolkit vs. Unity UI + +So if you want to make your next Unity project, which option is the best? + +- If you want to make UI that is not just on the user's screen, choose Unity UI. For example, if you want to make a TV in game that broadcasts information on its screen, this is World Space UI, which can only be implemented by Unity UI exclusively. + +- If you are more familiar with the skillset of web development, chooose UI Toolkit. In UI Toolkit, you can style your UI with a Unity Style Sheet(USS), which is inspired by Cascading Style Sheets(CSS) from HTML. With the help of style sheets, you can easily style your UI in a fast and efficient way. + +These two criteria are some problems that new Unity users might encounter, see [Comparison of UI systems in Unity](https://docs.unity3d.com/Manual/UI-system-compare.html) for more in depth comparisons. + +## Additional Resources + +- [What about UI Toolkit?](https://www.youtube.com/watch?v=Wz3k6afpDv8) This video talks about the comparisons so far and the potential for UI toolkit. +- [My disappointment with Unity's UI Toolkit](https://mortoray.com/my-disappointment-with-unity-uitoolkit/) This article talks about the frustrations and limitations of UI Toolkit. +- [Unity UI Toolkit is better than expected](https://prographers.com/blog/unity-ui-toolkit-is-better-than-expected) This article talks about some coding benefits of UI Toolkit. +- [Can anyone do an ELI5 for what is going on with uGUI vs UI Toolkit and the documentation?](https://www.reddit.com/r/Unity3D/comments/13agbid/can_anyone_do_an_eli5_for_what_is_going_on_with/) This reddit post has some interesting discussion over the comparisons between Unity UI and UI Toolkit. \ No newline at end of file diff --git a/Topics/Tech_Stacks/Unity UI Toolkit/Created UIDocument in Assets.png b/Topics/Tech_Stacks/Unity UI Toolkit/Created UIDocument in Assets.png new file mode 100644 index 000000000..8f5aa0a1f Binary files /dev/null and b/Topics/Tech_Stacks/Unity UI Toolkit/Created UIDocument in Assets.png differ diff --git a/Topics/Tech_Stacks/Unity UI Toolkit/Created UIDocument in Scene.png b/Topics/Tech_Stacks/Unity UI Toolkit/Created UIDocument in Scene.png new file mode 100644 index 000000000..a9f6245b8 Binary files /dev/null and b/Topics/Tech_Stacks/Unity UI Toolkit/Created UIDocument in Scene.png differ diff --git a/Topics/Tech_Stacks/Unity UI Toolkit/Select Source Asset.png b/Topics/Tech_Stacks/Unity UI Toolkit/Select Source Asset.png new file mode 100644 index 000000000..0f31d7058 Binary files /dev/null and b/Topics/Tech_Stacks/Unity UI Toolkit/Select Source Asset.png differ diff --git a/Topics/Tech_Stacks/Unity UI Toolkit/UI Builder.png b/Topics/Tech_Stacks/Unity UI Toolkit/UI Builder.png new file mode 100644 index 000000000..e69d325e3 Binary files /dev/null and b/Topics/Tech_Stacks/Unity UI Toolkit/UI Builder.png differ diff --git a/Topics/Tech_Stacks/assets/action-artifacts.png b/Topics/Tech_Stacks/assets/action-artifacts.png new file mode 100644 index 000000000..875c19b81 Binary files /dev/null and b/Topics/Tech_Stacks/assets/action-artifacts.png differ diff --git a/Topics/Tech_Stacks/assets/action-steps.png b/Topics/Tech_Stacks/assets/action-steps.png new file mode 100644 index 000000000..3f1aaee47 Binary files /dev/null and b/Topics/Tech_Stacks/assets/action-steps.png differ diff --git a/Topics/Tech_Stacks/assets/actions-list.png b/Topics/Tech_Stacks/assets/actions-list.png new file mode 100644 index 000000000..c0d7f08cb Binary files /dev/null and b/Topics/Tech_Stacks/assets/actions-list.png differ diff --git a/Topics/Tech_Stacks/assets/actions-secrets.png b/Topics/Tech_Stacks/assets/actions-secrets.png new file mode 100644 index 000000000..1acb07f1f Binary files /dev/null and b/Topics/Tech_Stacks/assets/actions-secrets.png differ diff --git a/Topics/Tech_Stacks/build-android-app-using-github-actions.md b/Topics/Tech_Stacks/build-android-app-using-github-actions.md new file mode 100644 index 000000000..8401ef655 --- /dev/null +++ b/Topics/Tech_Stacks/build-android-app-using-github-actions.md @@ -0,0 +1,175 @@ +# Build an Android React Native App Using GitHub Actions + +So, you want to build an Android React Native app using GitHub Actions? I'm glad +you asked! In this short article we will go over step by step on how to build +your APK directly on GitHub. + +## Getting Started + +First, we will create a new Github Actions Workflow. A workflow is just a +[YAML](https://yaml.org/) file that contains tiggers for when certain jobs +(scripts) should run. + +Create the file `.github/workflows/build-frontend.yml` to begin specifying the +workflow. + +You should also add a name for the workflow at the top which will be visible in +the GitHub Actions tab. + +```yml +name: frontend-cd +``` + +![](./assets/actions-list.png) + +## Workflow Triggers + +Triggers define when your jobs will run. We will setup the workflow to build +whenever there is a push to main: + +```yml +on: + push: + paths: [ "Frontend/**" ] + branches: [ "main" ] +``` + +Furthermore, notice how I included the filter `paths: [ "Frontend/**" ]`, this +is important because it avoid running our build unnecessarily. For example, for +my case, I have both frontend and backend code in the same repo. Thus, having +this filter avoid building the frontend for backend pull requests. + +## Defining a Job + +### Setup Steps + +```yml +jobs: + cd: + runs-on: ubuntu-latest + + timeout-minutes: 20 + + steps: + + # Clone the repo on the target machine (ubuntu-latest) + - name: Checkout code + uses: actions/checkout@v4 + + # Installs Node.js + - name: Set up Node.js + uses: actions/setup-node@v4 + + # Installs your prjects dependencies as defined in your package.json file + - name: Install dependencies + working-directory: Frontend/DebrisMine + run: npm install + + # Install the Android SDK (for building the app) + - name: Setup Android SDK + uses: android-actions/setup-android@v2 + + # Install the Gradle build tool + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 +``` + +The schema here is fairly self explanatory. But for completeness, here we only +define one job (named `cd`). It runs on an Ubuntu machine, and the job times out +after 20 minutes (useful to avoid unexpected long builds). Notice how each step +has a name, this is the name that will be visible when the action is run: + +![](./assets/action-steps.png) + +### Build steps + +```yml + # Optional pre-build step + # Make sure to cd to your android folder though! + - name: Prebuild Android + working-directory: Frontend/DebrisMine + run: | + npx expo prebuild -p android --no-install + cd android && chmod +x ./gradlew + + # Building using gradle + - name: Build Android Release + working-directory: Frontend/DebrisMine + run: | + cd android && ./gradlew clean && ./gradlew app:assembleRelease +``` + +Since I use [expo](https://expo.dev/), I have a prebuild step before building +which generates the android folder for me. If you are not using expo, then +simply ommit this line `npx expo prebuild -p android --no-install`, and just cd +into the android folder which you should have pushed to your repo. + +### Signing steps + +All Android apps need to be signed for them to be trusted by your Android device +(and Google Play). + +```yml + # Sets the environment variable BUILD_TOOL_VERSION based on the installed + # Android SDK version (needed for next step). + - name: Setup build tool version variable + shell: bash + run: | + BUILD_TOOL_VERSION=$(ls /usr/local/lib/android/sdk/build-tools/ | tail -n 1) + echo "BUILD_TOOL_VERSION=$BUILD_TOOL_VERSION" >> $GITHUB_ENV + echo Last build tool version is: $BUILD_TOOL_VERSION + + # Sign the APK + - name: Sign APK + id: sign_app + uses: r0adkll/sign-android-release@v1 + with: + releaseDirectory: ${{ github.workspace }}/Frontend/DebrisMine/android/app/build/outputs/apk/release + signingKeyBase64: ${{ secrets.ANDROID_SIGNING_KEY }} + alias: ${{ secrets.ANDROID_SIGNING_ALIAS }} + keyStorePassword: ${{ secrets.ANDROID_SIGNING_STORE_PASSWORD }} + keyPassword: ${{ secrets.ANDROID_SIGNING_KEY_PASSWORD }} + env: + BUILD_TOOLS_VERSION: ${{ env.BUILD_TOOL_VERSION }} +``` + +To sign the APK you will need to add four secrets to your GitHub repo: +`ANDROID_SIGNING_KEY`, `ANDROID_SIGNING_ALIAS`, +`ANDROID_SIGNING_STORE_PASSWORD`, and `ANDROID_SIGNING_KEY_PASSWORD`. + +[Keytool](https://docs.oracle.com/javase/7/docs/technotes/tools/solaris/keytool.html) +comes installed with the JDK. You can create a key using Keytool from the +command line: `keytool -genkey -v -keystore my-release-key.keystore -alias +alias_name -keyalg RSA -keysize 2048 -validity 10000`. You can replace +alias_name with anything you'd like, but make sure to remember it, since it will +be the `ANDROID_SIGNING_ALIAS` secret. The command line tool will aslo ask for a +store password and a key password (make sure to remember it or note it down +somewhere). Finally, the `ANDROID_SIGNING_KEY` is simply the contents of the +generated file: `my-release-key.keystore`. + +![](./assets/actions-secrets.png) +You can add the secrets through the repo settings. + +### Upload step + +The app has been build but it's still "stuck" on the machine, we need to upload +it back to GitHub as an +[Artifact](https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts). + +```yml + - name: Upload APK Artifact + id: uploadArtifact + uses: actions/upload-artifact@v2 + with: + name: app + path: ${{steps.sign_app.outputs.signedReleaseFile}} +``` + +## Ending Notes + +Congrats! If all goes well, you should have automatic builds setup and ready! + +You should be able to download the signed APK file for every push to main from +the Artifacts sections of a run. + +![](./assets/action-artifacts.png) diff --git a/Topics/Tech_Stacks/materialui.md b/Topics/Tech_Stacks/materialui.md new file mode 100644 index 000000000..daa2368ad --- /dev/null +++ b/Topics/Tech_Stacks/materialui.md @@ -0,0 +1,83 @@ +# Material UI Guide + +## Introduction + +Material UI (MUI) is the most popular UI framework for React. + +It is an open-source library containing a large amount of components that can be seamlessly integrated into React applications to create a customizable user experience. MUI components are responsive, allowing for consistency across different screen sizes and platforms. + +## Installation + +Since MUI is a framework for React, ensure that dependencies `react` and `react-dom` are installed. They can be installed with `npm install react` and `npm install react-dom` respectively. + +To install MUI using npm, run the console command `npm install @mui/material @emotion/react @emotion/styled` + +To install with yarn, run `yarn add @mui/material @emotion/react @emotion/styled` + +## Importing Components + +Material UI components can be imported individually. For example, a `Button` component can be added to a .jsx file with the following: + +```js +import Button from '@mui/material/Button'; +``` + +Multiple components can be imported like this: + +```js +import { + Box, + Button, + Grid, +} from '@mui/material'; +``` + +## Adding Components + +MUI components are utilized in a similar way to HTML in React JSX, with its own unique tags. MUI components are diffentiated from HTML with their capitalized tag names. Some components have variants that affect their styling. + +```js +export default function ButtonUsage() { + return ; +} +``` + +## Styling Components + +The styling of a component can be changed in serveral ways: + +### One-off customization + +To style one instance of a component, you can use the sx prop: + +```js + +``` + +### Reusable component + +Using the `styled()` utility, you can create a reusable component which appears consistently across the application: + +```js +import * as React from 'react'; +import Slider from '@mui/material/Slider'; +import { styled } from '@mui/material/styles'; + +const HelloWorldButton = styled(Button)({ + color: '#76ABAE' +}); + +export default function StyledCustomization() { + return Hello world; +} +``` + +## Mobile Rendering + +Material UI components are primarily developed for mobile devices, which are then scaled up for larger viewports. It is highly recommended to add the viewport meta tag, which ensures proper rendering and touch zooming for all devices. + +`` + +## References + +For a detailed introductory guide to Material UI with usage examples, visit https://mui.com/material-ui/getting-started/ \ No newline at end of file diff --git a/Topics/Tech_Stacks/p5.md b/Topics/Tech_Stacks/p5.md index 6a8b72605..f56f12d8f 100644 --- a/Topics/Tech_Stacks/p5.md +++ b/Topics/Tech_Stacks/p5.md @@ -7,6 +7,34 @@ ## Introduction +p5.js is an innovative and creative coding library published for JavaScript that enables the users to facilitate the process of creating +innovative visuals, apply visual arts easily and sketch with its pre-fixed codes that contains tools, drawing functionalities and other +software to make design of visuals simpler. + +p5.js is not an emulation or port, still in active development; it’s additional libraries makes it easier and efficient to implement images, videos, sounds, text, and HTML5 objects. p5.js uses HTML, CSS, and JavaScript - similar to almost all webprojects. + +It eases the process of sketching and creating visuals with the functionalities pre-set by the library and thus simplifies it. p5.js can be thought of as a software sketchbook similar to the ‘Preprocessing’, where p5.js is a translation of ‘Preprocessing’ software. + + +### Usage of p5.js + +p5.js is a free and open-source Javascript library. Anyone who is interested in implementing creative visuals, or including sketches or graphical visuals on their software can use this library. Users can either create a project focused fully on the creative visuals or support their existing project with the visuals designs with the support of the p5.js library. + +p5.js is also beginner-friendly. With its easy guides and tutorials everyone can learn how to use the p5.js library on their code. + +p5.js can be used for educational purposes as well, since it is easy to use, it makes educating easier also (especially for subjects involving mathematics such as geometry - since p5.js includes features to easily create geometric objects and coordinate systems, lines and geometric objects on the coordinate systems). + +p5.js users can utilize various options to enhance their coding project such as creating and setting up canvases, designing geometric shapes and coordinate systems with various color options : represented in various ways such as RGB, RGBA, gray value, hexadecimal , and HSBA. + +p5.js users can either use the p5.js editor published from the official website of p5.js or can use their own desktop (if selected to use on personal desktop, have to first download the library to the desktop - following the download instructions). + +p5.js users can include graphics, geometric motifs and shapes, and coordinate systems on their canvases - or even use a coordinate system as a canvas - which eases users to apply mathematical concepts and geometrical representations of images throughout their project. + +p5.js users can include features that are responsive to mouse movements and mouse touches : whether the mouse is dragged, pressed, released, clicked or scrolled. + +p5.js users can draw canvases with default functions set-up or load the canvas environment that the user wants to work on, to enhance the project that they are working on; with its easy to build set-up features users can create their canvases easily and time efficiently. + + ## Getting Started p5.js offers mainly 2 ways to use the library. User can either use the p5.js web editor provided by the library's official website or locally set p5.js to work on their desktop. diff --git a/Topics/Tech_Stacks/sorbet_for_ruby.md b/Topics/Tech_Stacks/sorbet_for_ruby.md new file mode 100644 index 000000000..909e923f6 --- /dev/null +++ b/Topics/Tech_Stacks/sorbet_for_ruby.md @@ -0,0 +1,91 @@ +# Pros and Cons of Sorbet for Ruby + +## Introduction +Languages like JavaScript, Python, and Ruby are powerful in the fact they offer dynamic typing, which eases the speed of development. Dynamically typed languages offer no type checking, and allows for some interesting lines of code such as referencing non-existent variables and changing the type of a variable on the fly. In recent years however, there has been a trend of adding a type system on top of dynamically typed languages; Sorbet adds a type system on top of Ruby. Originally developped by Stripe Inc. Sorbet is used at a number of large companies such as Shopify, InstaCart, and CoinBase to name a few. + +Below is an example of a simple function with and without Sorbet. + +Without Sorbet: +````{verbatim, lang="markdown"} +def sayHello(name) + puts "Hello, #{name}!" +end + +sayHello("Sorbet") # ok! +sayHello() # error at run time +sayHelo("") # error at runtime +```` + +With Sorbet: +````{verbatim, lang="markdown"} +# typed: true +extend T::Sig + +sig {params(name: String).returns(NilClass)} +def sayHello(name) + puts "Hello, #{name}!" +end + +sayHello("Sorbet") # ok! +sayHello() # error: Not enough arguments provided +sayHelo("") # error: Method `sayHelo` does not exist +```` + +## Pros +* Strict typing provided for an otherwise dynamically typed languageFurthermore +* Enhanced readability for both the outhor, as well as reviewers +* Engineers know exactly what type every method inputs and outputs, where errors are thrown if types used are invalid +* errors that would normally be caught at run time in these dynamic languaes are caught before hand +* Sorbet is backwards compatible with regular Ruby code + +## Cons +* Adding a type system to a dynamic language avoids the advantages of a dynamically typed language +* Type gymnastics to make the compiler happy about the type you used or are trying to define. + +Here's an example of type gymnastics in TypeScript, that occur when trying to define a type for url parameters of an api call using ````fetch()````: +````{verbatim, lang = "markdown"} +type params = string | URLSearchParams | string[][] | Record | undefined | null +```` + +* Code bloat, sometimes adding the Sorbet type system ends up adding a lot of extra boilerplate + +The code for a static language like Java is concise and readable +````{verbatim, lang = "markdown"} +public class SumFunction { + + public static int sum(int a, int b) { + return a + b; + } + +} +```` + +But Sorbet adds a lot of extra lines which aren't necessarily improving readability +````{verbatim, lang = "markdown"} +# typed: true +class SumFunction + + extend T::Sig + + sig {params(x: Integer, y: Integer).returns(Integer)} + + def sum(x, y) + return x + y + end +end +```` + +* Using dependencies is difficult, most dependencies don't have types defined which means you have to define your own types for external dependencies + +## Is Sorbet right for me? + +As I'm sure you can imagine, the answer to this question is, it depends. The advantages of Ruby on Rails is the fact it's a batteries included framework; everything is pretty much ready to go once you've initialized your project. This allows an engineer to develop their app very quickly, with scalability already accounted for. However, adding strict typing to Ruby on Rails will ultimately slow down one's development process, foregoing the advantages of a framework like Rails. If your project is intended to remain small, there's not really a reason to add Sorbet on top, there will be a manageable amount of code so the error tracing advantages aren't as drastic and you shorten the amount of time to a minimum viable product. If you plan on creating a monolith, Sorbet is definitely advantageous. The development timeline on a monolith is more stretched out so engineers can afford to spend a bit of time using Sorbet in order to avoid run time errors in the future (although this might result in some seriopus tech debt!). + +You can try Sorbet at https://sorbet.run/ + +## Sources: +https://sorbet.org/ +https://world.hey.com/dhh/turbo-8-is-dropping-typescript-70165c01 +https://youtube.com/watch?v=5ChkQKUzDCs +https://www.youtube.com/watch?v=zQnBQ4tB3ZA +https://betterprogramming.pub/why-i-stopped-using-sorbet-in-all-my-ruby-projects-9366bf6dd116 diff --git a/Topics/User_Experience.md b/Topics/User_Experience.md index 221c07925..1d842b770 100644 --- a/Topics/User_Experience.md +++ b/Topics/User_Experience.md @@ -10,6 +10,7 @@ - [User Experience Principles](https://learning-software-engineering.github.io/Topics/User_Experience.html#user-experience-principles) - [Site mapping, Wireframing, and Prototyping](https://learning-software-engineering.github.io/Topics/User_Experience.html#site-mapping-wireframing-and-prototyping) - [Accessibility](https://learning-software-engineering.github.io/Topics/User_Experience.html#accessibility) + - [Usability Testing](https://learning-software-engineering.github.io/Topics/User_Experience.html#usability-testing) 3. [Helpful Courses](https://learning-software-engineering.github.io/Topics/User_Experience.html#helpful-courses) 4. [Tools Used in User Experience Design](https://learning-software-engineering.github.io/Topics/User_Experience.html#tools-used-in-user-experience-design) - [Design Tools](https://learning-software-engineering.github.io/Topics/User_Experience.html#design-tools) @@ -312,6 +313,9 @@ Here are some questions that you can ask yourself when trying to make you work m - [What is Accessibility?](https://www.interaction-design.org/literature/topics/accessibility) by Interaction Design Foundation +## Usability Testing +[Usability Testing](/Topics/User_Experience/Usability_Testing.md) + # Helpful Courses - [The Design of Interactive Computational Media (CSC318) offered by U of T](https://artsci.calendar.utoronto.ca/course/csc318h1). CSC318 expands on the work done before coding projects. For example, the course will have you test how users would interact with your prototype of a UI and then modify it so that the UX is better for the user. diff --git a/Topics/User_Experience/Usability_Testing.md b/Topics/User_Experience/Usability_Testing.md new file mode 100644 index 000000000..4067ffd73 --- /dev/null +++ b/Topics/User_Experience/Usability_Testing.md @@ -0,0 +1,152 @@ +# Usability Testing +## Table of Contents +- [Introduction](#introduction) +- [Importance of Usability Testing](#importance-of-usability-testing) +- [How It's Done](#how-its-done) +- [Methods](#methods) +- [Data Collection](#data-collection) +- [Misconception](#misconception) +- [References](#references) +## Introduction +Usability is a procedure that takes place during the evaluation phase of the design process for testing the functionality of a system, website, or app – basically any digital product – by observing the interaction performed by a real user from the product’s stakeholder group. + +The goal of the usability test is to assess the completion of the current product and find potential room for correction and improvement. These involve any ambiguities in instructions, oversights in addressing user’s needs, inefficiencies, and more. + +## Importance of Usability Testing + +Usability testing matters in the software development process as a foundational tool for ensuring digital product quality and effectiveness. Evaluating user interactions with interfaces enables developers to refine design, functionality, and user experience, resulting in intuitive, user-friendly products aligned with user needs. Additionally, by addressing usability issues early, usability testing mitigates risks, cuts development costs, and boosts overall user satisfaction, playing a crucial role in product success amidst market competition. + +**It validate** + +The usability test helps us validate the prototype, experience map, or any mock-up previously created to envision the experience. It confirms whether the product aligns with the expectation and ensures the workflow is clear and straightforward. It brings user-centric insight: + +**It brings user-centric insights** + +Since usability testing involves the participation of real stakeholders, it is very likely to uncover issues unseen by the team that built the system. This is especially true when the team isn’t necessarily the stakeholders of the product. Having the real user interact with the product is an opportunity to observe how well our product satisfies the user’s need, fits into the user’s working habits, and is to the user’s preferences. From a third-person view, we can hear from the users, learn more about our users, and observe how our product resonates with users to create greater human empathy. It makes sure that the product we built is an actual working product liked by the users. + + +**It catches neglection** + +Usability testing helps us uncover any incomplete or missing components, features, and transitions in the flow of the entire product, which might otherwise go unnoticed when we operate directly on the product. This oversight can occur because our prolonged exposure to the system can numb us to the subtle nuances that significantly impact user experience, making it challenging to recognize deficiencies or areas for improvement without the fresh perspective that usability testing provides. + + + +## How it's Done +The usability test has three aspects: the facilitator (or research), the participants, and the tasks. The facilitator asks the participants to perform tasks and observe their performance in a realistic setting. + +![Usability Test Flowchart](/Topics/User_Experience/Usability_Testing_Images/usability_test_flowchart.png) + +### The Facilitator + +The facilitator is the one who usually knows the product, and is responsible for giving instructions, observing and documenting reactions, providing responses, and asking follow-up questions to the participant. When the task is conducted, the facilitator asks participants to perform tasks as specified. The participants usually practice the method of "think aloud," by verbally communicating their thinking process for better capture of the narrative from the user side, including detailed non-observable reactions/responses from the user. + +### The Tasks +The tasks asked to perform during the test must be realistic, meaning that they should be activities that real users intend to exercise regularly with the product and can be completed in a reasonable time frame. They should be structured to target the end question that the test or product wishes to resolve. + +The tasks given should be consistent across the participant group; however, they can be designed to target specific user groups the stakeholder comes from if different stakeholder groups might use the product differently (for instance, the student and teacher end of Quercus). The instructions given for each task should be clear and decisive. It should be carefully phrased to communicate the correct intention, as misunderstanding the task may heavily influence the outcome. Also, be aware that the instructions should not be step-by-step, as that defeats the purpose of observing the user's perception of the product. The instruction is not about "how to do", but rather about "what to do". + +> Poor task (not clear enough): Set an alarm. + +> Good task: Make a non-repeated alarm for 9AM tomorrow morning with label "Alarm" + +> Poor task (too detailed): Click on the alarm button, then click on the create alarm button. On the next page, change the time to ... + +### The Participants +Participants are also a vital component of the test. We need to ensure that the participants recruited are representative of the target user groups and cover various types of users (of different backgrounds, experiences, stakeholder groups, etc.) + +To learn more about particpants recruitment for userbility test, check out the following [article](https://www.usability.gov/how-to-and-tools/methods/recruiting-usability-test-participants.html). + + +## Methods +There are several ways a usability test can be conducted. You may choose one that fits the best for the team based on your needs and resources. Regardless of the method, it is encouraged to keep documentation of the process either in words, audio recording, or view recording for the possibility of revisiting in the future for retrospective examination. + +- Lab Usability Test + + In-person moderated tests happened in a lab-like setting. This method provides good control over the test as conditions are standardized, but comes with a high manual cost. This method is often best suited for smaller populations (8-10). + +- Phone Interview + + Done remotely over phone calls, where instructions and responses are given based on oral communication, hence is a missing observation over qualitative data, as some of these are often tied to participants' sentiments and non-verbal communication. This method is economical and far-reaching, therefore fitting well when gathering data from a larger population. + +- Session Recording + + Remote moderated test that combines strength from both phone interviewing and lab testing. + +View article on this link to learn more about [populat usability testing methods](https://www.playbookux.com/10-popular-usability-testing-methods/). + +## Data Collection + +Data collection will be done during the test without disruting the participant's task. The recorded observation should be accurate, comprehensive, and detail enough to address the end problem of the study. There are several types of data that can be collected during a test like this. + +- Quantitative + + *Metrics that describe user experience* + + These often include information such as the time taken to complete a task, the success rate, and the error rate. These data are great for evaluating efficiency and effectiveness, as well as major functionality errors. + +- Qualitative + + *insights, anecdotes, emotions, and responses expressed by the participants* + + They uncover important information about the overall user experience with emphasis on the user’s empathy and satisfactory values which are commonly hard to quantize. + +- Subjective + + *Directly communicated by the particpants, either during the test or follow up questions time* + +- Objective + + *Observation and from the facilitator* + + +Another way to break down the data collected is by categorizing the observations to address specific components/reqruiements of the products' usability. + +One good way to do this is to rely on the definition usability. E.g. +![Definition of Usability](/Topics/User_Experience/Usability_Testing_Images/usability.png) + +You could also complete this using the [Nielsen's 10 Heuristics for Usability](/Topics/User_Experience/Usability_Heuristics.md). + +## Misconception + +1. Usability Testing vs. User Testing + + Usability testing and user testing both aim to assess the user experience, including interaction with the product and emotional aspects. However, user testing focuses on user perception and feedback, while usability testing concentrates more on functional performance, identifying bugs, and task efficiency. Usability testing is a subset of user testing, focusing specifically on the functionality and navigational aspects of the product. + +2. Usability Testing vs. A/B Testing + + Usability testing evaluates user experience through observation, focusing on functionality and navigation. A/B testing compares variations of a product to optimize performance metrics like conversions. While usability testing uncovers usability issues qualitatively, A/B testing uses quantitative data to optimize design elements. + +3. Usability Testing vs. Demo + + Usability testing goes beyond a mere demonstration. Unlike a demo, which showcases features in a controlled environment, usability testing assesses how real users interact with a product to identify potential issues and gather feedback. It provides insights into the productand allows iterative improvements based on real-world usage scenarios. Therefore, usability testing is a vital step in ensuring that products meet user needs and expectations, going beyond the surface-level demonstration to uncover actionable insights for enhancement. + + +## References +1. https://www.hotjar.com/usability-testing/ + +2. https://www.hotjar.com/usability-testing/methods/ + +3. https://www.nngroup.com/articles/usability-testing-101 + +4. https://www.usability.gov/how-to-and-tools/methods/recruiting-usability-test-participants.html + +5. https://www.researchgate.net/profile/Mehmet-Gokturk-2/publication/264850409/figure/tbl1/AS:1078642784382981@1634179888840/Usability-according-to-ISO-9241-11-Schneiderman-and-Nielsen.png + + + + + + + + + + + + + + + + + + + diff --git a/Topics/User_Experience/Usability_Testing_Images/usability.png b/Topics/User_Experience/Usability_Testing_Images/usability.png new file mode 100644 index 000000000..a5336eaea Binary files /dev/null and b/Topics/User_Experience/Usability_Testing_Images/usability.png differ diff --git a/Topics/User_Experience/Usability_Testing_Images/usability_test_flowchart.png b/Topics/User_Experience/Usability_Testing_Images/usability_test_flowchart.png new file mode 100644 index 000000000..28c860b6a Binary files /dev/null and b/Topics/User_Experience/Usability_Testing_Images/usability_test_flowchart.png differ