Category: Python

  • Python App Development: Build Modern GUIs PyQt GUI Development: Building Interactive Applications

    Python App Development: Build Modern GUIs PyQt GUI Development: Building Interactive Applications

    The provided text offers a comprehensive guide to building graphical user interface (GUI) applications using the PyQt framework in Python. It begins by introducing fundamental PyQt concepts like widgets, layouts (rows, columns, grids), and the framework’s modular structure. The text then progresses through building several example applications, including a random word generator, a functional calculator, an interactive photo editor leveraging the PIL library, and an expense tracker integrating SQLite databases. Each project incrementally introduces new PyQt widgets, layout management techniques, event handling, and external Python libraries. Furthermore, the material covers styling applications using CSS and explores more advanced features like data visualization with Matplotlib and implementing a dark mode. The overarching goal is to equip learners with the skills to design and develop interactive desktop applications using Python and PyQt.

    Python GUI Application Development Study Guide

    Quiz

    1. What is PyQt and what problem does it solve? PyQt is a Python binding for the Qt framework, a comprehensive C++ framework. It allows Python developers to create graphical user interfaces (GUIs) and access other features of Qt, such as database management and networking, using Python’s syntax.
    2. Name three of the five interactive applications that the course aims to build. The course aims to build a starter app, a calculator app, an expense tracker, an image editor (PhotoQT), and an interest rate calculator.
    3. Why is project-based learning emphasized in this course? Project-based learning is emphasized because it allows learners to build their skills in a way that keeps them engaged and provides a tangible final product. It also challenges learners to apply their knowledge in practical scenarios.
    4. What are widgets in the context of PyQt applications? Give two examples. Widgets are pre-built GUI elements that users see and interact with on an application screen. Examples of widgets include buttons (QPushButtons), text input boxes (QLineEdit), and labels (QLabel).
    5. What is the purpose of layouts in PyQt, and name one type of layout discussed? Layouts in PyQt are used to manage the arrangement and sizing of widgets within an application’s window, ensuring a consistent and responsive design. One type of layout discussed is the QGridLayout, which arranges widgets in a grid of rows and columns.
    6. Briefly explain the role of SQL in one of the course projects. In the expense tracker project, SQL is introduced to create and manage a database for storing financial transactions. PyQt is used to build the interface that interacts with this SQL database, allowing users to add, view, and delete expenses.
    7. What is Matplotlib, and what is its primary use in the context of this course? Matplotlib is a Python library used for data visualization. In this course, it is used in the interest rate calculator project to generate charts and graphs, providing a visual representation of the calculated interest over time.
    8. What is the purpose of the eval() function in the calculator app, and what potential issue does the try-except block address when using it? The eval() function in the calculator app is used to evaluate the mathematical expressions entered by the user as strings. The try-except block addresses the potential issue of errors that might occur if the user enters an invalid expression (e.g., dividing by zero), preventing the application from crashing and displaying an “error” message instead.
    9. Explain the concept of “events” in PyQt and how they are typically handled. Events in PyQt are signals that are emitted when something happens within the application, such as a button click or a mouse movement. They are typically handled by connecting a specific signal (e.g., clicked) of a widget to a function (a “slot”) that will be executed when that event occurs.
    10. What is the purpose of CSS (Cascading Style Sheets) in the context of PyQt applications? CSS in PyQt is used to style the visual appearance of application widgets, allowing developers to control aspects such as fonts, colors, backgrounds, and spacing. PyQt provides the setStyleSheet() method to apply CSS rules to widgets.

    Essay Format Questions

    1. Discuss the advantages of using a framework like PyQt for developing desktop applications with Python compared to more basic GUI libraries. Consider factors such as functionality, cross-platform compatibility, and development workflow.
    2. Explain how the five different application projects in the course progressively build upon fundamental Python and PyQt concepts. Highlight specific technologies and skills introduced in each project and how they relate to the overall goal of building interactive desktop applications.
    3. Describe the role of data persistence in application development, and analyze how SQL is used in the expense tracker project to achieve this. Discuss the basic SQL operations demonstrated and their significance for managing application data.
    4. Evaluate the benefits of incorporating data visualization using Matplotlib in a desktop application. Using the interest rate calculator as an example, explain how visualizing data can enhance user understanding and interaction with the application.
    5. Compare and contrast the different methods of styling PyQt applications demonstrated in the course, including widget-specific methods, CSS stylesheets, and the potential for implementing features like dark mode. Discuss the flexibility and control offered by each approach.

    Glossary of Key Terms

    • GUI (Graphical User Interface): A type of user interface that allows users to interact with electronic devices through visual indicator representations (icons, menus) rather than text-based commands.
    • Framework: A reusable body of code that provides a skeletal structure for building applications. It often includes libraries, tools, and design patterns.
    • PyQt: A Python binding for the Qt framework, enabling Python developers to create cross-platform GUI applications.
    • Widget: A basic building block of a GUI, such as buttons, labels, text boxes, etc., that users interact with.
    • Layout: In GUI development, a mechanism to organize and manage the size and position of widgets within a window.
    • Signal and Slot: A mechanism in Qt (and PyQt) for inter-object communication. A signal is emitted by an object when a particular event occurs, and a slot is a function that can be connected to a signal to be executed when the signal is emitted.
    • SQL (Structured Query Language): A standard programming language used for managing and manipulating relational databases.
    • Database: An organized collection of structured information, or data, typically stored electronically in a computer system.
    • Matplotlib: A comprehensive library in Python for creating static, interactive, and animated visualizations in Python.
    • Data Visualization: The graphical representation of information and data. By using visual elements like charts, graphs, and maps, data visualization tools provide an accessible way to see and understand trends, outliers, and patterns in data.
    • CSS (Cascading Style Sheets): A stylesheet language used to describe the presentation of a document written in a markup language like HTML. In PyQt, it can be used to style the appearance of widgets.
    • Event: An action or occurrence recognized by software, often originating asynchronously from the external environment, that may be handled by the software. Examples include button clicks, mouse movements, and key presses.
    • IDE (Integrated Development Environment): A software application that provides comprehensive facilities to computer programmers for software development. VS Code (Visual Studio Code) is an example used in the course.
    • Library (in programming): A collection of pre-written code that users can incorporate into their programs to perform specific tasks, saving development time and effort.
    • Cross-Platform Compatibility: The ability of software to run on different operating systems (e.g., Windows, macOS, Linux) without requiring significant modifications.
    • Module (in Python): A file containing Python definitions and statements. Libraries are often composed of multiple modules.
    • pip (Package Installer for Python): A package management system used to install and manage software packages written in Python.
    • Object (in programming): An instance of a class, which can contain data (attributes or properties) and code (methods or functions).
    • Class (in programming): A blueprint for creating objects. It defines the attributes and methods that objects of that class will have.
    • Method (in programming): A function that is associated with an object and can operate on the object’s data.

    Briefing Document: Review of Python GUI Course Sources

    Date: October 26, 2023 Prepared For: Interested Learners Prepared By: Gemini AI Assistant Subject: Detailed Review of “Building Desktop Applications with Python” Course Materials

    This briefing document provides a detailed review of the main themes, important ideas, and facts presented in the provided excerpts from the “Building Desktop Applications with Python” course materials (referred to as “01.pdf”). The course aims to empower individuals with existing Python skills to develop interactive desktop applications using graphical user interfaces (GUIs).

    Main Themes:

    • Transitioning Python Skills to GUI Development: The core theme is to elevate existing Python knowledge by introducing the concepts and tools necessary for building desktop applications with user-friendly interfaces. The instructor emphasizes moving beyond command-line scripts to create interactive and visually appealing applications.
    • Project-Based Learning: The course adopts a hands-on, project-based approach. Learners will build five distinct interactive applications throughout the 7-hour duration, reinforcing theoretical concepts with practical implementation. This allows learners to see tangible results and continuously build upon their skills.
    • Introduction to Key Python GUI Technologies: The course focuses on core technologies within the Python ecosystem for GUI development. The primary framework highlighted is PyQt (specifically PyQt5), a powerful and widely used library that bridges the C++ Qt framework with Python. Additionally, the course introduces SQL for database management and Matplotlib for data visualization within the applications.
    • Step-by-Step Learning and Practical Application: The instructor emphasizes breaking down complex tasks into easily understandable topics, catering to programmers of all levels. The focus is on learning by doing, with learners actively coding and designing the applications. The course structure explicitly outlines the progression from basic PyQt concepts to more advanced features like database integration and data visualization.
    • Free and Accessible Learning: The course is hosted for free on the instructor’s platform, encouraging accessibility for a wider audience. The instructor emphasizes community engagement and provides additional free resources on their platform.

    Most Important Ideas and Facts:

    Course Overview and Structure:

    • The course is a “project-based course” designed to challenge learners and provide a final product.
    • “our initial overview is you can expect a project-based course as this allows you to build your skills in a way that keeps you going but also challenges you and you can see a final product”
    • It aims to build a “strong foundation in the fundamental concepts of building apps in Python with pqt” while leveraging existing Python skills.
    • The course will cover setting up PyQt projects, creating app widgets, designing GUIs, and adding functionality.
    • Key PyQt concepts to be covered include “pqt widgets how we can create custom widgets how we can style our widgets and using buttons and labels within our programs.”
    • The curriculum progresses from basic PyQt application creation and layout management to integrating “SQL to create databases in pqt” and finally “data visualization with a module called matap plot lip.”
    • Learners will work through five projects: a starter app, a calculator app, an expense tracker, an image editor (“photo QT”), and an interest rate calculator.
    • The course is designed for “programmers of all levels,” those looking to grow their Python portfolio, project-based learners, and visual learners.
    • Access to “all my slides live coding projects and more” will be provided.

    Software Setup and Libraries:

    • The course utilizes Visual Studio Code (VS Code) as the Integrated Development Environment (IDE).
    • The recommended Python extension for VS Code is simply “Python.”
    • The instructor uses the “synth wave 84” theme in VS Code, which learners can optionally adopt for visual consistency.
    • Three primary Python libraries will be used throughout the course:
    • PyQt5: For building the graphical user interfaces.
    • “we are going to be using pqt”
    • Pillow: Likely for image manipulation within the image editor application.
    • “we are going to be using pillow”
    • Matplotlib: For creating charts and graphs in the interest rate calculator.
    • “we are going to be using Matt plot lib”
    • Instructions are provided for installing these libraries using pip3 install <library_name> or python3 -m pip install <library_name>.

    Introduction to PyQt:

    • PyQt acts as a “module that Bridges it it connects a popular framework in C++ and python,” allowing developers to use the Qt framework in Python.
    • It enables the creation of “graphical user interfaces” (GUIs).
    • PyQt offers capabilities beyond just visual elements, including “creating data bases with SQL or adding in embedded web browsers.”
    • A “widget is what you see on the app screen,” representing individual GUI elements like buttons and text inputs.
    • “a widget is what you see on the app screen”
    • The course will focus on PyQt5, with the explanation that it is very similar to PyQt6, and knowledge of PyQt5 provides compatibility with a wider range of applications.
    • “there is no major difference between these two in this course we will specifically focus on pi qt5 as these two versions the framework are so similar”
    • Reasons for choosing PyQt include:
    • Cross-platform compatibility: Apps can run on Windows, macOS, and Linux.
    • “pqt allows for crossplatform compatibility so it allows our apps to be run on different operating systems”
    • Endless widgets: Provides a wide variety of pre-built GUI elements.
    • “it also provides endless widgets… pqt provides these ready-made or pre-built GUI elements”
    • Wide range of components: Beyond basic widgets, it includes support for databases, graphics, and networking.
    • QT Designer: A visual tool for building GUIs (although the course will focus on programmatic creation).
    • “QT designer makes it significantly easier to build a pi QT app it’s kind of like figma or canva for building with pqt we won’t be addressing that in this course because that’s not programming that’s not coding that’s not learning the logic”
    • Python-based: Leveraging Python’s easier syntax.
    • “pqt is based in Python py right we are bridging it and connecting it to python which makes it very straightforward to us as python is an easier language and has easier syntax to understand”

    Window Applications and Layouts:

    • PyQt is designed to create “window applications,” which are standalone programs with their own windows.
    • “pqt is made to create these window applications”
    • A window application consists of a “main window” that acts as a container for “app Widgets or objects.”
    • “we have a main window and inside this main window we have app Widgets or objects”
    • Widgets are GUI elements like “text input box a checkbox text push buttons a list.”
    • “Layouts” in PyQt are used to structure and organize the widgets within the application window.
    • “We use layouts in pi QT to build out our design”
    • Examples of layouts include rows and columns, and PyQt provides layout classes to implement these designs.
    • Widgets are added to layouts by specifying their row and column position in a grid-based system (starting from index 0).

    Calculator App Development (Initial Stages):

    • The initial design of the calculator app aims for a layout with a text input area (using QLineEdit) at the top and a grid of buttons below (using QPushButton).
    • PyQt widgets to be used include QApplication, QWidget, QLineEdit, QPushButton, QHBoxLayout, QVBoxLayout, and QGridLayout.
    • The basic template for a PyQt application involves creating a QApplication instance, a main window (QWidget), setting its title and initial size, showing the main window, and executing the application.
    • Repetitive button creation can be handled efficiently using loops in Python.
    • “Loops what are the two types of Loops you know in Python the while loop and the for Loop. The four Loop is used to iterate to go through something else. Let me propose that we actually Loop through to create our grid”
    • A list of button labels can be iterated through to create QPushButton objects and add them to the QGridLayout.
    • Counter variables can be used within loops to manage the row and column placement of buttons in the grid.

    Next Steps (Implied):

    The excerpts lay the groundwork for building interactive desktop applications with Python and PyQt. The subsequent parts of the course will likely delve into:

    • Implementing functionality for the calculator app (button clicks, calculations).
    • Developing the image editor (image loading, editing operations using Pillow).
    • Building the expense tracker (database creation with SQL, data entry, and display).
    • Creating the interest rate calculator (data visualization using Matplotlib).
    • Styling the applications using CSS within PyQt.

    This briefing document highlights the key information presented in the initial course materials, setting the stage for learners to embark on their journey of building desktop applications with Python GUIs.

    Python Desktop Apps: PyQt GUI Development

    Frequently Asked Questions about Building Desktop Applications with Python

    1. What will I learn in this Python GUI course? This course will guide you through building five interactive desktop applications using Python. You’ll learn to create graphical user interfaces (GUIs) using the PyQt framework, work with databases using SQL, and perform data visualization with Matplotlib. The course covers fundamental concepts of building Python apps with PyQt, including setting up projects, creating and designing widgets, implementing application functionality, styling with CSS, and more.

    2. Who is this course designed for? This course is designed for programmers of all levels who want to elevate their Python skills and learn how to build desktop applications with graphical user interfaces. It’s particularly beneficial for those looking to expand their Python portfolio, visual learners, and individuals who appreciate complex tasks broken down into easily understandable concepts. Basic Python understanding is recommended as PyQt is a class-based framework.

    3. What are the key technologies and libraries used in this course? The core technologies and libraries you will explore in this course include: * PyQt5: A powerful Python framework for creating graphical user interfaces. * SQL: For creating and interacting with databases within your applications. * Matplotlib: A Python library used for data visualization, allowing you to create charts and graphs. * Pillow (PIL): A library introduced for image manipulation in one of the projects.

    4. What kind of projects will I build in this course? Over the course, you will build five interactive applications: * A starter app to get familiar with the initial setup and design in PyQt. * A calculator app with added styling. * An image editing application (PhotoQT) that allows editing real photos in Python. * An expense tracker application that incorporates database creation using SQL. * An interest rate calculator with data visualization using Matplotlib.

    5. Why is PyQt chosen as the GUI framework for this course? PyQt is a popular choice for building Python GUIs due to several reasons: * Cross-platform compatibility: Apps built with PyQt can run on various operating systems (Windows, macOS, Linux). * Extensive widgets: PyQt provides a wide range of pre-built GUI elements (buttons, text inputs, menus, etc.). * Rich functionality: Beyond basic widgets, PyQt offers features for database integration, graphics, networking, and more. * Python-friendly: As a Python binding for the Qt C++ framework, it leverages Python’s straightforward syntax. * While PyQt offers a visual designer (Qt Designer), this course focuses on building UIs through code to enhance understanding of the underlying logic.

    6. How will databases be integrated into the applications? The course introduces SQL for creating and managing databases within your PyQt applications. You will learn the basics of SQL, such as creating tables and performing queries, without needing prior SQL experience. One of the capstone projects, the expense tracker, specifically focuses on using SQL to create a database for storing and managing financial transactions. You’ll learn how to connect to a SQLite database using PyQt’s QtSql module, execute SQL queries to create tables, insert data, retrieve data, and delete data based on user interaction.

    7. What will I learn about data visualization with Matplotlib? The course introduces Matplotlib for data analysis and visualization within Python applications. You will learn how to use Matplotlib to create charts and graphs to represent data. The interest rate calculator project culminates in using Matplotlib to visualize interest rate calculations over time. You’ll learn how to create figures, subplots, plot data, and customize your charts with titles and labels. The integration of Matplotlib with PyQt is facilitated using the FigureCanvasQt class from Matplotlib’s backends, allowing you to embed Matplotlib charts within your PyQt GUI.

    8. Will I learn about styling my Python desktop applications? Yes, the course covers styling Python desktop applications using a few different approaches. For the calculator app, you’ll learn to customize the appearance of widgets using PyQt’s functionalities, such as setting fonts. Later, the course introduces Cascading Style Sheets (CSS) for more comprehensive styling, similar to web development. You’ll learn how to use the setStyleSheet method in PyQt to apply CSS rules to your application’s widgets, allowing you to control colors, fonts, spacing, and other visual aspects. Finally, the course explores implementing a dark mode as an advanced styling feature, toggling between different stylesheets based on user preference.

    PyQt Widgets: Building Blocks of GUI Applications

    Based on the sources, QT widgets are fundamental building blocks for creating graphical user interfaces (GUIs) in Python using the PyQt framework.

    Here’s a comprehensive overview of QT widgets as discussed in the sources:

    • Definition: A widget is any element you see on an application’s screen. This includes buttons, text labels, input fields, menus, and more. The PyQt5.QtWidgets module provides a collection of these pre-built GUI elements or objects that can be added to your application.
    • Purpose: QT widgets enable you to create interactive and visually appealing desktop applications. They provide the user interface components that allow users to interact with your Python programs.
    • Key Concepts:
    • Framework Module: PyQt is a comprehensive framework, and QtWidgets is one of its modules containing various widget classes.
    • Class-Based: PyQt is a class-based framework, meaning you work with classes to create and manage widgets. Each widget you use is typically an instance of a specific widget class.
    • Objects: When you use a widget class, you create an object or an instance of that class, which you then manipulate and display in your application.
    • Essential Widgets:
    • QApplication: This is a crucial class that allows you to create and execute your PyQt application. Every PyQt application must have one instance of QApplication.
    • QWidget: This serves as the basic building block for all user interface objects. It provides the main window for your application where other widgets are placed. Your custom application windows often inherit from QWidget.
    • Commonly Used Widgets (with examples from the course projects):
    • QLabel: Used to display text or images on the screen. In the example app, QLabel is used for the title and random words. In the image editor and interest rate calculator, it’s used as a placeholder for the image/chart initially.
    • QPushButton: Represents a clickable button that can trigger actions when clicked. Used for actions like “submit” in the example app, number and operation buttons in the calculator, editing tools in the image editor, and “Add Expense,” “Delete,” “Calculate,” and “Clear” buttons in other applications.
    • QLineEdit: Provides a text input field where users can enter and edit single-line text. Used for entering expressions in the calculator, amount and description in the expense tracker, and interest rate, initial investment, and years in the interest rate calculator.
    • QVBoxLayout and QHBoxLayout: These are layout managers that help you organize and arrange widgets in your application either vertically (QVBoxLayout) or horizontally (QHBoxLayout). They automatically handle the sizing and positioning of the widgets they contain.
    • QGridLayout: Another layout manager that arranges widgets in a grid (rows and columns). Particularly useful for structured layouts like the calculator’s button pad.
    • QListWidget: Displays a list of items that the user can select. Used in the image editor to show the list of files in a selected folder.
    • QComboBox: Creates a drop-down list (combo box) from which users can select an option. Used in the image editor for applying filters and in the expense tracker for selecting categories.
    • QDateEdit: Provides a widget for selecting dates. Used in the expense tracker to input the date of the expense.
    • QTableWidget: Displays data in a table format with rows and columns. Used in the expense tracker to show the list of expenses. Methods like setColumnCount and setHorizontalHeaderLabels are used to configure the table.
    • QTreeView: Presents data in a hierarchical tree structure. Used in the interest rate calculator to display the year and total interest calculated. It uses a QStandardItemModel to manage the data displayed in the tree.
    • Widget Manipulation:
    • Creation: Widgets are created by instantiating their respective classes (e.g., QLabel(), QPushButton(“Click Me”)).
    • Adding to Layouts: Once created, widgets need to be added to layout managers using methods like addWidget(). Layouts then need to be set on the main window (or other container widgets) using the setLayout() method.
    • Styling: Widgets can be styled to customize their appearance. This can be done through methods like setStyleSheet(), which allows applying CSS-like styles. You can target specific widget types (e.g., QPushButton, QLabel) in your style sheets. Fonts can be customized using QFont and the setFont() method.
    • Functionality: Widgets can be made interactive by connecting their signals (like a button’s clicked signal) to functions (slots) that define the desired behavior.

    In summary, QT widgets are the visible and interactive elements that constitute the user interface of a PyQt application. The QtWidgets module offers a rich set of pre-built widgets that can be arranged using layout managers and styled to create various desktop applications, as demonstrated through the different projects outlined in the sources.

    Pillow: Python Image Manipulation Fundamentals

    Based on the sources, the Pillow module, also known as the Python Imaging Library (PIL), is a crucial component for building the interactive photo editing app in Python within this course.

    Here’s a comprehensive discussion of the Pillow module as described in the sources:

    • Purpose: The Pillow module is specifically used to work with images in Python, allowing you to open, edit, and save them. It provides the necessary tools to implement image manipulation functionalities in your applications.
    • Installation: The sources mention that Pillow needs to be installed using the Python package installer, pip. The commands provided are pip 3 install pillow or, if that doesn’t work, python 3 -m pip install pillow. This step is essential before you can use the Pillow library in your Python projects.
    • Key Submodules and Classes: The sources highlight several important parts of the Pillow library that are used in the image editing app:
    • Image Module/Class: This is fundamental for opening image files using Image.open(full_name), displaying images using image.show(), creating copies using image.copy(), and saving images using image.save(full_name). The Image class also provides methods for image transformations such as flipping using image.transpose(Image.FLIP_LEFT_RIGHT) and rotating using image.transpose(Image.ROTATE_90).
    • ImageFilter Module: This module allows you to apply various filters to images. Examples mentioned include ImageFilter.SHARPEN and ImageFilter.BLUR, which can be applied to an image object using the filter() method (e.g., self.image.filter(ImageFilter.SHARPEN)).
    • ImageEnhance Module: This module provides classes to adjust image characteristics like color, contrast, and sharpness. For instance, the ImageEnhance.Color(pick).enhance(1.2) class and its enhance() method can be used to increase the saturation of an image. Similarly, ImageEnhance.Contrast(self.image).enhance(1.5) can be used to increase the contrast.
    • Basic Image Operations:
    • Opening Images: Similar to opening text files with Python’s built-in open() function, you can use Image.open() from the Pillow library to load image files. You need to provide the path to the image file as an argument.
    • Saving Images: The save() method of an Image object allows you to save the modified image to a file, specifying the filename and format.
    • Image Manipulation Techniques Discussed:
    • Converting to Black and White: The convert(‘L’) method of an Image object can be used to transform a color image into a grayscale (black and white) image.
    • Applying Filters: The filter() method, along with filters from the ImageFilter module, can be used to enhance or modify the image.
    • Enhancing Image Properties: Classes from the ImageEnhance module allow for adjustments to color saturation, contrast, and potentially other properties.
    • Flipping and Rotating: The transpose() method with constants like Image.FLIP_LEFT_RIGHT and Image.ROTATE_90 can be used for geometric transformations.
    • Integration with PyQt: The Pillow module is used in conjunction with PyQt to build the image editing application. After loading and editing images using Pillow, the resulting image data needs to be displayed in the PyQt application’s GUI. The sources mention using QPixmap (from PyQt5.QtGui) to handle image display within PyQt.
    • Importance of Specific Imports: The sources emphasize the best practice of importing specific classes and modules from Pillow (e.g., from PIL import Image, ImageFilter, ImageEnhance) rather than using a wildcard import (from PIL import *), as Pillow is a large library.

    In summary, the Pillow module is essential for the image editing project, providing the functionality to load, manipulate through various filters and enhancements, and save image files within the Python application built with PyQt.

    PyQt and SQL for Desktop Applications

    Based on the sources, SQL databases are a key technology explored in this course for building interactive desktop applications with Python and PyQt, particularly within the expense tracker application.

    Here’s a breakdown of the discussion around SQL databases in the sources:

    • Purpose: SQL is used to create and manage relational databases within the PyQt applications. These databases allow for the storage and retrieval of structured data in tables. In the context of the expense tracker, SQL is used to store information about expenses, such as date, category, amount, and description.
    • Integration with PyQt: PyQt provides specific modules and classes to interact with SQL databases. The primary modules involved are:
    • PyQt5.QtSql.QSqlDatabase: This class is used to establish a connection to a SQL database. The course specifically focuses on SQLite databases due to their lightweight nature and ease of use within Python applications. The addDatabase() method is used to create a database connection, setDatabaseName() to specify the name of the database file (e.g., expense.db), and open() to open an existing database file, ensuring that previously stored data is loaded when the app starts. Error handling is implemented to check if the database can be opened, and if not, a critical error message is displayed, and the application may exit.
    • PyQt5.QtSql.QSqlQuery: This class is used to execute SQL queries on the connected database. Queries are essentially questions or commands sent to the database to perform actions like creating tables, inserting data, selecting data, and deleting data. The execute() method runs the SQL query. For safer data insertion, especially when dealing with user input, the prepare() method is used to prepare a SQL query with placeholders, and then addBindValue() is used to securely bind the actual data to these placeholders, preventing SQL injection vulnerabilities.
    • Database Schema and Table Creation: In the expense tracker, an initial query is executed to create a table named expenses if it doesn’t already exist. The CREATE TABLE IF NOT EXISTS SQL command is used for this purpose. The expenses table is defined with several columns, each with a specific data type:
    • ID: An integer that serves as the primary key for each expense entry and is set to auto-increment, meaning the database automatically assigns a unique ID to each new entry.
    • date: Stores the date of the expense as text.
    • category: Stores the category of the expense as text.
    • amount: Stores the monetary amount of the expense as a real number.
    • description: Stores a description of the expense as text.
    • Data Manipulation:
    • Inserting Data: When a user adds a new expense, the application retrieves the data from the input fields and uses an INSERT INTO SQL query to add a new row into the expenses table. Placeholders are used for the values (date, category, amount, description), and addBindValue() is used to associate the actual data with these placeholders before the query is executed.
    • Selecting Data: To display the existing expenses in the QTableWidget, a SELECT * FROM expenses SQL query is used to retrieve all data from the expenses table. The results are then iterated through, and each row from the database is inserted as a new row in the QTableWidget, with each column’s value from the database being placed into the corresponding cell of the table. The value() method of QSqlQuery is used to retrieve the data from each column of the current row in the database result.
    • Deleting Data: When a user wants to delete an expense, the application first identifies the ID of the selected row in the QTableWidget. A DELETE FROM expenses WHERE ID = :id SQL query is then prepared, where :id is a placeholder. The ID of the selected expense is bound to this placeholder using addBindValue(), and the query is executed to remove the corresponding row from the expenses table.
    • GUI Integration (Expense Tracker): The data from the SQL database is visually represented in the expense tracker application using a QTableWidget. The setColumnCount() and setHorizontalHeaderLabels() methods of QTableWidget are used to define the number of columns and their respective names, mirroring the structure of the expenses table in the database. The insertRow() method adds new rows to the table, and setItem() along with QTableWidgetItem is used to populate the cells of the table with the data retrieved from the database. When an expense is deleted, the corresponding row is removed from the database, and the loadTable() method is called to refresh the QTableWidget with the updated data.

    In essence, SQL databases provide a persistent storage mechanism for the PyQt applications, allowing them to save and retrieve data even after the application is closed and reopened. PyQt offers the necessary tools to seamlessly integrate with SQL databases, enabling the creation of data-driven desktop applications.

    PyQt Applications: Styling with CSS

    Based on the sources, CSS styling is a method used in this course to enhance the visual appearance of the PyQt desktop applications.

    Here’s a comprehensive discussion of CSS styling as described in the sources:

    • What is CSS? CSS, which stands for Cascading Styling Sheets, is a language primarily used to style websites, working in conjunction with HTML and JavaScript. However, the sources explicitly state that CSS can also be used with other languages, including Python and its GUI framework, PyQt.
    • How it Works in PyQt: In PyQt, CSS styling is applied to widgets using the setStyleSheet() method. This method accepts a string as an argument, and this string contains the CSS rules that you want to apply to the widget.
    • CSS Syntax in PyQt: The CSS syntax used within the setStyleSheet() method in PyQt is very similar to standard CSS used for web development. It involves targeting specific elements (widgets) and then defining style properties within curly braces {}.
    • Targeting Elements (Widgets): You can target different types of PyQt widgets by using their class names directly. Examples from the sources include:
    • QWidget: To style the entire application or main window.
    • QLabel: To style text labels.
    • QLineEdit: To style input fields.
    • QPushButton: To style buttons.
    • QTreeView: To style tree view widgets.
    • QTableWidget: To style table widgets.
    • QComboBox: To style combo (dropdown) boxes.
    • QDateEdit: To style date edit controls.
    • Style Properties: Within the curly braces, you define style properties using a key-value pair format, separated by a colon : and terminated by a semicolon ;. Examples of CSS properties used in the sources include:
    • background-color: To set the background color of a widget.
    • font-size: To set the size of the font.
    • font-family: To set the typeface of the font.
    • padding: To add spacing around the content of a widget.
    • border: To add a border around a widget.
    • color: To set the text color.
    • Applying Styles: The setStyleSheet() method is called on a specific widget instance to apply the defined styles to that widget. You can apply global styles by setting the style sheet on the main QWidget or more specific styles to individual widgets.
    • Targeting States (e.g., Hover): PyQt’s setStyleSheet() also allows you to target specific states of widgets using pseudo-classes, similar to CSS in web development. The source provides an example of the :hover state for QPushButton to change the button’s appearance when the mouse cursor is over it.
    • Organization of Styles: The sources demonstrate different ways to organize CSS styling:
    • Directly within the setStyleSheet() method call.
    • Using multi-line strings (with triple quotes “””) for better readability when defining multiple styles.
    • Creating a separate method (e.g., applyStyles()) within a class to encapsulate all the styling logic, which can then be called during initialization or in response to events (like toggling dark mode).
    • Dark Mode Implementation: The implementation of a dark mode in the interest rate calculator application heavily relies on CSS styling. By checking the state of a QCheckBox, different sets of CSS rules are applied using setStyleSheet() to switch between a light and a dark theme by altering background colors and text colors of various widgets.

    In summary, CSS styling in PyQt, applied via the setStyleSheet() method, offers a powerful and flexible way to customize the look and feel of your desktop applications by leveraging familiar CSS syntax to target widgets and define their visual properties.

    Python App Development: Build Modern GUIs in 7 Hours (Beginners Course)

    The Original Text

    are you ready to start building your own desktop applications you’ve landed on the Right video this is the course for you over the next 7 hours we are going to be building five interactive applications with python this course is designed for those wanting to take their python skills up a level and Learn Python guis or graphical user interfaces you’re going to be exploring core Technologies in Python like the powerful High QT framework and SQL and Matt plot lip just to name a few well without further Ado I don’t want to keep you guys waiting let’s start building apps it’s why you’re here are you ready cuz I’m ready let’s dive in welcome guys to another code with Josh special for super obvious reasons I’m Josh if you guys don’t want to hear me ramble on for the next few minutes it is going to be beneficial here’s the time stamp that just jumps into the course you can check that out okay but as I mentioned we’re going to be building five interactive apps a starter app a calculator app expense tracker an image editor as well as an interest rate calculator using matplot lib SQL guys this course is hosted absolutely free right show some love smash that like button and subscribe comment and engage as that does help my course reach more students around the world okay that is is your way you can show support and guys the first link in the description won use the links okay but I’m hosting this course on my own platform for you guys absolutely free over there’s the community all my other free resources all right so to show your support just use the links in the description all right um okay enough chitchat uh let’s just jump into the course I’m really excited I hope you are too [Music] hi there and Welcome to our course before we get started I like to kick off my courses by going over the course structure and what you can expect in this course let’s jump in and let’s take a look our initial overview is you can expect a project-based course as this allows you to build your skills in a way that keeps you going but also challenges you and you can see a final product you will be building a strong foundation in the fundamental concepts of building apps in Python with pqt and you will use your existing python skills now you should have a basic understanding as this course and pqt is a class-based framework the knowledge you gain from this course will be key in your programming journey and allow you to expand on what you already know we are going to talk about the setup for any pqt project we will look at ways to create our app widgets design our GUI and add some app functionality throughout this course we will talk about pqt widgets how we can create custom widgets how we can style our widgets and using buttons and labels within our programs to break down our course overall we will begin with giving you a good understanding of how we use pqt to create applications we then build on working with layouts in designs for our overall apps while introducing widgets and creating interactive guis once you’ve built this solid foundation of creating your layouts working with widgets we now have a basic understanding of pqt you will then be introduced to SQL and how we can use SQL to create databases in pqt now we’re only brushing the surface here and you don’t need to have any background in SQL you’ll learn everything you need to know here to hit the ground running and for our final project you will learn data visualization with a module called matap plot lip this will introduce you to data analysis and data visualization with python you’ll also see how we can use CSS to style our python applications throughout this course you will have five projects in total the first project isn’t here but it’s a project to get you warmed up with the initial setup and the design for pqt then we work with four projects that all build upon each other our first one is going to be a calculator app and we will add styling to this app we then move on to an image editing application or I’ve nicknamed my app photo QT this app allows you to edit real photos in Python we then will progress into our third Capstone project this is an expense tracker and here is where you’ll learn how to create a database using SQL our final project is going to be an interest rate calculator with our data visualization this is where we will talk about how we can use charts and graphs in our applications who is this course designed for well it’s designed for a lot of you it’s designed for programmers of all levels for those looking to grow their python portfolio those looking who want complex tasks broken down to a basic level of understanding that is what my courses in the zero to knowing series does breaks down complex tasks into easily understandable topics this this course is designed for project-based Learners as well as all you visual Learners out there don’t worry you’ll get access to all my slides live coding projects and more now that you have an overall understanding of what you can expect in this course and the overall structure let’s jump in and let’s start off with the installation of what we need to hit the ground running I’ll see you guys in the next video [Music] all right we’re just about there before we jump into the first lesson I want to get everything installed and set up here within vscode now you may have already used vs code or this might be new to you let’s go through just one extension that we’re going to be using and I’ll give you mine as well the first extension that you should have please look for Python and just go through and make sure that you do have python within VSS code you can install this here I am using a theme as you can see here we have a few different things going on now if you want to to follow along with my theme cuzz color coordination works for me it might work for you I use synth wave 84 as my theme currently for the duration of this course you are welcome to get it there too okay let’s get that out of the way we have looked at our two extensions now going forward we are going to be working with a few different libraries throughout this course I want to install them all right now so I have them we are going to be using pqt we are going to be using pillow and we are going to be using Matt plot lib let’s get these all installed to open your terminal on a Mac you can press command J or on a Windows control J down here I just want to install so using the python package installer I’m going to say pip 3 for yours you might say p pip but with most updated newer versions of python pip 3 seems to be the way to go I’m going to say pip 3 install Pi qt5 enter let it do its thing now as you can see it says requirement already satisfied for mine that’s because I already have it here for the pillow Library I’m going to say pip 3 install pillow get that there now if none of these are working for you okay you may need to try python 3-m pip install pillow you can try using instead of pip 3 saying Python 3 this brings us to our final one which is mat plot lib so pip three install Matt plot lib as you can see I also have that one already installed at this point you’re ready to go you have pqt framework installed which we will be using for our course and then we will also introduce how to use pill in the pillow Library as well as Matt plot lib at later stages I’m ready for the first lesson and at this point you are too I’ll see you guys in lesson one of our [Music] course hi and welcome to the zero to knowing building apps in Python course in this course we will be looking at how to create apps in Python using the pqt framework before building any apps let’s jump in and let’s talk about what is pqt so long story short pqt is a module that Bridges it it connects a popular framework in C++ and python so it allows us to use this popular C++ framework in the language we choose to use which is Python and it enables us to create graphical user interfaces now you’re going to hear this a lot throughout this course and what you’re going to hear me say is you’re going to hear me say GUI GUI is a reference for graphical user in interfaces pqt it allows us to do many different things such as creating data bases with SQL or adding in embedded web browsers and even using its own collection of widgets and a widget is what you see on the app screen and there’s so much more that we can do with pqt and these features make QT a comprehensive of framework and it allows us to make all types of apps in Python let’s talk about what is the difference between pi qt5 and Pi qt6 well there is no major difference between these two in this course we will specifically focus on pi qt5 as these two versions the framework are so similar anything you do in pi qt5 that are easy workarounds to any solutions that may occur with pi qt6 and by learning and understanding just the last version pyqt5 you’re going to be able to work with a wider range of applications you’ll be able to work with older pqt apps as well as the new apps using pqt 6 the final question you may be asking yourselves now is why do we use pqt why do developers choose this framework over others I’ve put together a few popular reasons why going through them pqt allows for crossplatform compatibility so it allows our apps to be run on different operating systems like I am on a Mac but you yourself may be on a Windows or a Linux pqt allows for this it also provides endless widgets you’re going to hear this a lot in our course what is a widget a widget is something you see on your app screen it could be buttons text menus anything like that and pqt provides these ready-made or pre-built GUI elements they also offer a wide range Beyond just these components like I’ve mentioned in the previous slides we could include databases Graphics like pictures networking and a few of these we will actually be building projects in this course using them pqt also has something called QT designer and QT designer makes it significantly easier to build a pi QT app it’s kind of like figma or canva for building with pqt we won’t be addressing that in this course because that’s not programming that’s not coding that’s not learning the logic in this course most developers aren’t going to use QT designer you’re expected to know how to build out an app and what things are doing within your app that’s what we focus on here finally pqt is based in Python py right we are bridging it and connecting it to python which makes it very straightforward to us as python is an easier language and has easier syntax to understand now that we understand what pqt is and why we use it let’s head over into our next video and talk about window applications I’ll see you guys in the next video [Music] here we are at the introduction to our first app before we start making our first app we need to understand what is a window application and pqt is made to create these window applications we are here to touch on the foundations we will use to construct and build your first app these are two current and popular examples of window applications I took these off my Mac and you see a calculator and we have the system preferences tab they pop out when we need them and we close them when we do not need them anymore more as we break this down further let’s examine and take a look at the system preferences app that you see here on the left we have a main window and inside this main window we have app Widgets or objects these work together to create the GUI of our app and if you think about the main window as like a jar right and then all of the widgets are the coins and the money inside the jar they all represent something different but they’re all inside the same jar this jar is like the parent it’s like the main window of our app within the app you also see many widgets which is a word that I also keep using in this app we see a text input box a checkbox text push buttons a list all of these are a type of widget or an object that we create and then we later add into the app remember this word later but these are widgets from a class called QT widgets if I asked you to design this app what comes to mind what type of layout would you use would you draw this out would you you put it in rows how could we design it that’s a great question and as we start looking further at apps it’s a question that you should be asking yourself how I would design this app is yes rows and columns exactly what can we store in a row and what can I store in a column can I store columns in a row let’s look at that this has two rows and two columns we use layouts in pi QT to build out our design okay widgets they are automatically aligned either vertically or horizontally so my two rows are horizontal and my two columns are vertical in row one I have 1 two three four buttons they’re in their own row at the top of my app in the second row I actually have two columns one column two column with some text and a button these columns are added into a row at the end interesting so start thinking about how can we break an app down to the design basics of rows and columns moving forward let’s take a look at what exactly the pqt framework is and how it all ties together pqt is a massive framework and within this framework we have modules so for example you may have used other popular python modules like the built-in ones time and random or maybe you’ve used other external modules Frameworks like pandis or plotly or others like that well pqt is like that it is one main framework and then within that there are many modules within each module there are many classes many functions all of that stuff here I’ve put just a few of the popular pqt modules will we use all of these in our course no will we use some of them absolutely are there going to be others also yes there will be others these these are just a few popular ones starting off I’m going to talk about QT widgets because we actually saw this earlier remember everything on the app screen is considered a widget and this really provides us with GUI elements or objects that we can add into our app screen another module that we will start off with using early on is a module called QT core QT core essentially holds the miscellaneous elements that we need within certain elements of our app as we grow in our fundamentals and understanding of app development you can expect to learn a little bit of sequel in this course in creating databases as well as learning some GUI and design elements something that I’ve created that I love to teach the order of in this pattern is the code Burger all right I’m going to put this at stages throughout this course if you take notes which not really if you should be taking notes and if you do you should write this down or screenshot the code Burger this is the order of steps we must take in order to design an app in pqt and get it to open and run accordingly number one we need to make sure all of our Imports are at the top of our burger at the top of the coat once we import everything we need I will then create my main app objects and all my app settings like the size of my app the title of my app things like that once we get everything set up I can then create all the widgets that I want to have in my app they can be stored at the top all the buttons all the text anything like that can be stored in this step once we create all these widgets we need to add them to our design we need to design our app or design our layout and add all those widgets to the main window our screen once we finalize that design it’s the good idea to set our final layout we want to set the final design to our main window ending with showing and executing our app pqt is a class-based language now at this point in your programming Journey you should understand the fundamental concepts of python and programming in general python has a core concept of objectoriented programming that is where we create objects in classes and the class can store fundamental information about those objects if we do a quick class flashback pause the video read through this code and understand what’s happening do you understand everything what things do you not quite understand and then answer the question for me what is a method and what is a property all right to touch on these very briefly we defined a class called app remember a class name is one of the only things in Python that is capitalized ized my class is called app I have three methods 1 2 3 a method is a function in a class I then create an object the value of an object is a class in this case is app I’m giving app three arguments one two 3 because my app has one two three parameters these parameters are used as the value to my properties what is a property a property is a variable in a class I can then use these throughout parts of my class when it comes time to use a method a method must be linked to your object so a method is a function in a class you must link it to an object of that class in order to use it all right that was a lot but don’t worry because I’ve color coordinated a part of it and I want you to take a look at that now making an object we’re giving the three arguments to our class now these arguments we are giving to init in it is what we call our Constructor method Constructor construction build we use in it to build our class now pqt is a framework that has modules each module has classes these classes we can import into our projects to allow us to use them in our apps each class has methods and properties of its own that we can use when we link it to an object of that class that’s a lot but this flashback it should get the gears turning it should bring back memories in The Core Concepts of how we use objectoriented programming in Python brilliant let’s talk about how we can connect 2 pi QT to set app up remember step number one of the code Burger we want to import everything we need now pqt you can see I am linking to one of the modules pqt is the framework QT core and QT widgets are a module from our framework QT is a class from my module QT core I am importing some something called QT you’ll find out more about this very soon then we import all of the QT widgets we need these widgets are the objects that we want to see within our app do you want to see buttons do you want to see an input field text what do you want to see in your app that’s what we import here the two most important classes that we must Import in order to get a working app our Q application and Q widget Q application it allows us to create and execute our app Q widget on the other hand allows us to actually create that main window the parent that all the other objects are dropped into great we need those two that’s why I always like to import them first next is anything you want to see in your app anytime you want to see text on the screen of your app text in pqt is called a q label anytime you want a submit style button that is called a q push button that’s like a click button or submit button and then the other one we’re going to take a look at here you visibly cannot see this but for the design of our app we need to use layouts now what we’re going to be looking at in this first app is a vertical layout V and we will also be looking at a horizontal layout these give our app alignment in the case of QV box layout this is going to be vertical alignment we have just introduced a few classes that come with QT core and QT widgets remember QT widgets provides us the GUI elements the widgets or the objects you want to see on the screen of your app in QT core it kind of contains some miscellaneous things that we can use throughout our programs mainly for us what we are going to be using is the QT tool for alignment like align left align right align Center to help us structure our app in a more visually appealing way we’re getting super close to starting to code but before we do I’ve just introduced some important classes that we will be importing but we need to talk about a few of those important methods you’re going to be using with these classes what is a method remember it is a function in a class what is a property a variable in a class how do we use them a method in property must be linked to an object in order to work let’s take a look at some popular ones we will start off with today in order to add an object to our screen we use the method add widget this allows us to add our object specifically to a layout so to a column or a row we can change or set the text of an existing object by using the set text method remember this for later change the text of something that’s where it’s really useful when we want to add two layouts together we cannot use add widget because a layout is not a widget in order to add a column to a row for example we can use add layout and this adds two layouts together once we have one final Master layout where everything is held we can take that Master layout and we can set that as the final layout to the main window here is the method we can use to set the final design to our main window our last two methods we will use throughout our course is show and hide and this allows you to show or hide an object when something happens let’s take a look at your first app that we’re about to put together this is our first application it’s rather basic but it does everything we want it to do to hit the ground running and and understand the fundamentals it allows us to add objects on the screen we will be creating functions as well as programming these buttons to do something so let’s get comfortable with the foundations of app design in pqt 5 what do we see here so I have a main window I have like a title text I have some text for some random words and then I have clickable buttons can you locate them here they are now I want you to think about I introduced important classes that we will import earlier what classes will we need to import in order to build this app I want you to think about that well in order to create our main window our main window uses the class Q widget any text on the screen is known as a q label one two three four I will have four Q label objects and then a submit style button is known as a q push button you may be noticing two things one everything starts with Q yes that’s true also everything is camel cased camel casing means it’s one word but every word the first letter is capitalized that is very important if you spell one of these wrong you’re going to get an error and it’s going to say undefined next up how will you design the app how can we solve this what design elements should we think about here you can pause try and use those Clues to help you it’s not completed yet what we could do is we could start with three rows that’s the most basic form of design design in this app these three rows are like the base layers and I’m going to stack them like cake in a column so my final design is a column and within that column I have Row one two and Row three bringing together the final application design how cool all right let’s tie everything together the real question we need to know to get started is what do we need in order to set up our main window screen to get our app started here we are if you memorize any code in this first part of the lesson memorize this because we will use this every time we start creating an app at the top of my code you can see all of our Imports I’m importing QT from QT core next I am importing all the widgets I need to build the app for from QT widgets our two most important Q application Q widget everything else is optional based on what you are trying to build after our Imports according to the code Burger we have our app settings and our app main objects these main objects are app in main window one of them should always be called app this is a generic name that’s used across the world by other Developers app is equal to Q application Q application is our class remember the parentheses and it also takes an empty list as an argument next I like to use the name main window you do not need to use that the value of main window is Q widget that allows us to create this window app once we have our main window object you can go forth and you can start to style or give your app the settings if you want to give your app a title you can do that with the set window title method that’s linked to our main window if you want to give your app a starting size what size will the app be when it first opens you can resize with a width 300 and a height of 200 you can choose any width and height you would like soon we will be creating all the objects that we’ll be adding to our app but the last two lines in order to get our app template all ready to go is we need to show our main window and we need to execute our app great let’s put together our starting app and head over to vs code I’ll see you guys in our next video [Music] alrighty here we are in vs code before we jump into start coding let’s take the code burger and let’s put it in here to VSS code to give us a starting template what was number one again well number one was we want to import our modules okay then we have our main app objects and all of our settings great once we have our main app objects what should we do we should create all app objects so anything we want to see in this app finally we can have all of our events and then we want to show slash run our app these would be the things inside now we do want to design where do we want to design in our app well we want to design right here okay so all of our design can be done after we create the main object so I’ll just say all design all righty to kick things off let’s go up and let’s work through and get a basic template going for the foundation of our app so importing our modules we can say from PI qt5 that’s our framework now I can attach the module I want to go QT core import class so I want QT class from the QT core module from the framework pi qt5 all righty now we can get our GUI going we can get all of the widgets we want on the screen so let’s import those I like to start with the two most important ones which are Q application and Q widget so right here Q application Q widget what else do we want to see in the app well I know that I want text so we can say Q Lael I know I want some buttons so let’s say Q push button finally what type of design are we going to be doing well we’re going to try to do some rows inside of a column which we’re going to actually check out here in our next lesson so before we do that let’s just say QV box that gives us one initial layout now that we have everything imported let’s work on our two main objects so I’m going to say app equals our Q application class and remember that this takes an empty list as our argument next up to kick things off let’s make a main window and we can say here Q widget you can name this anything you want my names are going to be to help you further your understanding so this is my main window I’m going to call it my main window now the other final settings we can do is we could set a title for our app right and we could say random word maker okay and then we could set the initial size what size do we want the app to open with I could say a width of 300 a height of 200 great all righty to close things off for our start all we need to do is is we need to take our main window and we want to show the main window while the main window is showing we can execute or run our app let’s run our code and observe what happens there we are our starting template you can see that the initial size is 300200 but you can make it smaller and you can make it bigger okay and then you can also see the app title is random word maker which we gave it here now this is great because every app we make will start with this this is the foundation it’s like you’re pouring the concrete to build the home so we can now build on top of this now remember there are many ways to do a certain task don’t be afraid to try your way I’m breaking this down so we understand the key fundamentals to build apps with pqt let’s head over to our next video and in that lesson we are going to address the design of our app and how we can do that I’ll see you guys in the next [Music] lesson [Music] Welcome to our next video now that we have our starting template ready to go it’s time to design our app how can we achieve this look right we have our three rows and these rows are held in one master column so the layout tools will be using are going to be our QV box layout V for vertical and our qh box layout or H for horizontal these will be used to build our rows and the columns how will our code look well now that we have our app ready to go we need to create all of the objects or widgets that we want to store in this app on my screen you see one 1 2 3 4 five six seven objects therefore we should be creating seven different objects they each have their own name but the value can still be from the same class they’re different objects from the same class my title text well that’s just text remember in pi QT anytime we want text we can say Q label when my app first starts all of these should actually be a question mark right until we start clicking the button so I can create those here to end with I will create three push buttons each button is a different object but they all say click me now that we have created all these objects you’re going to use in your app it’s now time to design the app you won’t be able to see any of the objects if you were to run your code now it’s because we can’t see these objects until we add them to our layout and we set that to our main window as I go through this course remember there are many ways to solve a problem in coding I am showing you one way and I’m breaking that down to a way that you guys can easily understand if you find a different way or you want to try it yourself I encourage you to do so here you can see each of those correspond to an element on the app screen and that’s held in our final QV box column now that we created those objects I need to get them on my screen here I have made my master layout which I know at the end everything will be added to but I also know that I’m going to have one two three rows so I can create three row layout objects right here next up it’s time to add things to the row so I can start with Row one because I know it’s going to be at the top what do I want to do I want to say Row one I want to add the title text to it it’s going to do just that if I want I can give alignment to the text and I can say I want it to align in the center enter you can see I’m using the QT class from QT core that we imported now that I know Row one is done check I can move on to row two and I can do the same thing row two I want to add the widget text one which corresponds to that and I can also give that alignment row two is done we can add the buttons to row three this is adding all of the objects you just made into each row now if you’re running your app no what do we need to do now what’s the next step in the code Burger now that we have our rows we need to add them to our Master column I can take that and I can say master layout I want to add Row one it’s important to add these rows in the order that you want to see them remember python reads top to bottom we need to code like that too once we have everything in one place or should I say in one master layout I can take my main window and I can set the final layout to be my master layout if I break that down one step further here is what that would look like we’re creating our Master layout that everything eventually will be added to I can create three rows because that is how I’m choosing to design my project then we just need to go through and we add each row once we’ve added the widgets to it we add each row to that Master layout finally you can use set layout to set the final design of your app to your main window screen this ties together perfectly the code Burger you guessed it you probably didn’t guess it but it does bring in the code bger I’ve just gone through each step individually and how they align and how they work together you have a designed app now but let’s just touch on the final elements what is this app going to be doing well it’s going to be generating a random word and displaying that on the screen every time you click a button how could we do that pause the video take a minute just think how could you do that that you heard the word random you should have thought the random module I want to import the function Choice from random now Choice takes a list as an argument and it randomly chooses one of the elements from that list so I have a list called my words and I’ve just put these random words in here I then have a function and when this function is called I have a word variable and this Choice function is going to choose one of these random words so word equals one of these I can then take my text one object which we already made in your app and I can now set the text to be that random were that is how I can use the set text method with our app to set the text of an existing object on our screen the final question that we are going to address is event handling how do we connect a button how do we activate a button to work in our code what event could we possibly use in pqt in pqt to kick things off we are going to be focusing on one event now you can see that I have my object button and that is a q push button that object is created here I then have a function and every time this function is called it’s just going to print this button is working that’s all the function is doing I take my button objects and I say when the button is clicked we want to run the test function clicked that’s the event type in pqt let me translate this now the event would literally translate to when this button is clicked I want to connect to this function and that is how we handle events in pqt in our first app we are just going to be looking at the clicked event but in other projects that we do in this course we will be learning about other events as well all right let’s head over to vs code and let’s finish off our app I’ll see you guys in the next video [Music] here we are in our next video in the lesson we introduced how we can create a layout and design our app the way we want it to we also addressed how to get the objects to appear on our screen because we now know that after we create an object we then need to add it to our design let’s start off by creating all the app objects that we need first up I’m going to create a title cuz I know I’m going to have a title that is going to be text on the screen and according to my app I can just put random keywords because that’s what I want the title to be I will then have three different text so as long as they all have a different name because they’re all different objects that’s fine and they can still all use the same class initially when the app starts I want my text to be a question mark when we click a button this is going to change to a random word great we have our text objects what other objects do we want the buttons so for each button you should create a q push button it’s a q push button that can say click me we need to give them different names great we now have our seven objects all of these we want to see on our screen now that we’ve created these objects it’s now time to move into our design we got to get these onto our our layouts onto our screen the first thing we can do for our design is let’s create all the layouts we want now I know that my final layout my master layout I want everything to be held in a column so I’m going to make that within this master layout column I know I’m going to stack some rows it’s going to be like cake so I want to have Row one row two Row three in order to get that I need my Q hbox layout therefore let’s go up and let’s just add that on to our Imports let’s say qh boox layout now that we have that I can go forth and I can say okay I am going to make a row one let’s make a row two and Row three these are the designs in the app great we can start to add our objects how do we add these widgets to our screen well do you remember the method we learned add widget what is that going to be linked to well let’s say hey python in row one I would like to add my title to the screen I would like my title to have the alignment of the center of the screen so I can pop that in just like so that’s what that translates to row one I I would like to add my title my title is a widget Q Lael and then my row is the layout great that’s Row one I can move on to row two in row two we’re going to have more I’m going to have text one text one is going to have its alignment again and I can say once again align Center but row two is also going to have our other two texts so I can say text two text three remembering that python reads like a book left to right top to bottom so the order we add these to our rows it’s going to go left to right text one text two text three that concludes with the final of adding our buttons to the screen our buttons do not need alignment so I can just take it and we can just add the button how it is button two button three awesome look at our design okay if any of that is confusing go back through some of our slides rewatch the last two minutes of this video right we create our layouts and we simply just go in order all right I’ve made my layout I’ll just start with Row one we do what we need to do row two and Row three now that we have all these rows I just want to drop them into my master layout here is US using the add layout method now remember that we use the add layout method because a row in this example is not a widget it’s a layout if we want to add rows or columns together we need to use add layout so how we could translate this is Master layout we want to add Row one at the top Master layout I would like to add row two under Row one and then Master layout we can add Row three under row two now that everything is stacked in our Master layout let’s just say okay I have my final design ready to go main window I want to set the final layout to be my master layout incredible let’s give our code a run there we are you can see our app I have the title which we’ve given it right here I have my three question marks ready to go for my random words and then we have all the buttons we added now if you try the buttons we have not connected any events yet that’s what’s yet to come in the next video we will implement ment our random words as well as the events for each button I’ll see you guys in the next [Music] video Al righty welcome back let’s get this app finished now we need to introduce random words and Link our buttons with our Events first things first let’s create some random words so when you hear the word random you should immediately be thinking of the Python random module if you’re not familiar with this do a little reading on the documentation it’s one of the built-in python modules like random or time or math python has these modules and choice is going to allow us to choose a random word from a list speaking of lists let’s go down here with all of our objects and let’s make one let’s just say my words equals a list I’ve already prepared some words you guys be creative you know choose a hobby that you’re passionate about and use those words here all righty so let’s see let me Mark these we’ve imported choice we have a list of words we’re now ready to make some functions I’m going to add one additional comment add functions I like to create my functions down here in the bottom okay after our design after the design elements of our app there are many ways to do this again and if you think of a different way go with your way try your way the way I’m about to do it is to make it more readable for you and easier to understand in the big picture of things it doesn’t matter if you do the same problem in three lines of code or 15 lines of code were you able to solve the problem if the answer is yes awesome that’s great and you should be proud of that let’s make a function now to be exact I’m actually going to make three functions they’re all going to be the same thing but they’re going to be linked to different events so random word when I call this function I would like to get a random word from my list of words so I’m going to use the choice function here and I’m going to insert my list so now word is going to be one of the random words from my list it could be Hello Goodbye test app any of those I can then take my object text one remember we created three of these one 2 3 currently text one is a question mark I want to update that value or change that value who remembers what method do we use to change the value of an existing object set text so I can link set text method because I want to change the value of text one and what do I want the text to be whatever random word was chosen that’s what we want great I’m going to use this now a few times so let’s just take this what do we need to change well uh random word two we now want to change text two and then random three would like to change text three great we have our three functions one two and three to close things off we need our pqt events and remember we have just learned our first event of clicked clicked is linked to a button object so let’s say button one when button one is clicked I want to connect with my random word one function when my button to is clicked I want to connect with my random word to and I’m just going to take that for the last one and we can say button three and random word three great run your apps play with your apps experiment and review our code what did we just do save this code somewhere as it’s going to help you build our future projects it is the code Burger structure it’s what we’re going to be using in this course I’m going to give my app a run there we are click ah look at that all different that’s great we have it working exactly how we wanted it to very well done we have put together our first app but fear not cuz what we’ve learned here we are going to use in the remaining projects of this course I’ll see you guys in the next lesson where we are going to introduce our next [Music] project welcome back to our next project in this project you’re going to be putting your knowledge of QT widgets to the test as we build an interactive calculator with pqt before we dive into this project let’s take a look at the famous code Burger one more time remember the structure of what we’re trying to do here we will use this structure within this project as well remembering all of our Imports our main app objects with the setting once we have those two feel free to create all the widgets you want to see in your app once you have those we can then design the app with our layouts and set that to our main window when everything is set it’s time to run and execute your app this is the code Burger so in the past we have been using QV box layout in qh box layout and remember that V is for vertical or a column and H is for horizontal and row you got some practice with these in the last project looking at this calculator app how would you design this do you see rows and columns does that make sense right what other options do we have well what I see is a grid what if there was a way to create a grid for us there is with pi QT we have a layout called Q grid layout and you can see that I have my object grid and the value is Q grid layout which I’m going to use instead of creating four columns and five rows that seems really repetitive I can create one grid and add things to my grid which becomes incredibly useful for us but how do we add things to this grid do we still use add widget yes we are adding an object to a layout we still will use add widget but now add widget actually takes two additional arguments we create our grid object then we say grid we want to add a button where we need to specify the row in the column right so if we translate this layout add this object to this Row in this column now for this to work right we do need to create some type of index or current position in this example I’ve said row equals 2 in column equals 1 that would actually give us the number five button if you’re thinking how that doesn’t make sense remember programming languages start on zero so I’m actually saying row 0 1 2 column 01 that gives us number five we are trying to take our knowledge from an idea all the way to a completed application currently we’re on the number one you know how to get to number two and after the last two slides you should have a rough idea on how we can achieve number three you do see a new object in our calculator this little guy is called a q line edit tool and this is where we will see all of our Expressions being entered and evaluated number four is like a final bonus redesign and it’s a way for us to add slightly more details to our app we can change the font change the color things like that that’s our goal for this app to go from design one all the way to design three if we can get here this is a completed product we can then worry about getting to number four looking at this calculator now this whole grid system it seems like it’s going to take a while because I I have I think at least 17 buttons maybe 18 buttons so it seems really repetitive how can we deal with repetitiveness in coding what do we have for this Loops what are the two types of Loops you know in Python the while loop and the for Loop the four Loop is used to iterate to go through something else let me propose that we actually Loop through to create our grid so let me break that down to plain English in general tasks before you see any code I’m making a for Loop and I’m going to go through this list this list will be all the string elements that I want my buttons to say what do I want to see on my buttons like the letter c the less than sign the number four all of those I could add to a list and I could Loop through and say for every button text in my list every time I Loop through one I want to create a new push button object with the current text I’m on two for that object object I will create an event only for that button great then I want to add this new button to my grid layout one two and three all work for one button number four before I make the next button I should change my row and or change my column so think about this how can you achieve this and how can you achieve this with using a for loop as well as counter variables if you’re up for a little challenge pause the video here give it a try and then come back to continue watching putting this into code on the outside of my for loop I have two counter variables responsible for keeping track of my row and column I’m going through my list of buttons and every time I’m creating a new button object a new event for that button and then I am adding I’m taking my button and we’re adding it to our button grid every button is being added at an index a position row column once we add one button I want to increase my column or change my column if I get to four columns then I want to reset my columns and I want to go down to the next row this remember we start on zero so it’s actually 0 1 2 3 increase row 0 1 2 3 and I’m repeating myself amazing very well done I would love it if you took the knowledge that we just learned in this lesson and you go on and you create your design and create the initial product for our app I’ll see you guys over in vs code where we’re going to put all of our knowledge to the [Music] test Welcome to our next video in this video we are going to put together our initial design here in vs code for our calculator app let’s get started so who remembers the code burger right let’s go through those steps what will we need in order to complete this project well we really just need some widgets okay so I’m going to say from pqt 5. QT widgets let’s import the two most important ones so Q application Q widget what else will we need to create this well we need our new tool our q line edit we will be using push buttons then our layouts we have our qh which we can use for row if we need it we have our QV box for columns and our new tool is our Q grid layout which I can import up top like so um looking good all righty now that we have those we can create our starting template so our app which is our Q application then we can say our main window amazing who remembers how to give the main window AR title let’s say main window. set window Title Here I can put calculator app then we can take our main window and we can resize so the initial resize let’s say the width can be 250 and the height can be 300 we can see how that plays out when we’ve run our app let’s put in the final two lines what do we need to show our starting template well heading down here our final two lines we can show our main window and we can execute our app great let’s give it a run all righty there we are our starting template what do we need on here we need to now design the layout using our Q grid box our q line edit and then our push buttons that we want for our clear and delete as a as a starting template so this is what we’re aiming for all right and I’ll bring this back up as we work through this project but this is the goal up top in a column we have a q line edit this is like where I enter something then we have our Q grid layout with all of our buttons and the last one could be a row here that I may put and that contains our final two Q push buttons so to get our row and our design well let’s create all of our objects first so even before my design let’s go back and let’s say something like uh all objects or widgets right CU that’s what they are what do we need here well I need a place for my input so let’s say like a text box cuz that’s that’s what it can be this is our q line edit now q line edit does not take anything I will make my grid which is a layout so Q grid layout now the way we looked at this in the lesson is we have a for Loop that can go through a list and every element in that list or every position it can append or put that into our grid layout so I need a list of buttons now what order do they need to go in and we need to think about that let me bring up our example of the app again I’m going to Loop through so either we want to do it in columns 7410 or I could do 789 SL 456 star let’s go with the rows so how about we start by making this I could I could probably keep this up as a template uh so let’s say 7 8 n slash right and then I’m coming down the row we have four five six let me enter the rest of these here there is our list of button text now this makes it really difficult to see so let me re Factor this and I’m just going to make it look more pretty so that it’s how it would appear on the calculator right so there’s the same list I’ve just put it in rows now and this is essentially what we want to see on our app screen right when the app fires up it appears and you can see how each row of this list is corresponding to the row in our calculator now I just made this look like the calculator will but one long list is the same this is easier to understand and interpret now the final two buttons we can make outside of our list and those can be our push buttons let me close the app let’s create a clear button and this will delete everything in the Box I’ll put C and then we’ll say delete and delete could be a push button like we could do that for delete we could also write clear and delete might be fine clear let’s keep the symbol for delete uh all righty so we have everything that we want to see on our screen at this point let’s go through and let’s map this out and get our design we have our objects we need our design to start flowing how could we get our design started here well let’s create our layouts so I’m going to say master layout I know in the end everything will be held in a column that makes sense at the top of my column I would like my text box right that input so I’m going to put that right there directly under this I would like to actually add my grid of buttons which I don’t I don’t quite have those yet so I’m thinking out loud here then at the bottom we want to have I actually want to have a row so let’s also say add layout and let’s say button row while I’m here let’s create that button row so I’ll say button row and within that button row I would like to add my widgets so from left to right let’s say the Clear button and then we have the delete button let’s focus on our grit we have everything going and so we can see that let me turn off the grid let’s set the master layout to the main window cuz that’s our final design I’m going to run my program this is what it looks like currently we have that box at the top we want we have clear and delete I want to get the buttons between those two now so here is where I’m about to implement that Loop and remember every time we Loop over we are creating a new object with a new event why while also increasing the row and the column as well I’m going to shut the app down trash the terminal we are going to go right here before our design this looks like a good place before our Design This is where our for Loop is going to take form now I’m going to create my two counters so row and column and this will keep track of how many buttons are in each row as well as each column I can say for every text in this list so I have my list of buttons and I want to say for every string for every text in here so let’s say for every text in my list of buttons I want to create an object for the current button I’m on so I’ll say button equals Q push button uh what do we want it to say well I want it to say whatever the current text is in the loop when this Loop first takes off text is going to be the number seven number seven will be the text value of the first push button we create for this button it has the object name button I can create my event and I’m going to say I want to connect it to some type of function which actually I don’t have yet okay so let’s keep that empty while we have our button created we have the event created which I could say none while it’s also none let’s turn it off we can now add this to our grid let’s take our grid let’s add the widget what widget do you want to add I want to add the current button at the current row at the current column looking great all righty before we go on any further I now need to increase the column I want to move to the next button on the right so column plus equal 1 if my column is greater than three I want to reset my column so column now equals zero and I can increase my row because it’s time for a new row this puts together exactly what we want to see in our calculator app the final step is let’s just turn this back on again we can add our grid to our Master layout design when we give the app a run we should see our basic template with all of our buttons looking great this is the basic form of the app now notice it doesn’t do anything yet but we have everything ready to go for adding our functionality I’ll see you guys in the next lesson where we are going to discuss how we can add functional ity to our [Music] app great now we have our design for our calculator app completed but what’s the problem it doesn’t do anything yet that’s fine because adding the functionality to our applications comes after we create our initial design so in this lesson we are going to learn how to create that functionality as well as learning how to evaluate our expressions for example 2 + 2 evaluate to 4 in order to do this we could do this a few ways now what are you thinking about right now in this moment how would you add functionality to our app you may be thinking a few things and that’s okay before watching this lesson you may want to try and Implement your own ideas in logic which I highly encourage you try I’m going to show you one of the many ways to solve this and the way I’m going to show you is actually done through one sole thing function I am creating one function called [Music] buttonclick this is the only function that’s actually required to run our app you could make a function for each button sure that’s just a lot of code but would that work absolutely it would work what we’re doing is going down we are checking if the text of the button is the equal sign if it is then we set the value of this variable to be the equal sign if I press the button that has the letter c on it I would like to clear my q line edit object if we press the less than button we would like to cut the last element off our current text do you know how to solve any of these currently well let’s take a look at some of them our first one let’s begin with this so when we click a button I want to get the text value off of that button object do you remember how we can do this well we can use the text method and this method is linked to an object and it gets the text value of that object which is pretty cool you can see here here that I’m getting the text value of the button I’m getting the text value of the input box the q line edit box and I’m doing that here here and here pretty cool all right now that we’ve collected the text from the button we need to evaluate the expression that we enter into the input field for example if you clicked 3 + 5 we need to now evaluate that we want to change that to 15 any thoughts on how we can do this in Python well in fact you may have seen this python function around before python has a function called eval this function is made to evaluate expressions so if the expression is true if the expression is allowed it’s going to run next if we press C we want to clear the input field how can we do that well thanks to Pi QT Pi QT has a method called clear we can link clear to any object that we want to Simply put clear great this brings us to our final one if we press the delete button we want to delete the last item that we entered any thoughts on how we can cut an element from a string you should know this from working with strings and string manipulation as well as working with lists in order to cut I have a variable called current text and that is the text value of whatever is in my input field so I’m going to take that text and I’m going to cut using our square brackets to index the last position of the string minus one this is a key fundamental of string manipulation that you should already feel relatively comfortable with this takes us to our last method now a current problem we actually have is all the buttons have the same event or the same Target of event and we need a way to tell them apart but don’t worry because Pi QT has actually got us covered for this as well we only need to do this if we are making one function for our entire application which in this lesson that’s what I’m doing we can use the sender method and I’m going to link sender with our app object the sender method was created specifically to tell the difference between multiple events in Pi QT so that’s the first thing we do I create a variable called button and I am tracking which button did I click which button sent the event to me amazing the last thing we can do here is I’m going to throw in a try statement because I could potentially get an error I would like to try to evaluate the expression if that’s not possible then I just want to set the text of the input to error why is this useful why would this happen well if you pull out your iPhone right now any phone you have and you pick any number and you say I don’t know 20 divided 5 you’re going to get four but if you say 20 / 0 you’re going to get error that is what could happen what if a user tries to divide by zero we want to anticipate what could the user do wrong and I’m going to catch that right here so as a final precaution I am going to add my try and accept statement to catch any potential errors amazing before heading back into vs code to implement our app functionality you are going to see the next few videos in the next video we will finalize our app then I have prepared two remaster challenges for you that we should be getting comfortable with here are your two challenges for this project once you have a working product your first challenge is to remaster your app into a class based application so I want you to try to build your own class and refactor all your code to get it in your own class all right if you’re able to do that why don’t you try to add some designs and styles to your app as a hint you can check out the Q font module from pqt this will allow you to play with your fonts and for all the styling check out the method set style sheet if you have ever worked with CSS you’re going to be ahead of the game because we can add CSS to our apps I’ll see you guys over in VSS code where we are about to finish our calculator [Music] app amazing now we’ve addressed the functionality that we will be adding to our application here is where we left off I’ve cleaned some things up a little bit as we’re getting ready to add in our function the question becomes where should this go so if I take away all of our spacing here based on our last app we put the function at the end but I am going to get an issue because right here we need to connect to some button in order to create this event so it has to go before our Point here because this needs to go before our layout our function can rest just up here right after we create all the elements we’ll use all those widgets I’m going to create my function and this function is going to be responsible for Anytime a button is clicked so remember we have all those buttons on the screen and each button really has the same function call so we need to check what is the face value of that button what text is currently on the button what we can do is I can create a variable and I’m going to listen to who sent the message who was clicked that’s what it’s listening for then I can take that button of who was clicked and I can take the text value of it right so those those two are working together right there first I’m listening to what button was clicked then based on that button I’m getting the text value from it we can then check if that text value is actually the equal sign if it is then we want to get the text that is within our object text box let’s get that we can then try to evaluate so remember that this is an expression and I’m going to have a result in this result we want to evaluate the equation so like 2 + 2 my result should equal four I can set my text box as the updated value of whatever my result was making sure that I convert that to a string what is every Tri statement need well every try statement we want to have an accept we want to catch that so how can I catch that for every exception I don’t just want to say accept I want to say exceptions overall and I can give them a nickname and I’m just going to refer to them as e e means every

    exception so I can just print off and I’m just going to say error let’s put two dots and I’m going to say e so that I can get that type of error as well if we press the equal sign we evaluate that expression let’s check if the original button text is actually clear right does the text value say clear if it does we can take our text box and we just want to clear the value that’s within it that’s where the pqt handy clear method comes in what is the last button that needs its own as well well our delete button right if we press delete we would like to be able to backspace so if the face value of our button is that sign that we set we can then try and do a few things we would like to get the current text within our text box whatever it is it could be 85 minus 2 I want to get 85 – 2 I want that value it could be 100 I want to get 100 from there so let’s say let’s just say current value it’s the current value within that box and that is equal to my text box the text within looking good in order to update this now every time I click I want to update the text box so I can say set text because I want to change the current value of that and I want it to be the current value but I want to take off the last position so I can do that by signaling this as the index great and to touch up I want one more but it’s going to trigger no matter what so if I put an else here now that we understand that each of these are a condition we also need to understand that I can only press one button at one time all of these are a part of one condition instead of saying if let’s say also if or El if our final else we can say the current value is going to be the textbox value and let’s just say our textbox set text our current Value Plus text now remember text is going to be a button value so if it’s not an equal sign if it’s not the clear button if it’s not the delete button then it’s going to be a number or an addition symbol a subtraction symbol we want those to appear in the text box that is what this else is doing this is adding numbers to the text box as we click them this is our overall function and the functionality to it we just need to connect our buttons to this function and we have a working app going down now let’s take away all this space we can turn back on this event and I’m going to put in here the name of our function which is button click at the bottom here right before we execute our app let’s take the clear button that we made let’s say when that’s clicked I want to connect also to button click and when the delete button is clicked that can also connect to our function button clicked looking great amazing all within 80 lines of code just about we have a working calculator app well let’s check that it’s working that was our final stage of the basic form of this app all right let’s go down here let’s say 55 * 62 equals wow there we go looking good minus 36 equals great clear that works choose we can delete amazing well done coming from the first warm-up app that we created you were introduced to these basic concepts of design and how we set up a template app in pqt this is your first real world application in your first project this calculator app very nicely done what we’ve learned here we’re going to continue to build on in the next video we are going to learn how to refactor this code as a class-based application I’ll see you you guys in the next [Music] lesson as we enter this lesson let’s address who we did in the last lesson we completed the basic functionality of our calculator app a fully working app in Python with pqt using this framework now in this video we are going to learn how to refactor our code into a class-based application why is this so important well pqt is already structured in classes as you can see here with QT widgets it’s everything we already have so you should feel confident and comfortable creating your own classes methods and properties the second point is as we go forward in our projects they are going to become more class based focused as this course is designed to take your basic programming skills of python in object orientated programming and grow on that idea that concept of o or objectoriented programming as I’ve introduced how this framework is class-based it’s now time to start making our projects in a class right here is where we left off in our last video our app still functions I haven’t added any more code it’s now time to refactor we looked at this very briefly in the introduction lessons of this course but if there’s anything that you’re hesitant about feel free to check out my other objectoriented programming course or just go back a few slides and review what we looked at in order to do this let’s create some space here so pretty much everything I want to have in a class and the last two things I’m actually going to remove our app and Main window because those will automatically run here at the end so I’m just going to store them down here for now going up to our top let’s try and keep everything so I’m going to create a class and I can call this Cal app it’s my calculator app everything below we pretty much want inside of this class all righty I am now storing all of our original code in a place called class app now we still need a main window and as you saw I just removed my main window so how can I pass in a main window that my class can use well the obvious one that we may be thinking is Josh why did you just remove that well what I can do is I don’t actually want to do this I can take first off let’s uppercase that I can take Q widget and I’m actually going to inherit Q widget why can I do this well remember in pi QT all of these are classes so a class can inherit a class I’m using this Q widget as a super class I can now take that away I’m inheriting that I’m left with all of our starting code and this code starts as soon as the app starts so what is that special Constructor method that automatically runs when an object is called in it we need our initializer function so let’s say in it I’m going to put self I’m going to activate my super class so with our super function we can initialize the super class now that we have that let’s take all of this we’re just going to put that right there inside main window is nothing but now that I’m working with a class these are not variables they are now properties self is referring to the Q widget remember that originally I had said main window equals Q widget I’m inheriting Q widget so instead of saying main window it’s kind of like saying self my S is a q widget I am a q widget so I can say self. set window title instead all righty all the widgets we originally made I’m just going to come down here and let’s turn those into properties so self self and self looking good all righty uh let’s continue down you can see that I’m given an error Here in My Method this has become a method it’s now a function a class everywhere it says text box I don’t have textbox anymore that has become a property correct so let’s just add our key keyword self just like so and then pass in self as a parameter looking great missed one self going down this where we create our buttons that should be done at the start right that’s done through the initialization process so I can refactor that by putting that just directly inside our Constructor in it there we go looking good I’m going to give self here so self button click my grid has become a property self grid and our button list is now self buttons already going down our design once again when the app fires up in order to start the app everything should be done at the beginning so all of our design now that we’re working with classes I can remove this and I can put this inside in it once again I’m going to drop down here and let’s just drop it right there all of these we can tab over remember that anywhere we have main window we don’t have that it’s now self uh all of these guys have become properties going away from the variable form so let’s add self looking great all right so our class has been restructured and refactored let me clean that up so now in it initialize start when the app starts everything is done all the design is done right because that should be happening we then have our method Now button click that’s only triggered when we click the buttons and the reason that I can put my design before now is because this is a class the word self unlocks everything in our class that we can use anywhere we want we can go to our Bottom now for this to work if we ran it well let’s run it and let’s watch what happens it’ll make for a better explanation I get this massive window blank screen that doesn’t look right okay let’s close out what we need is we can use the python condition that we like to say so if the name if you’re running the main file is what this translates too if that’s the case then I want my app to run or execute I want to create an object I want to show that object now I am using Q widget remember we don’t need Q widget anymore because we gave this as the super class to our calculator app so this really should be Cal app main window is fine I can use that outside here running our app it’s now brought back to life 78 – 35 equals there we are a refactored form of that app through classes heading over to our last video now if you’re up for the additional bonus challenge we will be learning a new class that I gave you the hint of using Q font as well as the method of set style sheet to design your app a little bit more I’ll see you guys in the next video [Music] all right let’s add some design fonts and color to our application in order to change the font of our line edit and other tools let’s import Q font so I can say from PI qt5 this is from the qtgui module I can import Q font and Q font I want to use that to set the font of the text box so I can use the method set font and inside here you can see it actually says Q font so let’s say let’s put our Q font class in there as the argument to our method set font and I can actually put the type of font I want so let’s say uh helvetica as my font and then I’m going to style it as let’s say a size of 32 all righty so that’s step one we’ve styled that let’s go down a little bit and style the buttons so here we create a button here we create a button button event before we add it to our layout let’s style it so let’s use the method set style sheet so this is going to allow us to essentially use like CSS in pqt which is quite cool and wherever you are in your programming Journey you have probably come across CSS and HTML before if not this will be a great time to just briefly read through some of the CSS guidelines So within this method set style sheet I’m going to specify a few things and I’m going to specify all this as a string this is going to be just like normal CSS So within any CSS file we would typically put the name of the element that we want to affect so I want to affect a q push button that would be followed by a set of brackets or curly braces the first thing that I want to affect is I’m going to say font and I want to give it a font and I’m going to say this font is going to have be 25 pixels or a font size of 25 and let’s be creative here and let’s say comic Sands as our font style and then I would like to give a padding as well of let’s say 10 pixels to each button so I can specify that like that great so each button is going to have this styling to it all right we haven’t added the color we’ve given it a font size a font family as well as padding going down to each button now let’s take our Master layout and let’s set our margins so this is going to be a small amount of spacing in between all of our buttons and let’s say I want there to be 25 the right left top and bottom that’s the margins that I’m giving each button and I can justify it just like that finally to end things off let’s go down to to our bottom right here I create my main window object before I show my main window let’s set some styling to this now the question becomes what do we want to style I want to style my entire app and our entire main window is our Q widget so I can set that like so in here let’s just say uh background color and let’s give it background color so let’s say like uh o I don’t know these let’s say 1 two three interesting color it’s like going to be a really darkish black blue let’s try it let’s run our code okay so unknown background color and that’s because I spelled background wrong you can see the comic SS taking place that’s really cool let’s go down uh background and I also noticed one more thing that we didn’t put in O okay so far too dark right I’m not I’m not a fan of that I’m going to change a few details let’s give it like a lighter color and I actually have a color right here and also my delete button and my clear button they did not have any styling to them I’m going to go up so I actually create them right here I have my self. CLE property and myself. delete and both of these are going to be our buttons for each each button let’s say self. CLE let’s say set style sheet I’m going to actually take this because I want the same properties as my other styling great we can copy this and for our last one let’s just set our delete button running our application there we are it looks amazing it looks much better than the last product we had congrat congratulation that is the completed calculator application for our course going into the next project let’s take what we’ve built here and build on top of that and create an app that’s going to add even more functionality that we can use in real world situations I will see you guys in the next lesson for our second project [Music] Welcome to our next project in this project you’re going to learn how to combine multiple modules to build an interactive photo editing app in Python with pqt and the pill module let’s dive in and let’s take a look at what this app is going to look like and what it’s going to be able to do Here’s the final product of what we want to get our app to look like what can this app do well we can select an image from a folder from the desktop we can apply filters to the image before we edit it we can edit all of our photos using the tools that we Implement and finally we want to be able to save the photo we edit to our desktop pretty cool now looking at the app what widgets do you see in this app what widgets do you think we’re going to import from pqt to build out our design here we go how many of these were you able to get right hopefully all of them if you happen to miss any it would most likely be the Q combo box and the Q list widget as we haven’t used these widgets yet our Q list widget allows us to have a list of things within our app and then the Q combo box is essentially a drop- down box and this box drops down and it allows you to select an item from that box all the other ones you’re familiar with and you may be thinking Josh this is a picture why did you say Q Lael well we’re going to look at that closely but in the initial design of the app it’s easiest if we just set this area to something that’s not the picture yet so I’m going to say Q Lael in the future we are going to change the value of this Q label to become a picture the final a point we need to think about now how would you like to design this app what’s going through your head right now well so far you’ve learned three layouts we have our QV box which is for vertical or columns we have our qh box horizontal row and then from the last project you were actually introduced to Q grid layout what do you see how would you design our app how I’ve put it together is I have a master row this master row everything will be added to but instead of adding it individually we can create one two columns we can add the items we need to these columns then we can append it or add it to our row pretty cool now before we get into this new module pill which is going to help us edit photos with python and before we Implement any functionality to our app we need to focus on the design of our app so far we have created two projects you were introduced to pqt with our warm-up random keyword app in the last project you created your own interactive calculator I want you to use use the two projects and everything you’ve learned in these last two to create our initial design for our app here let me go back here’s a refresh of what you need to add let’s head over to the next video but before you do I want you to at least spend the next 20 minutes and I want you to try to design what you see here in VSS code I’ll see you guys in the next video [Music] here we are in vs code in this lesson we are going to set up our initial project for our image editor app let’s jump in and let’s set up our initial design starting things off what do we need to import here well let’s start with our design so from PI qt5 what widgets do we want to import well our two most important we have are our Q application let’s say Q widget what else do we need for this app well based off what we discussed in our lesson we’ll need a label we will put in some Q push buttons we have a Q list widget this will allow us to add the items we select to a list we have something called a q combo box let’s start to think about our design for the design we know we’re going to have some rows and we’re going to have some columns great I think that’s a good starting point for our wiek widgets for our alignment tools who remembers the module for alignment we can say QT core specifically I would like QT and we can start with that for our setup great I’m going to begin by creating the two objects that we need to start things off here so app and let’s say main window that’s our widget great I would like to set my app title so set window title and let’s call this a photo QT my version of uh Photoshop let’s set our initial size and I can say 900 and 700 great I’m going to jump down and let’s get our template shown so main window Show app dox execute I’m going to give it a quick run to make sure everything checks out before we jump into our design there we go great so it is working this is the size of our app and my template is all ready to go we are ready for the next part of our code Burger speaking of the code Burger let’s label a few things out to prepare us all right now that I have things labeled I’m going to jump here and I’m going to create all the widgets we want to see in the app now this can be in any order you want as long as we have them all So based on the app we’re trying to create I’m going to work left to right at the top we have let’s keep it with good name so I have a button for my folder and this will allow me to click and access my desktop so that button will say folder under that we have our let’s call it our file list and this is is our qless widget that’s going to contain all the files within the folder that we select we are going to have all of our editing buttons so now comes the question of what editing tools would you like to add in your project you can read some of the documentation and be creative to what you would like to add I have selected the following so I’m going to create a rotate left button a rotate right button let’s have a mirror let’s have a sharpness let’s say gray is easier than black and white we have a saturation and we have a contrast I could say blur as well that gives our tools more ability for each of these there each going to be a q push button and each of those will have a string so let’s just go down and let’s add those great we have our objects ready to go what would you like your buttons to say so let’s initially say left WR uh we can keep all these variable names that we initially used we can just keep those that brings us to our next widget that we need to add I need a drop- down box essentially so I’m going to call this let’s say drop- down box and in order to get this into Pi QT when you’re working with this widget this is our combo box so let’s call this a filter box and I can say Q combo box now we need to add the items what do you want to see in the drop- down box ideally I want to see all of these in the Box to do that we can take our newly created object filter box and let’s use the method add item I want to add a sing single item to my drop- down box the first one will be my original so I need that because when I apply a filter I would like to have the ability to revert or go back to my original photo so let’s say original I am just going to go down through each button I created and I’m going to add that in here as well I now have my combo box with each of my buttons added in there which we will use to apply a filter with later very good my final item is I want to create an object for my picture and this is the actual area in the app that our picture is going to appear but initially we don’t have a photo so I just want to create an object that I can set as the initial placement in my app later changing to insert a photo initially let’s just say Q label and the label is going to say image will appear here we can just put that text like so awesome all of our objects have been created which leads us down to our app design the master layout for my app so I’m going to create a master layout and I want it to be a row so I will set it as a cube hbox layout within my master layout I know that I’m going to have two columns so I can create column one and column two let’s begin with our first column so what do we want to see in this column starting at the top I want to see the folder button and let me show you guys our app so this is what we’re aiming for in our design I want to see this button up top above my Q list widget my drop down box than all my buttons let’s add those to our column one the first thing we want is the button for folder next up we would like our file list this is the Q list widget I would like to see our filter box and directly under that I’m just going to go through and I’m going to add add each button that we’ve created up here to our screen all of our buttons are here and they’re added so column one is completed and column one contains most of our objects the only thing that we want to see in column 2 is currently it’s just going to be our Q label or the picture box because I want to give my picture as much space as we can so we have more editing space column one and column 2 is completed what is the next step of our code Burger well let’s take our Master layout which is a row and we can use add layout to add column 1 as well as column two to our Master row or the master layout the final piece of the puzzle let’s take our main window and let’s set the final layout to become our Master layout let’s give our app a run here’s the app when it’s loaded now it looks a bit strange and that’s because this left column is actually taking up the most room that only leaves a little bit for our image when in reality we want to flip this we want to have this the opposite way I want the First Column to take up the least amount of room possible and give our image the most space we can let’s close our app I’m going to kill my terminal in here I’m going to justify how wide do I want column 1 to be out of 100% let’s say column 1 is going to be 20% of the entire screen this argument is called stretch it allows us to justify how much of the screen we want that column to stretch when we run our app again we now have it exactly how we want it to all of our buttons are on the left our editing tools and our drop- down box has the options that we’ve added to it when we click one we will have this apply a special filter to our image to see if we like it before we go and we click the black and white button great our design is done and we’re ready to add the functionality to our app I’ll see you guys in our next lesson where we are going to discuss just how to do so [Music] now that we have our app all set up and ready to go it’s now time to introduce to you this new module that we are going to be working with this new module is is called the pill module or more specifically the python image library now before we Implement any of this code within our project I want to take some time to just play with the pill library in its own file we can break that down understand that then we can take what we learned and use that within our app let’s take a look at how this new module is broken down the python image Library allows us to work with real photos in Python so imagine the photos you take on your phone or your camera we can take those photos and we can edit them in Python and if you broke this down this is like a really basic version of Photoshop but the more we build on the more advanced we can make our apps and if you notice here I’ve actually put this how I structured the breakdown of the pqt framework and the pill library is actually quite similar pill is like a massive library or module and within pill we have other modules that we can import individually to achieve a certain task each of these modules contain functions and properties of their own this is very similar to how Pi QT is working we will be using three modules from the pill Library the first one is called image and this is a class that holds properties and methods specifically for working with pictures as files so you should start to think now okay how do we work with files in Python how do I I load a textt file or a Json file in Python think about that and get a head start the next class that we can look at is image filter and this is a group of constant variables that we can use to apply filters or rotate our images apply filters or rotate our images remember that and the last one is called image enhance we can use IM image enhance to enhance our images so if you’re used to photoshop or the editing tools on let’s say Instagram there are tools for saturation contrast and Vibrance we can use these with python and we can get those from the image enhance module now that we understand these three modules that we will use from the pill Library let’s take a look at a few code examples in what they they actually do behind the scenes here is some of the code that we’re going to be using and it’s not in any particular order except the first one and the last one because this is the overall structure we will use in the app going forward to kick things off we can import pill but remember pill is massive and just like Pi QT we don’t want to say import Star there’s too much happening so be more specific what do you want to import and what will you be using in your app I can say from the pillow Library import the image module class image filter and image enhance and this is the structure to import the classes we are going to be using in this app we have a method called convert convert takes an argument of an L don’t ask me why that’s what it is and what could convert does is it converts this image pick to a black and white image pretty handy pretty short and that can be done very quickly next up we could increase the sharpness of your picture now by changing the sharpness this is actually a filter we are applying to the original photo pick what do we want to filter well I want to apply the sharpen filter that is a part of my image filter module and it’s stored in a variable called sharp all right now we’ve seen the basic image module we’ve seen the image filter module now let’s look at the image enhance module if I want to make my picture more saturated or add color I can do so and how we do this is we create our variable and the value is we take our class image enhance and we apply a subclass color what do we want to add color to this pick this original picture and I can enhance that by 1.2 I say 1.2 because the picture begins at one so I’m increasing it by more or less 20% 1.2 if you want to mirror an image you can use your image class and you can use something called flip left right and finally to save a picture you can just use the pill save method we can link that to our new picture name and then our picture is actually saved within our desktop or within vs code now I asked earlier how do we open text files in Python and I wanted to get you to think about that because we can do the same thing with an image in Python we can use the python open function take a look at our code try and interpret what’s happening if you need to pause the video please do at the top we always import everything we are going to be needing in our code so because I’m using pill and images I’m going to import the pillow library then we can use the open function just like we do with text files with open the only difference we need to do is I need to specify what am I opening so with open I want to open a picture called selfie. JPEG and this picture I load I’m going to give it a nickname and reference it as pick so now anywhere I use this variable pick the value of pick is actually the picture we decide to open so I can show my picture I can then take my picture and I can enhance it I can add SE saturation to my pick it’s being passed down if we want to convert our pick to black and white the same thing I can take my new picture variable because I created that and I can convert that to black and white remember after we do something if you want to see it you need to show the new picture if you want to save it you need to save the new new picture but in this code did we save the pictures no we didn’t do you remember how we save a picture we need to use the save method I am saving this new picture black and white and I’m giving this new picture the name gray pick jpeg let’s head over to vs code in a new file outside side of our pqt app and let’s spend the next 10 minutes and let’s experiment with how this new library works and how we can use it to edit photos you are going to need a few photos you can use your own or you can head on to Google and find a few stock photos that we can use I’ll see you guys in our next video [Music] let’s take a step away from pqt you have just been introduced to a new module and this module is called the python image Library we use this to work with images in Python which allows us to open them and edit them so in this lesson we want to practice and introduce the steps we need to take in order to edit an image everything we learn in this lesson you will be implementing and using within your pqt image editor app all right let’s jump in and let’s import what we need so I’m going to say from the pillow Library I want to import image we need image to be able to open the image or do the basic edits to the image we are also going to be looking at a class called image filter this allows us to apply filters to the image as well as image enhance image enhance allows us to add contrast or saturation to a picture now that we have that I’m going to come down here and we want to open a picture so here I have the picture I’m trying to open I can delete this one right this is the figma logo I want to use this and I want to edit this in our main file I can put inside open my picture name whatever picture you want to use just drag it into VSS code so I want to open this picture and I want to give it a nickname and reference it as picture so every time I use this variable I just make picture it’s referring to the picture we’ve loaded in here but I can’t just open an image in Python I’m going to get an error open is meant for text files and Json files but because we’re working with the pill Library I need to say hey it’s actually image that I want to open and this image that I open I’m going to call it picture now that we’ve done that let’s just run a a quick test I can say picture. show and there we have it so it’s loaded up on our screen great I’m going to turn off picture Showdown let’s start with our editing techniques so a nice one to be introduced with is black and white let’s say that we want to convert our picture to black and white so I make a variable and the value of this variable is our original picture and I’m going to take that and I want to convert the original picture to black and white now that I’ve done that I can take this new image and I can save this image what name do I want to give this well I could just say gray.png save it when I run this I’m not showing the picture anymore I’m just saving the picture so it’s going to edit the photo and it should appear here great our code’s ran and it has appeared here I click that there we go our picture has been edited we’ve converted it to black and white it looks great let’s play with a few more going down what is another one we could look at well let’s say we want to rotate or mirror our image we looked at these during the lesson I won’t be doing all of them in this video so I encourage you to use what we just learned from the lesson and try the ones that I don’t talk about about here in our video Let’s make one for Mirror I’m going to say all right what do I want to mirror well I want to mirror my picture all right what do I want to do with this picture I want to transform it or transpose the picture great what do I want to do to it now that I can transpose it well I can take my image and I can say I want to do flip left right that’s going to mirror our image I can take this newly created image and I can save this image let’s just call it mirror.png running our code there we are with mirror and you can see the figma logo is actually flipped right if I go to the original it looks like an F for figma I go to mirror it’s a backwards F that’s awesome we just transposed and flipped our image with mirror we’re going to take a look at two more I want to use use one from each of the classes we’ve imported so I’ve used image and you can see how we use that with our open function as well as any type of rotation so if you want to mirror or you want to flip the image left flip right upside down we use the image class let’s say we want to apply a filter so a filter could be like blur or sharpen things like that let’s say we want to make the image blurry so I’m going to create a new variable called blur I’m going to take my picture and I’m going to apply a filter to that picture what filter do I want well I want blur and that it comes from the image filter class so I can say blur just like that we then take it we can save it give it a name of blur and we can run it now it’s quite tough it is blurred it’s just quite tough to see because this is an SVG image there we go that’s blurry all right looks great I’m going to do two more now and both of the next ones are actually going to be from the image enhanced class we’re going to talk about two ways we can do this I would like to begin with the contrast so I would like to add contrast to my image this is equal to our image enhance contrast what do you want to add contrast to my picture okay so I am telling python that I have a picture called picture and this is what I’m going to add contrast to it’s now called contrast I’m going to take that variable contrast and I’m going to say it’s now equal to the original contrast but I want to enhance it you photos start on one every photo is one a good starting point once we get into coding our app will be like 20% so 1.2 would be 20% contrast for this I’m going to go all out I’m going to say 2.5 that’s a lot so I’m adding a lot of contrast I can then take this new image let’s save this new image let’s run our code look at that that is a lot lot of contrast added to our image and it actually looks pretty cool we’ve turned all of our colors if I go to our original we came from that we went to that so you can see the power of this and the power of editing these photos I’m going to do one final one now what you see here is you see a lot of repeating actually there’s nothing wrong with this this is easier to understand especially when you’re first introduced to this module but we could do this a faster way as well now I’m going to create one for color I can say the value of this is image enhance this time color what do we want to add color to my picture instead of going to our next line I can just link my enhance method here it’s the same exact thing let’s say 2.5 again that’s a lot of color in our app right let’s just try 1.2 because we will be be able to continuously click the button to add more if we want to for here 2.5 we can take our color and we can save that new image as color PNG you can name your images anything but the extension they end with make sure it’s the same extension as the image you originally loaded I’m ending with PNG so I’m using PNG when I save the images let’s run this for the final time you can see how much brighter that got we added so much more color in there looks great we have just gone through and we’ve introduced and played a little bit with photos before you head into the next video I would like you to go find three photos these could be photos that you’ve taken off your phone that you want to try editing or photos online spend the next 10 or 20 minutes programming out a few more edits you can use what we talked about in the previous lesson or you can Google and do some research and read the pill documentation what can you find anything you’re able to add you’ll be able to add in your image editing app I’ll see you in our next lesson [Music] now that you understand how the pillow pill Library works it’s time to implement this to our photo app and in our last project the calculator app as a bonus part of the creation of that we did a refactor challenge where you refactored the app into a class-based application we are going to start from the get-go right now in creating our image editing app as a class-based application here I have two bullet points and each of these are actually two different methods that we need to create and I’ve worded these out before we look at the code to get our minds thinking about how this can be done and after I go through this in a file in vs code I want you to just type your ideas out spend 5 minutes what would you do what do you think is right to solve these we need to create a function now we want to create a function that’s going to filter through two two lists the first is a list of files and this will contain all of our photos and the second list is going to be a list of extensions so think about that what extensions do photos end with what we want to do is for every file in our file list we want to check to see if the file has one of the correct extensions now our photo extensions should have either jpeg PNG or SVG as there’re in image if they do indeed have one of those extensions we want to add them to a new list that we create within this function now as a hint I’ve given you a part of the code because this is a new pqt method we’ve never used before I can use this with a condition and I can say if the current file name I’m looking for ends with the current extension I’m looking for we can append it to a new list you’re going to start to see a lot of new methods actually I will do my best to explain them here in the lessons as you implement them into your code now that we have this first function done our filter function we want to create a function that gets the current working directory now if you aren’t familiar with the directory that’s okay let’s introduce you to that now you’ve probably seen this before in vs code when you run your code in your terminal it displays something like this right and this is basically where are you within your computer system users is like the main starting point at least I’m on a Mac the main start of a directory on a Mac is users then it’s the current user so what this would say is my path I’m on a Mac in the user Josh on the desktop in a folder named folder one in a file called main.py right that gets where I’m at and that’s called our directory in order to get my current working directory with pqt I can make a variable and the value is a q file dialogue and the method is get existing directory now Q file dialogue that’s a q do we import that what do you need to do for that think about that this function calls the filter function and we add the file names to our Q list widget on the app screen so this new function that you’re making is actually going to call the first function we made and it’s going to take those file names and it’s going to add it to our Q list widget as a hint here is the actual code we’re going to use this is the filter function we just made and it’s taking the current working directory with our extend iions this is our class in the last slide we introduced the two functions we need to create outside of our class which we are going to use to give a path or give a file to our class we Define four properties from the beginning because I know taking a look at some other important methods we need in our class we do need to create a method to save our image but don’t worry because we can still use the pqt or the pill save method but I want to create a method that is going to allow us to do so when we want to save an image we have to check right here I need to check if the path that I’m am trying to save my image as already exists so for example imagine you have a picture on your desktop called background then you try to save another picture as background we can’t do that you can’t have a picture that has the same name because they need their own unique path so first we want to check right here if the path already exists or the path is the current working directory if not then let’s make a new directory that’s what that says right there we can make a new directory and we can join that path with our picture then you can save that new picture awesome that brings us into actually loading our image so in the last slide we loaded a file but now we need to take that file and we want it to show as an image so how can we do that well let’s create a new method to show this image and this method will take one argument which is actually going to be a path where is this file we’re trying to show located remember in the original opening of the app we said the picture was going to be a q label so let’s hide that Q label it’s now time to show an image we can use the Q pixmap class from the QT GUI module and we’re going to give it the image we want to load which is our path once we have this image we want to give it a width and height which it’s just going to take the width and height of the CU Q label in our screen and then we can set the image and show our image set pix map and qpx map are coming from the module qtgui you must import qix map at the top of our code from this new module now that we pretty much have everything our class in the app generally are going to work but we cannot edit our photos remember if we click a button we want to have the ability to edit the photo based on the button we click we want to take what we learned just in the last lesson while you were experimenting with the pill library and bring that into our new application here is just one example of one of our methods so let’s let’s say we want to add saturation or add color to our image I create a property called self. image because remember my class has these properties we made at the beginning inside in it and it’s going to be given one photo in our class this photo no matter what it’s called we can call it and reference it as self. image the value of the image for this method is exactly what we saw before remember when we were introduced to the pill library and all the new code this is the same code the only difference is we are changing the name from pick to self. image all right after we edit the photo we can then call the save method that we just made we want to save our photo and then finally you want to show your new photo because this photo is new you need to generate a new image path remember let me go back actually I’m going to go back to the very beginning here we created a new folder called save folder this is the new path we need to use this now while we’re loading our new image I need to join together my current working directory my new save folder in my new save file all of these final three lines in every method you make are going to be the exact same you can copy and paste them because every time you edit a photo you want to do the same three things you want to save the image and you want to show it the only difference in the methods you are about to program you need to change what you want to do with that photo you can remember this and you can go back a few slides and look at what we did in the last video finally to tie everything together you need to link your buttons or your events do you remember from the first two projects how do we connect our events in pqt the object has the value of the class that we just made we can take the folder button and we can say hey python when this button is clicked I want to connect to the function we first made that allows us to choose the work directory then once we load all of the images we can take our file list and I want to access the image that I choose from the file list to do that we can make this new function and we can check if we select one of the items from the file list if we do we want to call the load image method we made inside our class editor this final function is responsible for loading the image we click from the Q list widget we have done a lot now before going into vs code you should go back through and review a little bit here and take some screenshots try and put all these pieces together in debug on your own I’m about to head over there and I’ll see you guys in the next video where we’re going to add the functionality to our image editing app I’ll see you guys there [Music] now that you’ve been introduced on how we’re going to add functionality to this app let’s Jump Right In and let’s do so to kick things off let’s focus on what we’re going to be doing and we want to be able to click a button and unlock your desktop or access your operating system and through this you’ll be able to select a folder from your desktop that we can open its contents and display within the app to open and unlock our operating system in pqt or python in general we are going to import the OS module OS stands for operating system we use this when we work with operating systems and finally in order to get an image into pyqt5 we are going to import something called Q pixmap qpx map comes from the qtgui module great we have imported OS and we have imported our Q pixel map looking great where are we going to add the functions and our class within our code well let’s go down to the very bottom all the functionality that we want to add will take place before the show in the execute methods so let’s jump in right here what do we want to do well I know that I want to filter the files and extensions we know that we want to choose or get the current uh work directory so where are we within our system those are going to be the first two that’s going to help us so let’s create a variable and let’s say working directory I don’t know what that’s going to be yet but I’m going to need that variable and then making a function for filter so filter is going to take a bunch of files and it’s going to take a bunch of extensions remember that these extensions are what our photo ends with so jpeg PNG SVG something like that I am going to create a list here CU I want to go through these files and extensions and I want to check that if they match if my file ends with the correct extension I can add this to my list let’s Loop through and let’s say for every file in all all my files I also want to Loop through every extension in all my extensions if the current file that I’m on ends with the current extension I’m on that’s a good thing I want to append that file to my new list once my Loops are done we can return my list okay so let me translate that I’m creating a list and I’m giving this function a bunch of files and a bunch of extensions I’m going to Loop through and I’m going to say for every file in the list of files it was given for every extension in all my extensions if the current file I’m on ends with one of the extensions I’m going to add that to this list and then finally return this list I want to use this function within another function I need to create a function that’s going to allow me to access my current working directory I’m going to say get work directory this is not going to take any arguments what I want to do here is I want to access this variable and because it’s on the outside and I want to change the value let’s make that a global variable in order to get my current working directory we are going to use a class from pqt called Q file dialogue let’s go up to the top of our code and let’s actually import it can be anywhere and I’ll say Q file dialogue just like so I can now use this in the function that we were just making get work directory so to access the current working directory I can take my Q file dialogue and say get existing directory just like so so now the variable working directory is holding my current working directory I’m going to create a list here called extensions and this is the list of all the possible extensions that my photos can have so I’m going to put these here for now and where these are going to go are they are going to be passed up to our filter function this is the list we’re giving and this is the list that we are going to Loop through because these are the accepted extension names every photo if you take it on your phone or if you take it on a camera it’s most likely going to end with one of these extension now that I have my current working directory and I have my extensions I’m going to create something called file names this is just a variable but its value is going to be whatever I return from this function so the value of this variable is going to be a list results that we get back what arguments do I need to give my function well we need to give it all of our files and all of our extensions where are we going to get all of our files well it’s going to be our current list directory or our current working directory so I can access my operating system and let’s use the list dur method function from the OS module and I can just give it my working directory that’s the first argument this argument is the same thing as my files the second argument I’m just going to give it my list that I’ve just created of extensions all right this looks good once we’ve done that I want to take my list where do we want these files to appear in our app well the correct answer is the Q list widget that Q list widget we have named file list right here I want them to appear here so I want to make sure that I have a clean slate or an empty list before I load in these new files going down let’s just say file list clear remember the clear method we learned this in the last project I’ve cleared my file list and I can now Loop through my new list file names remember that this is a list because the value is the list that we return so my list is called file names for every file name in my list of file names what do I want to do well I want to add every item that I come across to my file list just like so amazing all right we are so close here so we have our three starting functions we’re close to testing our app but we’re not done just yet all we need to do to run a quick test is let’s connect the button so let’s take our folder button and let’s run a quick test let’s use our clicked event so when the folder button is clicked I would like to connect to my get work directory function let’s run our app I’m going to click the folder button and try to load something from my desktop it’s working right so when we click the folder button we unlock our desktop you have the ability to go and select the desktop and choose a folder you want you just have to click the folder one time and click the open Button now everything within that folder I have loaded in my Q list widget these are all PNG photos you could have jpeg you could have anything that we specified right here as an extension awesome the app is looking great I want to have the ability to now click one of these and have it load over here how can we do that well let’s carry on and let’s solve that to do this we want to create our main class our class that’s going to store all the methods we make as well as be responsible for programming all of our buttons I’m going to close this I’m going to create a class and I’m going to call this editor editor we do need to have our Constructor and we need to ask ourself what pieces of information do we want to have inside our Constructor and not even inside the Constructor what information do we want to have access to within our class well I know that I’m going to have an image currently I don’t know what it is but it will have a value I will have one called Original and original is going to be responsible for holding the original image that we can go back to at any point in time I’m going to have a file name and lastly I’m going to have a save folder Where do I want these new photos to save this will be an extension of your current path so let’s just call it Edits edits is going to be the name of a new folder that we start to save things to let’s start with all the important methods we need a method to load images to save images and to show images let’s start with load an image this specifically will not actually load the picture in the app but it’s going to load the file name that we can take and then we can load that file name into our app as an image this method load image is going to take self as we need to remember self is like a key it unlocks our class and it will also take the file name that we want to load in our app let’s turn that file name into a property so I actually already have my property I am taking that same property and I’m changing the value To None to become whatever we give this function so my argument becomes the value to my property self. file name all right great next we need to create a name so the full name of where we’re trying to access and I can do this by connecting pieces of our working directory to do this we can access our OS module and we can say I want to join together I want to connect two paths or two directories together so OS path join I want to join together my working directory of where I’m currently at and my file name just like that after I have this new path called full name we want to open this so I’m going to take my property self. image that we’ve created up here currently its value is none who remembers how do we open an image I want to use the open function but I can’t just use open alone I need to use the pill python image Library so let’s go to the top of our code and let’s actually import pill I’m getting ready to use it from pill I want to import image what else will we need for this well I might as well import my other two classes now as well image filter and image enhance look at this we are creating this app and we have used three modules I’ve used OS I’ve used pqt and I’ve used pill they’re all working together to create a single application pretty cool now that we have image let’s return to our class I can say image. openen there we are what do we want to open well I want to open my full name right this is that path I want to open this image now as a file we have our image and before I edit the image or do anything I want to make a copy so I’m going to take my property original right here currently its value is none but I’m about to give it the value of my current image that I just loaded what do I want to do with this current image I want to copy this image now anything I do to the pictures through editing I always have a copy of that original image load image is done what is the next method that we want to do well let’s make one to save our images that’s what this is going to be responsible for every time I edit an image I want to have the ability to save this image within our new save folder how can we do this well let’s create a path and let’s say this path is equal to a join path and we can join together our working directory and at the end of the working directory I want to just link on the save folder so for example if my current directory is users SL job SL desktop now I’m going to link on my new folder edits right here that’s what we’ve just connected those two together we have our path I now need to check to make sure that this path does not exist so does this path exist or is this the current path so OS path is dur is the current directory okay if it’s not I am allowed to make a new directory with that name of my path I can create a full name again and just like before let’s say OS path join but now the question becomes what do we want to join together well I want want to connect this New Path I just made and at the end I want to connect my file name that property we can take our image and let’s call the save method what do we want to save I want to save my new path that we just made amazing all right we have our load image we have the save image before we do any type of editing we need one last method to get everything working this method is going to be responsible for showing our images so let’s call it show image this will actually allow an image to appear within our app screen this will take the path of the image that we are trying to load the first thing we need to do is the place we want to load the image is at actually a q label we don’t want to see that Q label anymore so our Q label is called picture box let’s hide the picture box taking that away from our screen next up let’s create an image and this is going to be an object of our Q pix map class that we just imported qix map allows us to load images into Pi Q UT it takes an argument what do we want to load well this path so I am giving a path to this class qix map and QX map is converting this path to a real image that we can show the next question becomes how big do we want this image well let’s actually load our app again I want the image to take up all of this space this space remember is 80% of the screen and we said that because when we created our layouts up here I Justified it as 80% of the screen so column 2 is 80% in column two it only holds our picture box in our show image let’s create two variables width and height let’s say the width is going to be the picture box width that’s literally the width of the whole column two and the height can be the picture box height and that’s going to take that what can we do with this now well I can take the image that I’ve created right here in line 119 and this image I want to scale it so I’m going to take the image and I’m going to scale it how big do I want to scale it well I now have a width and height that that I can scale it too an image that we load could become distorted and I don’t want that I want to prevent it from being distorted or weirdly deformed in any way to do this I can actually use the QT module and remember in the past we have used QT for our alignment well here I can use QT to keep my aspect ratios of the picture this will prevent the picture from being deformed in any way we now have an image that we are ready to load I’m going to take my picture box and I’m going to set pixmap what picture do I want to set to the picture box well my image my image is now set to the picture box but remember originally we hid the picture box let’s say picture box I now I want to show you again everything is done before you run the app this is all within a class so this isn’t going to work just yet we need to do a few more things on the outside let’s go on the outside and let’s create one final function this function is going to be responsible to display the image that we click from our file list so whatever image we click in this function we want to check to make sure that our file list actually has items in it and so I’m going to say file list the row has greater than or equal to zero there’s something in the file list if that’s the case I would like to get the value of an item that I click let’s create a variable called file name and we can say okay the file list. current item this will be the current item that I click on I would like to get the text value of that item and I want to use my load image method right here because I have a file name right I just made that I’m going to give this file name to my load image method how can we do that it’s a method well before moving on I’m going to create an object let’s say main I’ll say editor all right I have my object I can say main do load image now what do I want to load well my file name then I would like to show the image that I’ve loaded what do we want to show well I want to show my OS path I need to join together the working directory with something else with my main file name I need to connect those two this will allow our image to load great the final stage is we have an event for our button well now we want an event for our file list so I’m going to say file list when the current row is changed we want to connect with our display image function amazing let’s give our app a run the app is working I’m going to go through and select a folder now that I have the folder selected I can choose one of these images boom look at that I have loaded an image into my app I can select any of these images and they are loaded into our app this is great well done the functionality is coming together what do we have left well our buttons don’t edit these photos so let’s head over to the next video and let’s add the editing power to our app I’ll see you in our next [Music] lesson [Music] our app is coming to life in this stage of the creation of our app it’s now time to add the functionality for the editing so when we click our buttons I want to be able to add more color to a picture or convert a picture to black and white let’s program all of our buttons let’s scroll down to our class editor and in our editor class we have our load image method that’s great I load an image I can save an image we have show an image I’m going to go down here and I’m going to start to create all the editing tools we have so let’s just start with our first method and I will call this gray now this method we are going to program and it’s going to be very similar to the lesson we had that introduced you to the pill module if you go back a few lessons to the lesson that we spent time practicing and introducing the python image Library we want to use the same idea and the same Core Concepts in programming our methods so I’m going to take my image remember we made a property called self. image this currently holds the value of the image that we loaded into our app and I want to change that image I want to convert this image so I can use the convert method and give it the argument of L so I’m changing the image to Black and White Once I have this new image let’s say self and let’s call our save image method so I can save this new image into my edits folder that we created it next up I need to create myself a new image path because I want to show this new image and this new image it has A New Path because we generated a black and white image and we saved it into a new folder with a new name this new image path well I want to take my path and I want to join together what do we want to join together well my working directory with my save folder with my file name that’s a new path we can now take our show image method and we can

    show this new image path that’s it that’s our gray method we edit our photo we save the new photo we show the new photo that is what’s happening in this editing function now that we have that the only thing to do to test if this is working is we can go down and we need to create all of our events the final step is I need to take my black and white button when that’s clicked we want to connect to our gray method that’s inside our class we can now give this a quick test before we write any other methods I’m going to select a folder now that I’ve loaded everything in let’s choose one I’ll choose a colorful one here okay this is pink I’m going to click my black and white button ah voila it is working it has been converted to black and white that’s great all right let’s work on the other buttons I’m going to close my app let’s trash the terminal now all of the methods are actually the same thing except what we are doing to the image but the idea of saving the image creating A New Path and showing the image that’s the same for every button so for example if I just take this method and I’m going to paste that here let’s change this to say uh left and take our image now and let’s change what we want to do to it so do you remember how do I rotate an image left right well I can take my image and I I want to transpose that image as the argument I’m going to take my class and Link the property rotate 90 that’s it we have a new method it’s the same exact final three lines we just need to now connect our left button all right I want you guys to pause the video here and I want you to program the rest of your buttons use the knowledge you gained with the python image library and use the knowledge from these first two methods to complete this challenge pause the video now I’m going to go through and I’m going to program the rest of these I’ve just finished up programming the remaining methods and as you can see here we have our gray left right we have mirror sharpen blur color contrast they’re all doing the same thing in the end the only difference is what we’re doing with that photo specifically the final step is each method needs to be connected to its button at the bottom of our code remember take our button when it’s clicked we want to connect with one of the methods that we made for that button everything’s working let’s run our app and at this stage 80% of what we’re trying to accomplish is done here’s my app I’m going to load a new folder now that I’ve loaded the folder let’s start with python so I can click left o there we go let’s click right that’s working mirror it’s flipped it our buttons are working we’re editing real photos with our code let’s do color if I keep clicking it you can see that it’s getting brighter and more colors being added if I click contrast it’s contrasting and then finally blur will be oh it blurred well I thought that may be tough to see with the python image right if I take it I click blur again it’s become blurry black and white loses its color our app is coming together and this is the most advanced app that you’ve created yet the last thing we need to do is we need to program this filter box to apply a filter remember that we can apply a filter it’s not going to save that as a new photo we can apply a filter and see if we like it before before we edit the photo in order to do that we’re going to introduce a new and popular python topic which is slightly Advanced and that’s the topic of Lambda functions I’ll see you guys in the next video where I will introduce Anonymous [Music] functions [Music] as we approach the end of our project it leaves us with one final task of adding functionality we have not programmed our filters or the filter drop-down box and that’s what we’re going to look at here in this lesson but to do this we have so many filters I don’t want to create a method or a function for each filter cuz that’s repetitive and we sort of did that just in our class I want to create Anonymous functions that I create and I use them right when I create them those are called Lambda functions this special feature comes with python and it’s for creating Anonymous functions which are these special functions that don’t really have a name most of the time when we create functions we do Define a name so we can call on them later but with Lambda functions we create it right where we need it and we call upon it immediately to run so they don’t need a name this is called Anonymous functions or in our case with python Lambda and this is a slightly more advanced topic that we are getting to explore let’s check out two live Lambda code examples I’m going to explore the first code example up here I have a function called Cube and cube is an anonymous function cuz yeah in this case I have given it a name but when I call this it’s going to run instantly now I’m saying it’s an anonymous Lambda function and I’m giving it something here this something is used in our expression what could these be in Lambda Lambda is taking a single parameter in this example I am justifying a single parameter and then that parameter is used in the expression of the function or what we want to do so four is really saying 4 cubed let’s add some color coordination in the bottom example I’ve actually written out a scenario so imagine you have your math problem you’re trying to solve by multiplying two numbers instead of writing a function for this somewhere in your code I am writing the function in one line right when I need it and that’s going to solve this specific problem now because we’re multiplying two together I am giving my Anonymous Lambda function one two parameters if I have have my two parameters we’re giving it two arguments when we use it these are being used in here so if we ran our code what would be the output of both of these Anonymous functions well the first output would be 64 and our second output would be 15 so you kind of have a core understanding now of what is Lambda what it accepts and how we create a basic Lambda function but how can we use this our project well let’s break that down a bit more our mission with Lambda is to create an anonymous function for each filter that we have in our Q combo box so I’ve kind of given you a head start but how could we do this with a dictionary because it seems very repetitive and I’m going to have a lot of these filter options so instead of creating these in seven lines or however many we have why not store them in a dictionary now remember a dictionary key value and what this would translate to is dictionary key unlocks a value so we can use that to structure our dictionary hm that’s interesting what would this look like in our code here I create an instant Lambda function and when this is used it’s going to be executed and ran immediately this is a dictionary filter mapping and remember in a dictionary we have a key and every key has a value together these are called our key value pairs so the key is actually the text from our drop-down box and the value is this Anonymous function that’s going to take an image the image that it takes it’s going to convert that image to black and white that is really interesting that makes our code run a lot faster and it allows us to create these little functions that we want to call upon throughout our program and you can see for every item in the drop- down box I’m making a key value pair which represents the drop- down box name and a Lambda function here is the overall function so let’s say we create it and we name our function apply filter I am going to give one parameter of a filter name this is the name that we select from the drop-down box if I click black and white then black and white is going to be given to this method the first thing I want to do is I want to check if I chose original because if I did I want my image to actually be the copy that we first made when we loaded the image I want to revert to the original copy if we do not choose original it must mean we did something else so here is our dictionary of everything else that we have the ability to choose from our drop down box each of these Keys has an anonymous function that will be executed instantly and they all take the same parameter image which you can see are being used within the anonymous function now this dictionary nothing is happening if we get to else we are going down here and we’re checking right we want to get whatever the filter name was from our dictionary remember that this filter name is actually the parameter that we gave we can check to make sure that yes we do indeed have text from our dictionary and we can go about our day we can set our image to whatever image we chose from our dictionary we can save that image generate a path and show the image just like how we created our methods in our class inserting the dictionary taking the value of the filter function is whatever the Lambda function returns if Lambda returns something we want to show what lambdaa returned let’s jump back to our code and let’s implement this final apply filter function and get you guys reading your first Anonymous Lambda functions I’ll see you in the next lesson [Music] now that you’ve been introduced to Lambda in Anonymous functions let’s create a method that’s going to store many Anonymous functions and these functions will be responsible for applying our filter let’s scroll down to our class and in our class we can go pretty much towards the end actually let’s go all the way down before the final one so I can go right in here let’s create a method that I could call this apply filter needs our word self and then what do we want to give it well I’m going to give it a name more specifically whichever word that I choose from the drop- down box I want to take that text value and I want to use that within this method so I’m giving this method a text value from my drop down box let’s just call this filter name the first thing I want to do is I want to check if my filter name is equal to original because if it is I want to revert or change the image back to the initial starting image I can do this by saying okay cool self. image in that case is equal to self. original. copy so our image is equal to the copy that we generated earlier great that’s why made the copy to be able to go back to the original copy else if it’s not original then okay I have selected something that I want to actually apply a filter on now in our drop down box if I were to go check we have all of these so 2 4 6 I have eight different options and each option is going to be able to do something or have its own function so the best way to do this would be to create a dictionary where each of these would be my key and the value is going to be a function that’s triggered only one time that’s why we create a Lambda or Anonymous function I’m going to return to our method that we’re making and let’s create a dictionary let’s say mapping now I need a key in the first key let’s just start with black and white and let me make sure these the text value needs to match what we’re trying to do so black and White’s good make sure your spelling is consistent returning black and white and the value is now going to be a Lambda function so to create a Lambda function we’re going to use the word Lambda then I need to justify any parameters my function will use the parameter well it needs an image that it’s going to edit so this function doesn’t have a name because it’s only being called when I get to here so it’s a function it’s a Lambda it’s Anonymous it has no name but this Anonymous function it does have a parameter which means I’m going to give it an argument next up in the function it is going going to take what I give it and it’s going to convert that image to black and white that’s what it’s going to do one and done all right so next up let’s try one more together let’s say color color is going to be a Lambda function it takes a parameter of an image let’s take what we give it and let’s say image enhance do color what do we want to enhance the color of well the image we give it how much do we want to enhance it by let’s say 1.2 just like when we programmed our method above right here same thing I have now created two Anonymous functions I want you to try to program the rest of these Lambda functions on your own pause the video here I’m going to go through and I’m going to complete the rest of these Lambda functions what do we want to do to that photo the New Concept though is creating an anonymous function now remember that this Anonymous function is a special python function that doesn’t have a name and it can perform any task we assign it without needing a name as well so I am giving a parameter of image and we are taking whatever we give it and we’re going to apply and edit to it great so I’ve created this dictionary now and my dictionary is called mapping well I now want to map over this and I want to get one of these I want to get the one that is equal to my filter name let’s create a function let’s say filter function and the value of this is I’m going to take my dictionary and I want to get what do I want to get well I want to get whatever the filter name parameter of this method is that’s the value of filter function I now want to check to make sure that there is a value that we selected so to do that I can just say if filter function right that translates to if filter function equals true or if there is something in our filter function if there is what should we do well let’s take our image right our property self. image and we’re going to say hey I want to update this and I’m going to update this to the value that we gave our filter function self. image I can then save let’s call our save image method I can create an image path just like we did in our initial method so OS path join we want to join together many things working directory our save folder and then finally our file name what do we want to do last well then I can show this new image that we have kind of created or at least applied the filter to so image path uh finally if that fails let’s just say pass I want to skip over it so our apply filter function or I should say method is done we have a method and this method contains about eight other functions which is incredible now that most of the supply filter method is done we’re pretty much there outside of my else right so no matter what when this condition is done running I would like to save the image so let call our method we made save image let’s take our image path and let’s show our image so I’m going to take those and I’m going to put those just like that right there looking great we want to create a function on the outside to handle any of this so let’s say let’s create a function called handle your filter and the first thing we need to do is we need to make sure that indeed there are items that have been loaded into our Q list widget so just like we did in the other one let’s make sure that we have an item what do we want to do with that item well I want to get text so bear with me Whatever item I click from the drop down box I want to get that text in order to do that with a Q combo box or a q drop-down box we do not use the text method instead what we can say is let’s take our filter box and let’s use the method current text now that we have the current text value let’s call the apply filter method giving it the text that we just created or got our final stage is we need to create our event for our handle filter method we can take our filter box and we can say hey when current text is changed we want to connect to this new filter function now the current text the current text is initially original because it’s the original photo when we change that all right now we want to trigger this event amazing let’s run our app I can now load in a folder and let’s go through and choose one of our images so let’s choose a this will be perfect in my drop down box I can now choose how would this look as a black and white image oh that looks pretty good okay let’s go back to the original great now how would that look if we blurred it well I can’t really tell right so I’m gonna go back to the original again everything is working this is great well done you guys have a completely working image editing app that we’ve created we have accessed our desktop using the OS module you’ve used multiple modules from pqt and we’ve used a few classes from the pill module as well to achieve this well done I’m so proud of you guys if you’re interested head over into the next lesson where I’ve prepared a special challenge using Lambda to extend the functionality of our photo QT image editing app I’ll see you in the next [Music] lesson congratulations we have a working image editing app for fully completed with the editing capabilities that we wanted as well as Lambda functions now let’s refactor our code and I’ve prepared a challenge for you guys using Anonymous functions to make our image app more efficient let’s take a look currently we have a class and our class has all of our editing methods in right so every button we have we created a method for I want to see if you can take all these editing methods and convert them into this can you replace all the buttons and how can we use Lambda to do so I want you to try to create a new method which is going to replace all of these you can name this method transform image or if you have a better name use that name this method will hold a dictionary just like our previous method with all these functions we want to replace or I should say update if you’re up for a good challenge this is better going to improve your understanding of how to use anonymous functions as well as using dictionaries I’ll see you in the video where we refactor our app and add in this final method [Music] you must be up for the lamba challenge if you’re here and I’m glad you are we’re going to refactor this code and make it significantly more efficient and less all while keeping the same functionality let’s take a look right here we have all these buttons and we want to create a Lambda function for each button this is going to be very similar to how we created them for the filter let’s take a look at our class we have our editor within here we have in it we need that we have load image save image show image we need to keep all those because they each have an instrumental task that is called upon at some point in our program but all the other methods the ones where we create the actual editing techniques you can see here that I have 1 2 3 4 5 6 7 eight we have eight of those what if we could replace all of those with a single function well that’s what I’m going to do I’m going to take all the methods that we just programmed and I’m going to delete them from my code what you can do before you delete is maybe make a copy to keep this and you’re able to see how far you’ve come and we have a starting point which is this and now we’re progressing into more advanced concept so I’m going to delete those we have our apply filter method currently now I have if we go down to all of our events we have none of these anymore right main mirror mirror is not a method we just deleted that let’s go up here just above our apply filter method we are going to make a new method here and we can call this transform image transform image is going to take something so transformation what do we want to do to the image if I click the blur button blur is my transformation it is very similar to how I explained filter name in the apply filter method inside here we will make a dictionary this dictionary is going to be structured the same way as as we did here so I can actually take most of these out let’s just copy those paste those here what do we have 1 2 3 4 five six seven eight those are all of our buttons as well and just double check that these text these strings all match your button names at the top and if I do a quick check they do match going back down to this new transform image function we have a dictionary inside that each of these is a key value pair the key is what the button says and the value is an anonymous function our Anonymous function will take an image and it will do something with that image we have all of our functions ready to go in our Transformations dictionary let’s create a a transform function and let’s just say I’m going to say Transformations I want to get the transformation I give as the parameter this is my dictionary I want to get something from the dictionary and I want to get the original parameter we passed into our method just like our apply filter method I’m going to check to make sure this is true I indeed have something because if we don’t have anything well I can’t quite do anything with it if I do though I’m going to take my image and I want to update my image this is now my image after we apply our filter to it we can save this new image finally we can show this new image just like that I have replaced all eight of of our original methods with a single transform image method all that’s left to do is we need to connect our methods to our buttons and because we’re using Lambda this is going to be slightly different where do we keep all of our events well they’re at the bottom let’s head to the bottom starting with our first button gray now I’m going to change what we’re connecting to we are connecting to a method but that method is a Lambda Anonymous method or it’s an anonymous function in our method transform image Lambda is anonymous I can take my main object that’s my class remember and to our main class we can link our method we just made which is transform image I now need to select one of the keys in transform image so if I go up here for the gray the black and white this is my key I’m going to use this in here I can just say black and white if I go to our next one I would do the same thing I would take Lambda and I would say our object let’s transform our image and I think we just called that one left if I go up and check yep right there left I’m going to go forward and program the rest of these all right we have all of our new Lambda functions connected that means it’s time for us to run our app all right and just right here so I’m trying to show an image but if we remember show image takes a path which I’ve left out here so let’s come out here I’m going to do a few things outside I can do save image again then directly inside let’s create an image path again and we can say OS path I want to join what do we want to join well I want to join my working directory I want to join my save folder that we have created so save folder and then finally our file name and we can just do a check does this match this it does our app is running selecting a folder going down to our images left great it’s working right there we go I can mirror it I can add color to it there we are contrast all of our buttons are working they look great amazing we just refactored our project to more efficient code you have been introduced to so many new Concepts in this project one the introduction to a new module pill the pillow library for working with images two you have now been introduced to Anonymous function in Python which I’m sure you’ve seen before these little guys are called Lambda functions as well as taking your pqt skills to the next tier amazing job congratulations I’ll see you guys in the next lesson for the start of our next [Music] project [Music] congratulations as we enter our next project you guys have done an incredible job you have so far three fully working apps with one warm-up or introduction app for pqt you have a fully working calculator applic and after completing the last project you now have an image editing app as we enter this project you are about to make an expense tracking app but this app is going to do so much more than just track your expenses and use your knowledge of pqt not only are you going to use and build on all of your pqt knowledge you are also going to get an introduction to SQL and how we can incorporate SQL databases into our app to track and maintain live data more specifically live data that’s changing so in the last project you got an intro to Lambda in Anonymous functions add that to the CV in this project you’re going to get an intro to SQL and what that is and how we can use that with apps let’s take a look this is our overall app overview our app we have the ability to add expenses delete expenses and also save data in a database and I want you to think what widgets are you seeing on the screen you should know most of these right we have been using these in previous projects so what widgets do you know well let’s take a look all of these widgets we will be using in our app and you can see right from the get-go there are two that you may be unfamiliar with as we haven’t used them before we have our Q date edit in Q table widget now you can see that the date edit is collecting a date we even have a category that’s going to allow us to choose what category our expense came from we have the ability to enter the amount of the expense as well as a description of what we spent it on we create two buttons and at the bottom here we have our visual database so this is the front end of what we see once we add all of our data using SQL to our SQL database have you thought about your design yet because as you’re growing more and more of an expert with pqt you should be thinking about your design every step of the way how could we design this app well let’s take a look I have created one map Master column and you can see I’m using QV box layout I have three rows at the top with a few objects in each row my table does not need a row because it’s going to take up my whole screen everything else I want is actually above my table while you’re designing this app you know most of the methods and the ways that you will be able to implement your designs but C table widget this is new and you will need to import this along with your other QT widgets in order to get your table set up there is a method that comes with our Q table widget class we have set column count and this takes an integer as an argument and you can see that in this example we have five columns if I put the number five inside here we will see 1 2 2 3 4 and 5 that allows us to structure our database and get it ready to accept data the second method that we are going to use is called set horizontal header labels this method takes a list more importantly this list is going to have many elements each element will be a string and the string will be the name of your columns if you say you have have a column count of five then in your list you should also have five elements each element is representing the name of your headers the name of your rows let’s head over to vs code and let’s try and get our app designed and structured before we dive into SQL I’ll see you over in the next lesson [Music] now that we’re here in VSS code let’s get our expense tracker project all set up and designed you can see here on the screen this is what we’re aiming for and by the end of this video we will have an initial design something like this ready to go let’s move that away for now I have here my code burger and what do we need in order to design this app well a lot of things but in this video we are just going to focus on one module QT widgets because we need to design our app first and that’s what we can start things off with in the previous projects we have created an app then converted that or refactored it into a class-based application well to kick things off with this project we are going to start by creating our application as a class-based application let’s begin here with all of our Imports so from PI qt5 QT widgets we have that one down let’s import our Q application we can import our Q widget what else do we need in our app so if we take a look at it what do we see here right I see Q labels I see q line edits I see our Q combo box I see an area for our date and time we have a table a few new widgets we need to import all of these so let’s begin I know that I’m going to have a Q label we saw a q push button there we saw our q line edits we can bring in our Q combo box then our two new ones we had a date edit window and finally let’s just come down here I’m going to say Q table widget now I’m going to put that back on the line there we are Q table widget anything else that we’re missing is there anything else we need well don’t forget QV box and qbox even if you don’t know if you’re going to need both layouts it’s always good to import them because there’s a high likelihood that you will let’s create our class let’s create a class called expense app inside we can create our Constructor as this is going to run immediately every time we create our app so when our program runs it creates an instance from our object and this init Constructor will immediately run we need to ask ourself what do we need well our main settings we usually like to use resize but I don’t have any main window and in order to get that let’s inherit just like we’ve done before let’s inherit Q widget now that I have q widget I can refer to myself and we can say okay let’s resize and let’s give ourselves a window title because we always want to give our app a title we can call this expense tracker 2.0 the window size let’s give it a size of 550 for width and 500 for height that’s a good starting point now we need to create all the objects we see on the screen remember the input Fields the table the date box all of those items so let’s create one let’s say datebox and datebox will be one of our Properties or an object that we’re creating now for the app UI and a date box we can say Q dat edit just like so we also have a drop- down box so let’s just say drop down and this is our Q combo box we have our amount which is going to be a q line edit and then we have our description an area that you can enter what you spent that money on and that will also be a q line edit now we did have text within the app but that’s going to create too many objects and the text I won’t need to do anything with that value so I’ll actually create it here when I create my design speaking of of design we need to justify our Master layout I can create my object Master layout and I know that everything here will be held in a column so let’s say QV box we have that and within that column we are going to have let’s say Row one row two and Row three bringing those down just remember to change the name of your property all right what else do we need we have our all of our input Fields I know I’m going to have a few buttons on the screen so our buttons will be an add button to be able to add to our expense so we can say that would be a q push button add expense we will also have a delete button this delete button will once clicked we’ll remove from our table we have almost everything that we want to see this brings us to our final and our new object we are introducing SQL in this project so with SQL I want to be able to display all my data within a table we are going to use our Q table widget let’s create a property called table this can be our our Q table widget we can do a few things with this in the beginning when I’m creating this table let’s take our object I would like to set the number of columns this will help us with our SQL queries and adding data at a later stage let’s use the method of set column count in here I’m going to to have five rows of data which we will see here shortly but that’s going to look like an ID a date category amount and description that is why we have five columns once we have this then we can take our table I’m going to call the method set horizontal header labels because I want to give a title to each column that we create this will actually take a list we can do this two ways I can say header names making a list what do we want our header names to be let me code these out I now have a list of my header names you can see these are my column names just like before I created five columns in column one that’s my ID column column 2 is my date our method set horizontal header labels that takes a list so header names did I have to make this no I did not I could take this I could just put this inside here like this how I did it before was easier for readability we have a table now with five columns and the columns each have their own name we’re ready to go what do we need now I have all my objects next up in our code Burger I can actually structure this so there we are we can design our app with our lay layouts what layouts will we be using QV and qh box let’s create a master layout that can be my QV box then within my app I know that I’m going to have three rows so Row one qbox layout let’s create the other two we have our Master layout along with our three rows ready to go now that we have these let’s go through and Design Row one I want to start with you I want to add some widgets to row one in case we forgot what we’re aiming for in our app in row one I’m looking for these date text the date time box our category text and our Q combo box notice I didn’t actually make Q labels and that was to save us space in our code as we aren’t going to do anything with these values vales so I can immediately add these to my layout what do I mean by that well right in here I can just actually add the class Q label what is this going to say well it’s going to say date like that so I’ve added my widget next up in my Row one I would like to add what do we want well I would like to add my date box after these we can add category text followed by our Q combo box which is what we called drop down so Row one is completed going on to row two it’s the same idea I can take this as a starting template and instead of Row one change that to row two our Q label that we’re going to be putting on which actually right here this should also be our Q label instead of saying date here we can actually say amount what do we want add next to amount well let’s add the widget and let’s say self. amount that was our property that we created here of a q line edit the final two all right row two is completed Row three we just want to add our two push buttons to them great our three rows are designed and all ready to go what does that mean what do we need to do with our rows let’s add the rows to our Master layout so take your master layout use the method add layout you should have this under your belt by now adding in row one we can copy that as we need to do it three times one two get them all set the only thing we have to do is change the layout that we’re adding so self. Row 2 self. Row 3 let’s set our final design usually we would do something like this but where is my main window I don’t have a main window remember my main window is my super class so I’m going to refer to my S and I can say self. set layout I want to set the master layout as the main layout all righty our design is almost all the way there currently there’s no table on the screen we’ve added our three rows to the screen then we did set the final design but right in between here before I set my final Design This is where we want to see our newly created table let’s add that but the table is so big I don’t need it in a row it’s going to take up the whole row itself it’s just going to go at the bottom of our expense app all we need to do for this is take our Master layout we can add widget and we can add our table because we have created our class base application let’s go on the outside right here and we can say if name in main we can create our app Q application give it an empty list here you could create something just an object and what is our app class expense app main. show app. execute let’s run our app and see if it’s set up the way we want it to be all righty so right in here it’s telling me that I need to activate my super class which that’s actually true I buzzed right over that going up remember anything that we pass in so I’m inheriting the super class let’s use the handy python super function and say hey super I want to initialize you just like that give our app one more run there it’s all taken care of here is our app ready to go everything is where we want it to in our three rows with our new table at the bottom spend the next five minutes and tweak any details you may want to tweak if you want to change the words change the header names change your alignment that’s up to you I’ll see you guys over in our next lesson where we will introduce SQL in pqt [Music] now that your app is all set up and ready to go it’s time to introduce the top IC of SQL and how we are going to use SQL light with the module QT SQL to work with our app in pqt if you’ve worked with SQL before great you have a head start and if you’ve never used SQL before that’s okay because I’ve structured this lesson as a breakdown to what it is and how we can use it it’s going to ease you into working with SQL let’s jump in so SQL really means structure structured query language you might hear people say SQL or more commonly SQL now we’re going to look at three SQL keywords and this is basic Syntax for SQL these words these key operators are used in the SQL language select from where notice that all of those are capitalized that’s very important we use the select operator to select the column colum we want to look at we use the from operator to choose the table where the data lives that we’re trying to look at and we use where to justify a specific condition so when something is true that’s what we want to find with our data so picture this we have an example down here picture I have a table that has the name users I have two two columns in my table I have a username column and a password column then I have a condition that I want to look for the username Mario 123 I could write my query in two ways up here I’m writing a query I am saying select star which literally translated means select everything from my table remember my table is called users so this literally says I want to select everything from the table named users but that doesn’t do it right because I have a condition so I want to be more specific I’m looking for a username right well select the column named username from the table named users where my username is equal to Mario 123 that’s allowing me to access key components of my database and pull out the data that we are looking for we are using SQL and we use this to work with our relational databases or these are databases that store our structured data within tables let’s take a look at how we set up a SQL Connection in pqt before I move on remember these three key words from SQL select from and where and try and remember these two examples and how they relate to our example here let’s take a look at how we can set up a SQL Connection in pqt in order to create a connection to SQL light we are going to import something called Q SQL database we can import this from QT SQL module I am adding a database what type of database is this well it is a SQL light database which is a lightweight database for working with SQL in Python I am justifying that as the value to a variable or an object of database I can give my database a name giving it right here making sure my extension is DB these are the methods that we are going to see here I can use add database to create my connection I can use set database name to set the name and we are going to use the open function to open our pre-existing database so that every time we load our app it’s going to load all the data that we’ve previously stored in our database you can see I have a condition here now let’s just start with the very Basics I have a database so if my database is not open I want to print off error I’m going to talk more about this in the next slide but the key component here is I’m creating a condition just to make sure that indeed I do have a database and I can open it if I don’t have a database and I can’t open it I want to print off or alert the user to an error now you can see I’m using something called Q message box simply put in pi QT a q message box is just a popup box any of these popup boxes can look like the following you can see they’re all different but they’re all little windows that can pop up on the screen and each method we use with Q message box so for example I want to ask the user a question you can see that it kind of has a question mark warning warning critical critical there are different things that we’re triggering we can use to ask the user questions as well and based on the response of the user we can do something with those but let’s focus on the bottom two right now because it’s just a pop up and it’s just alerting the user to something remember that those methods are linked to what type of Q message box we are seeing now that we’ve created our connection to our database remember from the previous slide database was created and we open our sqlite database let’s create a query and we want to run our query to create a table named expenses but we want to check first to make sure it doesn’t exist so a query is basically a question that we are asking the database I’m preparing to query or ask the database for some type of information so I can create an object and I’m going to import qsqlquery this is used to execute any queries on our connected database then I can use my query and I can execute a question or I can execute a query to my database this structure inside is actually quite important okay all of this is a string and this is how we can use SQL light to perform queries in Python we are saying Hey I want you to create a new table if it doesn’t exist and I want you to name that table whatever you say here expenses we are giving an ID now these items here are the columns in our database so the First Column is going to be the ID of that item in our database the second column is going to be a date and this date is going to be the value type of text category it’s going to have a text value amount is going to have a real value a number value we use this execute method which you’ve seen before in pqt because it prevents us from needing additional boilerplate code specifically with SQL we can incorporate the code inside the execute method okay so take a look at what’s Happening Here We execute the SQL query specified in our quotation marks to make it a string and we create a table named expenses with the following columns ID date category amount and description each of those I’m also telling the database what type of data it’s going to have is it a text data or is it a number data let’s jump into our project and let’s create a database that we can begin to add things to where are we going to create our connection to the database and where will we create the query those are questions to ask yourself as we jump on into the code I will see you guys in the next [Music] lesson now that we have our database all set up it’s time to create our methods now these methods we’ll be building are specifically going to be built for our add and delete buttons when we click add we want to add our data to a database when we click delete we want to remove our data from our database let’s take a look at our first method before we even get to the ADD and delete methods we need a method for loading our table because every time we open the app we want to load our pre-existing data now in the previous projects I’ve put a lot of code examples on the screen but at this stage you should feel challenged or at least I want you to put in the challenge to problem solve and to logically solve these steps I have broken down step by step what we need to do to create the method to load the table and I am going to show you a part of the code in the next slide start to think about how we can do it using what we talk about now the first thing we need to do is we want to clear the current Table that’s because any old data I don’t want the old data to be there to do this we’re going to look at something called set row count I can then create a new query to select everything from our table using using our class Q SQL query you’ll create a loop and this Loop will run as long as there are more rows in the table right so if you have a database with 10 rows or 10 pieces of data your Loop is going to run 10 times until everything from your database is in your app once we do that Loop we can retrieve the values from each column we will use the Value method to do that the information we retrieve we want to insert the data from number four right that’s what we retrieved and we can use insert row to do that before increasing a row counter this method is responsible for displaying all of our database data in our app so we can visually see it how would the loop look I want to make a loop and that’s going to repeat and I want to use the next method with a loop that’s a bit odd well along with our query we do want to create a while loop so I can say while there is another row in my query that’s what that translates to right so while my database still has another row I want my code to run every time this Loop runs we are retrieving the values from each column column one column 2 column 3 column four column 5 if you have more columns make sure you retrieve those values we’re using the Value method that takes an integer once we’ve retrieved all the data from that current Row from every column we want to insert that data into our table so imagine you your table is called expense table you want to insert the current row that you’re on right so row needs to be an integer we need to insert the current row we can then go through and set the items of every row so I’m going to put my row number which would be the same for all of these and then I’m going to put the column in the row next is the information we want in that row now notice this is a new class but this is the item that we collected that we want to display in row one or more specifically in the First Column of our first row now we’re going to look at the added new expense method what do we want to do with this well we want to gather the info that we entered from the input boxes all the info the date the description the drop-down information the amount and we want to insert all that information into our database then we want the input fields to clear to prepare for the next input we can then load our database if I add or delete information I want to load that new database information so we can visually see it take a look at all these methods some of them we’ve worked with before others are new which ones look familiar to you do you remember why and how we use them in our code let’s take a look at what each of these will do for us I’m going to touch on a few of these I’m going to touch on all the new ones we haven’t addressed and if you need to pause the video screenshot that’s fine you can do that we have the prepare method we use use prepare when we’re working with SQL and this will check the provided query to make sure that it’s a valid question it’s a valid query so when we click a button I want to check to make sure that all my data is going to sit well in my database that is when prepare comes in hand we have the method add bind value add bind value will put the information in a column that’s in our database for us every piece of information we will need to use add bind value we can use the two string method and this will convert an object into a string we can use date and this will convert our input in our case which is a date into an actual date and let’s take a look at our last one here current date this will get the live current date in time like if I ask you hey what’s the date today that is what that that will return take a look at these remember these are all methods so think about the objects that these will be linked to how can we finish up our add function within our add new expense method the first thing I want to do when I click the add new expense button is we want to collect all the data from our input fields at the top of the app you can see that I’m collecting my date I am collecting the information from my drop-down box which is a category we are getting our amount and we’re getting the description using all this information that we just captured from the input fields we can create a query and we can prepare to execute our query now notice the seq syntax insert into so we can prepare to to insert into our table expenses what do we want to insert date category amount description date category amount description our information is going into our database every item we want to send off that info now so prepare it’s preparing to get the database ready to accept this new information now we want to send off our information to our database and we can do that using the add bind value and giving it an argument what do we want to send well I want to send my date off to my query and you can see in position one of my query is the first item that we prepared as well in position two of the query is the second item we prepared for our query all right let’s jum back to vs code and see if we can program out this add new expense method to make some SQL [Music] queries we have our app all set up and ready to go you’ve been introduced just on the surface to SQL and I’m excited to be able to implement that now into our application to create a real database that we can load in data delete and add data to begin let’s go to the bottom of our code here we have our class at the bottom that’s what’s running right this is where our app is running right here this is where we we can create our database before I can create the database we need to import that from our module going up here all we currently have is pi QT and the QT widgets module we want more than this we are going to say from PI qt5 the module we’re looking for is QT SQL we want to import to two classes or two modules from within I want the Q SQL database and we would also like the Q SQL query those two perfect outside while we’re creating our database here I can create a variable I’m going to call that variable database and I can say all right database is equal to Q SQL database dot I want to add a new database what kind of database is this this is going to be a q sqlite database we have this variable that is a sqlite database we can take it and let’s set the name the name I can call is expense. DB DB you guessed it stands for datab base we’ve created it I want to create and try and catch any error errors that might happen and the error that might happen is I’m not able to open my back end I’m not able to open this database for some reason if that happens my app needs to close it’s it’s not able to open without any data let’s say if not my database open so if I can’t open it I want a message to appear on the screen how did we do that before what did we use it starts with a q but we haven’t imported it yet Q message box let’s go and import Q message box at the top right there’s our Q message box returning now I can create this and let’s say critical because if this happens that is a critical error I can’t I can’t get past that my app can’t run without it our first argument can be none I’m going to say error within the app I can say could not open your database what do we want to happen I would like exit I want my app to just exit immediately exit is something that we need from another module this is the only time we’re really going to use it in our applications that module is called CIS or system we want it to exit after 1 second up at the top let’s pop in here import CIS now that we’ve created this database I can now create an initial query remember query is like a question or an initial setup so how do I want to set up my database what structure is this going to have I will create a object called query from the Q SQL query class I’m going to take this and I’m going to execute an initial query or run an initial query when this is Ram this is where we put all of our SQL syntax a lot of this is specific for SQL light here we’re going to put six double quotes drop down like that how do we want to set up this database well what I can say is I want to create a table if it doesn’t already exist this table is going to be called expenses or whatever you want to call that table that goes there okay so if I don’t have a table I’m going to create one and it’s going to be called expenses what structure will this table have if you don’t remember go up and let’s take a look here at set horizontal header labels this is the structure of our database let’s make sure everything is pretty much how we want it I can say ID everything’s capitalized the first thing that’s going to be in my database will be ID that will be in column one and so forth returning to our query let’s say the first one is our ID ID is going to take something called integer primary key autoincrement what this means is an ID I’m not giving it that information every new row of data it’s automatically generating a number so Row one row two Row three and it’s automatically adding in that number so that’s autoincrement this is known as the primary key the master key for that row let’s put a comma next up we have date what is date well date is is going to be text we don’t have to do anything mathematical with that value so it’s just text next up is category category is also text we have the amount amount is real real in SQL just means it’s a number we can do something with that value lastly we have our description and our description is text great we have our query all ready to go it’s set up in the order that it’s going to receive that data it’s going to receive it as an ID but it won’t receive that because that’s automatically being incremented the other four in order are being added into this newly created database every query is going to be structured in this order ID date category amount and description amazing we’ve created our first database in the app but currently we can’t do anything or we are not doing anything with it we want to be able to add and load from this let’s go up to our class we are going to create a few methods here the first method I want to create before I can add data or delete data I need to load my table into my app I need to load my database let’s create a method right here and let’s say load table it’s a method it’s in my class it’s after we initialize everything I can give ourselves a bunch of room right here to kick things off let’s take our table I’m going to take the table we’ve created and I’m going to set the row count we going to set it at zero this is one of the methods we introduced during our lesson during the previous slides we have our row count set I can create a new query a new question remember anytime I say query I’m saying question what do I want to ask it well I want to ask it to select everything from my table known as expenses please remember that these are special SQL syntax words expenses is lowercase because that’s the name of my table select is a word and from is a word from SQL let’s create a row because currently I haven’t loaded in any data but I want to start on row zero and begin after that so row zero Row one row two everything after that first row will be loaded in as well but we need to load in the first well we can say while my current query. next so while I have another row available still while there is another row in my table we want to get the values from each column in our row remember the order of our column let me bring back up our SQL query we have our ID date category amount description let’s go up now in order let’s get an expense ID let’s say the expense ID is just equal to our query value0 so it’s equal to whatever the first column in my database is because python starts on zero My First Column is actually zero in my database if you check the First Column is our ID so the value is whatever we get from our current row next up we can get a date we can say our date is query. value and I think you can guess so for each of these we want to get the value of that current column I’m going to go forward and I’m going to grab the values from each column I have our five columns and I’m getting the value out of each of those so every query runs we get the value from that column we’ve indexed now now that we have these values we want to put them into our Q table widget so I’m going to say add values to table we can’t see these values we can’t see what’s in a database I want to take it out of the database and put it into a table for us to be able to see let’s take our table property and we can say insert row what row do I want to insert well well I want to insert the first row which would be row zero the first time this while loop runs but I need to be able to increment that to go to row two Row three I’m just going to put my row variable remember we have our row variable here so I’m adding the first row I’m inserting the first row to my table at the end of this you guessed it we can increase the row so so every time our Loop runs we are increasing the row and adding in row two Row three Etc after we’ve inserted the row I want to take the values that we got back and I want to insert them into a column within my table to do this let’s take our table I now have my table object and I want to set an item in that table okay what row is this from I don’t know but it’s from the current row I’m on all right now it’s asking me for a column great the first one I know is column zero that’s the First Column then we need an item well to get an item here because we’re working with a Q table widget I’m going to go up and I’m going to import one more key class for us to do this at the top here let’s import a class called Q table widget item this is an item in a table you guessed it going down I can now use that new class I can say Q table widget item like so what is the first item in the First Column think about that for a moment what do I need to add inside here an ID well where’s my ID it’s right here it’s called expense ID let’s convert this to a string and let’s put in expense ID just like that so I’m taking my table and I’m going to set an item in that table it’s going to be in the First Column and it’s going to be my ID amazing I’m going to copy this how many items do we have we have five so one 2 3 4 five there are our five items let’s go down let’s change our column numbers and also the values here what do we need here well I need a date I need my category I need my amount and amount is a number so I’m going to leave it to convert to a string here our final one our description if you need to pause to understand what’s happening please do read through an interpret in your own way once we’re done here I’m going to read through again and translate what’s actually happening let’s bring our row up and we are ready to go through this method let’s break things up when this method is called we are setting our table row count I’m then creating a new query I’m getting ready to ask my database a question what’s my question going to be well well I don’t know yet but what I do know is I want to get the data to use for my query question I want to select everything from my table expenses I’m going to start with the first row and I’m going to repeat all of this while there is a next row in my database if there’s not another row in my database stop if there is a row keep repeating every time my Loop runs I’m taking the five values from the five columns in the current row I’m going to insert that row into my object table remember table is a q table widget and I’m going to insert the current row that I’m on I then go forward and I set every col column in my table to the items that I got earlier those values we end with increasing our row we’re pretty much done with our load method I’m going to go up here into our init I’m going to say here I want this to automatically call load table method every time we boot up because we will always want to load in the database so I can insert that right there self load table let’s run our app now we won’t see anything because currently we don’t have anything in our database great our app still works airfree which means we are ready to go to the next video in the next video I will walk us through how we can add expenses to our database I’ll see you in our next [Music] lesson [Music] we did a lot in our last video and I hope you took some time to read through your notes and review the previous lesson as we introduced a lot more advanced concepts as well as introducing SQL and our databases to our project in the last video you created a database as well as creating a method for loading in our existing database in this video we want to be able to add items to this newly created database wow I’m saying the word database quite a lot let’s go down to our load table method and right after it we can create our add expense method right here the first thing that’s going to happen in in ad expense is we want to retrieve all our input field data let me show you what I mean I’m going to put pass here for now let’s run our code here’s our app let’s say we have a date of today is the 8th 23 I have a category an amount so 25 description uh food category oh I don’t have a drop down box yet I have it but it’s not dropping down let’s address that too but all this information right here I want to capture it it’s like taking a picture I want to capture it and I want to store it in variables remember that let’s go and address this drop down box quickly going up our code where did we we can jump in right here actually so here we create the dropdown let’s jump in here here let’s say self. dropdown let’s say add items add items takes a list just like the horizontal header labels what do we want the items in the drop-down list to say well I want them to be our categories so pretend they are categories you could spend money on food Transportation uh rent shopping entertainment uh let’s say bills and finally other so all of these are options that you can select from the box all right that should take care of that issue let’s do a double check click oh yeah okay great so all this data here we want to capture this returning to our ad expense method now what we can do here is we can create four variables all the information we want to capture I know that I want to capture a date I have a category I have an amount and we have a description so these are all local variables I’m not making them properties they’re only inside this method date how do I capture the date well from what we looked at in the lesson when we introduced this topic we can capture the date by taking that date box so self. dat box I can convert the date and I want to turn that to a string what format do I want to format the date too that’s going to be done here in a string

    as well I can say 1 2 34 that’s year so if it’s 2023 it will be 2023 then I can do the month then I can do the day that’s how I want this format to look for my category let’s take our dropdown box so self. dropdown remember the method we used in our last project we can say current text to get the text value of a drop down box item amount self. amount we can say text q line edit we use the text method we saw this as well and we can get our self. description that is also a q line in it getting a text value so we have four variables each of these variables holds the value the face value of our items that we’re trying to collect the data from we now want to take this and I want to drop it or put it into my database we need to create a new question for the database a new query for the database let’s say Q SQL query I’m going to prepare to ask it a question this is a SQL statement so our six quotation marks what do we want to prepare to do that’s what this says well I’m I’m going to prepare to insert into my table known as expenses what do I want to insert well I’m going to insert the date I’m going to insert the category I’m going to insert the amount followed by my description each of these that I’m going to insert so these are like the names each of these are going to have corresponding values and these values will be represented by the information that we give it currently we don’t know it but the information we pass to it it’ll have those four values we are preparing to insert into our table this information that will have four values as well we’ve prepared the query let’s now push or send information to our database so I can take my query and I can say add bind value what value do I want want to go into the first slot of the database I want the date you guessed it we can take this now one 2 3 4 next up in the second slot I want the category the third slot amount fourth slot description we now have added these values to a specific column slot in our database I want my query to now execute it has the information it needs I want to send the information off to my database that is what we’re doing with our query once we’ve created that query we captured all this information from our box well I want to now clear those fields to prepare them for the next expense that you might enter right that’s a convenient thing to do for the user let’s clear everything how can we clear everything this is a method we’ve used before in our previous projects everything we do let’s start with our uh drop- down box let’s say dropdown we can reset it using this method Set current index back to zero we can take our amount field and because that’s a q line edit we can say clear we can take our description box and because that is also clear what am I missing well my date now my date originally was like 1 one 000000 let’s say when it clears let’s actually give the current date as the face value of our app that looks way better too so let’s take our date box and let’s set the date of the date box I want to set the date to the current date to do this we are going to import another module into our app this also comes from p qt5 and it comes from a module that you’re quite familiar with let’s say from PI qt5 QT core I want to import a class called Q date this will allow us to get the current date let’s return to where we were inside our set date method what do I want to set the date to well I’m going to take my Q date that’s a class but I’m not giving it any arguments I just want to link it I want to link it to something called current date just like that that is going to change the value of that date box to the date today and as of today it is July 8th amazing the last thing we want to do what do you think we want to do after we add an expense the last line of code well I have new information so I want to now look load this new database I’m going to call the method we first made load table as I have new information in our database great I’m excited let’s give our app a run at this point we have the ability to add information to this table before running the app break down and pause what is happening here let me go through and translate this when we click the add expense button so we need an event first but when we do click it we capture all the data from the input boxes at the top of our code we capture a date we capture the current text the amount and the description then I’m preparing to ask my database a question or preparing a query what am I preparing to do well I’m preparing to insert something into my table that we named expenses I’m going to insert in the format date category amount description each of these will have a value they have four values because I have four columns in our database then in my query in the order that we said we’re going to give it the information we are adding a binding value that’s going to bind with that current query once we add all the values we want to execute and send the query off to our database we’ve added something to this database it’s now time to prepare our app for the next input so we want to reset everything finally ending with loading our new database into our table in order to get this to work let’s link this to our ad button where did we create our ad button up top let’s go up top to where we made the ad button and right after here we could just say Okay self. add button. clicked when that’s clicked we want to connect to our new method add expense all right time to run the code let’s give it a run things are starting off let’s start things off with our date today so let’s say 8723 today food amount 10 description tacos add look at that we have added something into a database and taken that database and loaded it into our app let’s go for another one this time let’s say rent let’s say someone’s rent is 500 let’s say description landlord add ooh we have the ability to add things this is great we can say night out when did we do this night out let’s say one amazing we have almost full functionality of our app the last things we need to do is program our delete button and any designs we want to do well done I hope you’re starting to see the gears turn and how we can use SQL to enhance our applications it’s a way for us to store data within a database in pull it as we need it I’ll see you guys in our next lesson where we will introduce the delete expense [Music] method here you are in the final stages of your app and very well done because you’ve been introduced to a big new topic topic and you’ve only just scratched the surface what was that new topic that we’ve learned in this project well SQL the structured query language that we use while interacting with databases and you’ve gotten it down so far let’s finalize this app what’s left to do well our delete function our delete an expense what do we need to do to achieve this well in order we want to get the row that we clicked on from our table remember this method we’ve used this before so whatever row we click on I want to capture that and I do want to check I want to run a quick check and I want to check to make sure that I indeed chose a row within that database if I did I can create a variable using the ID of the row that I selected we can generate a question popup and we can ask the user if they want to delete yes or no remember the Q message box well we’re going to use that here along with the question method if I choose yes from my popup box I can prepare a query and I want to SQL syntax delete from table where the ID I collected is equal to the value we can then load in our new table using the load method that we previously made if we look at a little bit of the code from our delete method you can see in the first part I am creating a variable and the value of this variable is whatever row we click on I am capturing that from whatever row I click on I want to get the ID from that row so I’m saying my ID this new variable is equal to my expense table item the selected row column zero because I know that no matter what every Row in the First Column which is column zero that is actually holding the ID of that row so I am selecting so if I click on row five I want to go to row five and get the information that’s in the First Column and convert that to text that’s our ID based on that ID I’ll now create a new query and I’ll say hey prepare to execute this query all right I want to send my message and I want to execute the query so my expense ID is right here that’s our question it’s going to to remove that row and load in our new database right this prepare query where it’s preparing let’s translate that it literally says delete from my table named expenses but only where the ID matches the one I give you here that is how we could program out our delete method if you want to try and implement this yourself jump on over to vs code and I’m I’m about to head over there myself I’ll see you over in vs code let’s finish off our [Music] app you’re closing in on the final details of your project the last thing we should be doing is adding our delete expense method we have our functionality down we want to have the ability to remove something from our database from our app table let’s head down to our class and after our ad expense method this is where we focused our endeavors last lesson let’s create right here our closing method this will be our delete expense method let’s clean this up a bit so I’m going to give some space what do we want to happen how can we delete something well what I want to try to do is I’m going to click a row in my database and I want to capture whatever row I click I want to delete that row whatever row we click on after I click my delete button we have within our UI design so for whichever row I click on I want to capture the ID that’s linked to that row and I want to delete it from my app screen as well as my database let’s start with I want to capture the row that I click on let’s create a variable called like uh selected row this is equal to my table do you remember how do we get the value of the row we clicked on we’ve done this before actually and we did this in our last project I’m going to say current row so the value of this variable is one of the rows that I click on in my table first things first I need to make sure that my database is not empty because if I click into an empty table if there’s no database or there’s no rows I should not be able to delete anything so I need to anticipate that someone might try to do that let’s make sure that if the selected row is equal to -1 so that means you actually did not choose a row from the table you clicking the delete button but you did not click a row yet I want to alert the user to a problem an error what is the best practice for us to alert the user let’s give them a friendly message box and let’s just give them a nice warning and say hey something’s going on here and you might want to address that so that’s a part of myself and I’m going to say no expense chosen you are the chosen one you didn’t choose one so we can say that and I’m just going to say hey please choose an expense to delete that looks nice exclamation point we can simply then just return that that’s going back to the user nothing else is going to happen we now have checked and warned the user that they need to choose a row if they’ve chosen a row we want to capture the ID from that row so specifically the text value of that ID let’s create a local variable and previously we have one called expense ID I can use that here because this is within my method expense ID is going to be a number now the number is going to be something from my table and it will be one of the items in our table what item do I want from the table well I want to get it from the row that I’ve clicked on and I want it to be from column one which is column zero remember in our database the First Column is our ID that’s what I’m capturing I’m getting the ID from our database from the table specifically everything in the table is a text object so I’m just going to say text here this whole item is an ID text value but we’re converting it to an integer which is good I have an ID let’s double check and make sure that that user really wants to delete it CU if they don’t then okay let’s give them a second chance let’s create and let’s say something like confirm confirm is going to be also a friendly message but this is going to be more like a question because I want to make sure and I say okay are you sure that you want to delete this so we can say are you sure question what do we want to say then we can say delete then we need to give them two options and it’s telling me to give them two butt buttons now these are going to be our Q message buttons so we can say the options are going to be Q messagebox do it’s going to be yes or no I can say that like that so I’m going to confirm and this little question box which we’ve looked at before is going to pop up and it’s going to ask the user if they want to delete an expense the user will then be given two options from which they must choose choose yes or no if our answer so if what we get back from confirm is equal to no what do we want to do well I just want the program to end I don’t I don’t want to delete anything here’s a popup box if the confirmation is no just exit out of this method I’m done using it I don’t want to do anything I don’t want to delete that item but if this condition is not true it means we do want to delete an item and we clicked yes what do we need to do to remove an item from a database well it’s kind of the same question what do you need to do to create a database to add an item to delete an item we need to ask a question I’m going to prepare a query the query that I’m going to prepare is I’m going to take this query and I’m going to prepare something what SQL syntax do we want to use well I want to delete from my table called expenses everywhere where the ID is equal to the bind value I give it what’s the bind value well the bind value is going to be the expense ID this expense ID that we got from the row we clicked on is going to be where the ID matches that so delete from our table everywhere where the ID is equal to the row we clicked on that’s us using the ad bind value again finally let’s execute our query it’s time to run it now that we have new data let’s load our new table the updated version of our table into our application this pretty much wraps it up the final step that I’m going to put on here before a quick test going up to our buttons we just need to connect self. delete button doclick do connect we can link our delete expense method are you ready for this let’s see if our expense tracker is ready to go running our app let’s choose so you can see here my app’s loaded and it’s loaded in our saved database that’s the point of a database we can save information every time the app fires up it’s loading that in now let’s say I want to delete this rent that was an error so I’m going to click I could click anywhere in this row I’m capturing the current row delete expense do I want to delete it no okay so nothing happened entertainment delete yes look tacos that was a mistake yes you can see our database working look at that amazing well done to everyone I’m so happy with how far we’ve come and how many projects we’ve been working through you started off with not knowing what this new framework was but now you’ve come so far and you’ve learned how we can use this framework pqt to build out window applications in Python and we’re not done yet there’s more projects to come and more tools that you’re going to learn I will see you in our next [Music] video [Music] you’ve just finalized your expense tracking app we’re at a later stage in this course and you may be wondering okay how can I start to implement a bit more styling into my apps this could be changing colors or adding boxes anything like that in the next few minutes you’re going to learn how we can style our pqt apps with CSS what is CSS you may have seen this term before you may have actually used CSS as well let’s take a look now CSS is used to style websites specifically it’s used with HTML and JavaScript and it can be used with other languages and this also includes python how does CSS work well our casc G styling sheet that’s our abbreviation CSS we use it to Target specific elements in our code so for example if you have a website that has H1 elements these H1s are the big text the headers I want to Target all the H1 elements and I want to give them the font size of 32 and the font family Gothic so I can use these parent elements to Target specific objects on my page or in our app and apply filters or apply stylings to them in CSS we have our main elements which are like your H1 tags any of your header tags your paragraph tags anything like that you can also narrow it down so if you created a class in HTML you can Target the class by using the dot with your class name now keep in mind this only works for HTML this class structure as in Python we have something different and finally you could style it by ID and ID is very specific so I’ve actually put this in the order it takes precedence with our least important in between and the most important we can use our styling CSS by targeting our element followed by a set of curly braces inside the curly braces we put the font Styles we want to apply to that element what would this look like in pi QT well it’s actually going to look very similar we can style the same way in pqt we just need to use the set style sheet method inside here the only difference is all of our styling is actually a string and you can see I’ve specified that by using a multi-line comment or a multi-line string with three quotes in the beginning and at the end what elements are we trying to Target well remember with CSS we are targeting the parent elements originally these were our main elements and classes well we can Target that with pqt and python too you can see here I want to apply a background color to my entire app my finance class this will apply a solid background color to everything everything that is a q label a q line edit or a q push button they are going to have these Styles then my Q Tree View could have this style now we haven’t talked about Q Tre view but don’t worry I’m just including classes here as examples but we will see these at a later stage in our course let’s jump back into vs code and let’s finalize and style our app I’ll see you guys in the next video [Music] video it’s time to add some styling to our application our current application is looking like this let’s take a look at what we’re actually going to achieve in this video I want to take our application from this all the way to something that looks like this now you can use your own colors of course this is just going to be what I’m aiming for and we’re going to do a little bit more than just CSS I have some bonus surprises we haven’t talked about in order to tweak our app but don’t worry as we go through I will break it down and give you a good explanation all right let’s move these off and and jump into our code at the top of our code uh I’m going to go in here let’s just import QT the first thing I noticed was when our app started we don’t actually have the initial date set so let’s take our date box and let’s call Q date we’ve actually done this before and we can link our current date method to our class Q date now when the app starts it’s going to have today’s date on it okay next up I want to go down here to my table I want to design my table a little bit more there’s currently a few things I don’t like going on let’s bring our app back up in our app I don’t want to see this bar at the bottom I don’t want to move the table I want it to be hardcoded so how can I prevent that we are going to take a look at that and then another thing I want to do for example if I add this expense I want it to go in descending order so at the top I have my newest entry my newest expense and it goes down to my oldest expense let’s try to implement those two functionalities the first functionality here I’m going to take my table I’m going to say self. table and I’m going to take horizontal header I want to apply a method and I’m going to say set section resize mode this is going to allow our table to be hardcoded and take away that scrolling bar so it’s going to look nicer and more clean within here we need to stretch the header I need to stretch the table so to stretch the header I’m going to use something called Q header view we haven’t imported this yet but it does have a method called called stretch let’s go up I’m going to throw in here and I’m going to say Q header view as a q widget there we go so this is going to stretch our header across our entire table widget brilliant the last little tweak I want to do to my table is I want to sort them so everything is in descending order let’s take our table and thankfully pqt has an awesome method method called sort by column and inside sort by column it’s going to take the column we want to sort so if you remember in our app the First Column is actually our ID I want to sort the second column this is at position one so inside here I’m going to put one as I want to sort by column one and then my sort order I’m going to use QT and I’m going to say descending order now that we’ve styled that it’s now time to add in some of our CSS let’s clean this up I’m going to add in my CSS before we add everything to our design so let’s say self. set style sheet inside here remember we need our string 1 2 3 4 5 6 then we can add in our CSS what do we want to change well I want to change a few things in order to change my entire app we need to remember that our entire app is actually a q wiget so I want to affect that parent element of Q widget returning to set stylesheet let’s say okay so Q widget I would like to apply some styles to I’m going to give them a background color and the background color I want to be I have picked out is this great we have that color what else do we want to add in our Q widget well I have my Q widget let’s say we want to affect our Q label we could affect our q line edit if we want to affect more than one element with the same styling I can put a comma so in this line I’ll be affecting any q line edits we have any Q combo box Q date edit as well as any Q push buttons we can have our Q table widget Q push button and then the last one we are going to apply a state so for example with CSS I could apply a hover state or other types and to do this I can use a semicolon and I’m going to say okay when the Q push button buttons are hovered over with our Mouse then these Styles will be applied I’m going to go through and I’ve already created some styling that I’m going to add in here let’s see what we’re going to add my stylings look all ready to go let’s walk through and see what I’ve done here so I’ve taken my Q label and my Q labels are going to have a darker font to them and I’m setting their font size anything that’s text Q label all of my Q line edits combo boxes in the date edit box they are going to have a background color of this the text within those boxes will be this dark gray and I’m giving them all a border around the perimeter of that object with a little padding my table widget will be the same color as my overall background and it will have a border so we will be able to see the difference between the two in between each row and column I’m going to have white or like this grayish color I’m applying my Q push buttons will be green with white text no border then when we hover over the button the color is going to change ever so slightly so a little bit darker wow look at all the styling so we can do that within one method self. set style sheet this looks great let’s try running our app and seeing our end result is it what we’re aiming for amazing it is exactly what I was going for and you can see as I hover over these buttons they’re changing color all of our items match the background color and I’m hoping that you used some of your own colors too let’s add our expense everything is working how we want it to delete look at that even our Q message boxes are styled to what we set this looks amazing incredible job have a play around with CSS and do a little bit more research because in our next app you’re also going to use CSS to do some styling I’ll see you in the next video for an introduction into our next project [Music] are you guys ready for our next project cuz I certainly am we are about to dive in and create an interest rate calculator application in this application you will be using everything you’ve learned so far but in order to create this we need a way to visualize data in Python we will introduce a library used for data visualization in this project let’s break it down here is an initial overview of our app take a look at what we see going on and what this app can really do we have the ability to enter an interest rate the initial investment M or the amount of money that we want to put in and the number of years we want to invest for you can see up here here is the interest rate here is the initial investment and then here is the number of years we want to invest for you can also see that I have a little box here for dark mode which is a way that we can style our application even more we can create a chart we are going to display in a table or some type of view all of our interest rates calculated and then finally I want to have the ability to save so when we click this button I want to save our chart but then I also want to save our table as a CSV file what widgets do you see on the screen right here well we know all these except Q tree view this is going to be a new widget a new class which allows us to have it’s almost like a q list widget but we have two lists going on we have two columns we have a year and we have a total then we do need something for our chart but just for the initial setup and design for now let’s just use Q Lael very similar to what we did in our image editor app are you thinking about your layouts and how you’re going to design this app a lot of things are happening here what makes sense to you what is the easiest way we could design this are we going to have a master row or a master column and what will be inside our Master layout what I’ve come up with is I’ve said that I could have two rows because at the top of our app we have a lot going on up here so this could be held in its own row then I could structure in a second row and within the second row I can have two columns My First Column is going to hold my Q Tree View along with our buttons and my second column is just going to hold the area with the chart this for now can be our Q label our design will have two rows row two will have two columns and together Row one and row two these will be held in our Master layout that Master layout we can drop that into a column start thinking about this because you’re about to head off and design the app on your own So based on your experience with pi QT and everything you already know how can we set up this app to the best of our ability I’ll see you guys guys in the next video where together we will prepare the initial layout and design of our [Music] app all right here we are in the initial setup for our interest rate calculator app you know what to do here building on all the knowledge we have been learning how can we set up our initial project let’s kick things off with our Imports what do we need from PI qt5 we are going to do our QT widgets import everything we want so Q application Q widget what else are we going to be needing for our application well we need our Q labels we need our Q push buttons let’s get our layouts in there before I forget them so QV box layout Q hbox layout we will use Q Tree View that’s the new widget item we have our q line edits so I can say q line edit and finally here I’m going to talk about something briefly called Q main window let’s put that in as well and this will allow us to create a window very similar to what the Q widget does but it allows us to inherit it a little bit differently great I am then going to go and I’m going to import something else so I’m going to go to qtgui I would like to import Q standard item model this is what will allow us to to build out and add elements to our Q Tree View itself great we want to create a class-based application so I’m going to create one called finance app and instead of inheriting Q widget this time I’m going to inherit the main window itself so let’s say Q main window you’ve seen how we can inherit Q Widget the same thing’s going to be done here for main window and it’s it’s going to act very similarly let’s create our Constructor what do we want to run when the app first starts well everything actually up top here I can inherit and so let’s say our super function I want to inherit everything from our finance app and I’m just going to say in it just like that so I’m inheriting I’m initializing this as a super class as well as activating the main M Window what this translates to is I am activating my super class Q main window and I’m giving my super class my class that we just designed this is how we set up the inheritance for Cain window what do we want to create well I can set my window title now we know that what do you want to call it interest interest me 2.0 I don’t know that’s kind of cool okay let’s give it a resize what would the width and height of the app like to be let’s say to kick things off 800600 all righty because I’m inheriting Q main window I don’t have a Q widget yet so we can actually make that locally inside our Constructor method so let’s say our main window and let’s say that’s equal to our Q widget like so I don’t need self because it’s not going to need that it’s you used and constructed right here let’s create all the objects we want to see on the screen I’m looking if I run my class what objects do we want well if I run this app I want three text labels at the top and three q line edits that’s going to be in the first row I want my treeview two push buttons and then for now A Q label let’s start off just in the first row so interest rate initial investment let’s say rates text I have that I’m going to say rates input that’s the input let’s create one for uh initial text we’ll create one for initial input we can create one for years so years text and we can say years input now that I have those all sorted I can just go through and I know these are going to be Q label so I’ll say Q label take that two times we have two more and then our next one we know is going to be a q line edit so let’s get this all prepared for us all righty in the first Q Lael rate text we can just say like interest rate this is going to be in a percentage looking good so our first one is interest rate then we have our initial investment our final one is going to be years to invest so our row I have all those objects this is going to now bring me into let’s say creation of our tree view so how do we use Tree View and how do we get items to it what I need to do is I’m going to create something like a model and this model is ultimately going to hold my tree View and it’s going to allow me to add items to this model self. model is an object from this Nifty class that we’ve imported from our qtgui I can then create my treeview let’s say treeview is equal to Q treeview it doesn’t take any arguments right now I can take my treeview so self. treeview and I would like to set the model to become my my model great look at that all come together we have our starting row I have created my Q Tree View and I’m preparing it to accept items within the tree View and we are setting our model then our last three things are I want a few buttons so I’m going to start off by creating my buttons and say let’s say I have a cal button and let’s also say I have a clear button our C button can say calculate and our clear button can say clear then I’m going to create a figure now in the end ultimately this is going to hold my chart but I haven’t introduced data visualization yet or our new module that we will use for this so for now I’m just going to say Q Lael and I can just say uh chart will be here soon that’s just like placeholder text next up we have all the objects what should we be going into we should be going into our design right we can take our design for our app so let’s create that I’m going to create my master layout I’m inside in it so I can use self like that I know that I want it to be in a column I know that I’m going to have Row one and that is our c and we also know that we also have row two that can be our Q as well now within row2 there will also be two columns if I created those now I can just say column one that’s my QV and column two is also our QV box let’s start off with Row one so I can take my Row one and let’s add all of our widgets to them so I’m going to actually copy this I know I’ll be needing it the first element we want is going to be our rate text our rate input let me get the other four added we have everything added to the first row I can carry on now to row two now within row two I have columns so let’s let’s begin with those columns actually I’m going to take column one we want a lot of things in here initially at the top I I want my treeview so I can add in my treeview itself directly under treeview we would like our calculate button bringing us to directly under our calculate button we can just insert that clear button let’s take a look at what we want the app to look like as well one more time I have put everything in the column I now just need to add my Q label to my second column before we can add it into our row taking column two adding the widget what widget do we want to add here well I want my figure to be here eventually which will be a chart great we have our two columns let’s take row two and I would like to add layout Row one and row two I can take my master layout now we can add layout to that and at top we want to say Row one and row two I can see a little mistake here I threw off right here I’m adding to my row row one and two this should actually be column one in column two set we can take our main window we can set that layout and we can say selfmaster layout a great everything’s set up and it’s ready for running but let’s come outside of our class real quick cuz we don’t have anything so if name is equal to main then let’s create our app object and say Q application we can create an object and say well let’s say my app is equal to our finance app let’s say mya. show and then let’s take our app and let’s execute our app before we run our app we’ve set layout now I’m inheriting Q main window and we’ve seen this before with our Q widget because we’re inheriting it I want to set like a central window so I can say set Central widget what do I want the main widget to be well my main window that’s my main widget so I’m going to set that here in line 62 that’s the last and final part of using our design with Q main window when we run the application we see everything come to life now this looks almost ready to go and ready for the next stage but this tree view is huge ideally I want these to be swapped so chart will be here soon this should take up the most space how can we do that we’ve done this before remember I need to set the width and the percentage of my columns Let Me Close Our application let’s find right right here let’s give this a try so I’m going to say column 1 is going to occupy 20% column two is going to occupy 80% of the screen looking much better this is how I want the app to look we are ready to go in the next lesson we are going to convert your data and get it into our tree View and calculate our interest rate starting to visualize our data before we take the data we’ve created and generate a chart or a plot with that I’ll see you guys in our next [Music] lesson [Music] great we have our app set up in the initial design ready to go now we need to talk about how we are going to calculate our interest and how we can use what we calculate to put into our tree View and into our chart what are the step steps we need to do in order to calculate our interest well if we take a look here I want to add the interest calculation to the Q Tre so we are going to create a method and this method is going to do all of the following it’s going to convert all our input fields to numbers so all these guys will be converted to numbers and we do want to try to catch any error so think about that what error could occur in this program if we try to convert these fields to numbers what if the user enters something that’s not a number we want to catch that and alert the user to this so think about Q message box once we’ve converted all of our input fields to numbers we want to then create a list for every year I want to multiply the total investment by the interest rate our calculation is right here I can create a treeview and each item in here is going to be something called a qard item we can import this into our project this is going to take a single item that we want to add to a treeview we can add our item year and item total to our treeview as a list so think about how can we do that as a list finally once we have data in our box I want a save button to appear on my screen initially when the app starts we should not have a save button because you can’t save if we don’t have any information so pause the video read through each of these steps what would you need to do in order to achieve or to solve each of these steps here I am using to calculate the interest the value that we enter into those fields so this interest rate I could store that in a variable and use that and then this initial investment that’s like my total I could store that in some variable as well this calculation is the equivalent to the output of our interest rate the input that we entered in number of years you can see that that’s displayed in the First Column versus the second column let’s take a look at converting all of our input fields to numbers and how we could catch any errors with that we have our try and accept statements what do we want to try to do we are creating these local variables in the function and we’re trying to convert all of our initial properties to a number number now remember a q line edit we can get the text value of a q line edit by using the text method and linking it to our qine edit object now that I have the text value I want to try to convert that to a decimal a float number we try to take our values we entered and we convert them as we need them I’m going to try and catch any errors specifically the errors that I want to look out for are value errors so if the user enters something that is not a number I want to catch that as a value a and to alert the user we can use our Nifty Q message box and just give the user a warning and say hey um you need to enter a number please try again we’ve now converted all of our input fields to numbers or we’ve caught the errors to do so what comes next well we need to calculate our interest we had a local variable called initial investment but I don’t want to change that variable that value um I do want to create that so I can change it so I’m making a variable total and whatever our initial investment was that is now the value to this variable total try and break down what’s happening here as I go through where do these correspond to what you see in your app for every year in the number of years I entered which is essentially this I’m going to take my initial investment my total every year I want to add the previous total and I want to times it by the interest rate so so every time this runs this is going to start with the first initial investment multiplied by the interest rate but then the second year comes and you can actually see here in my treeview that the numbers changing because I’m earning interest off my initial interest and investment so as the years go on it’s actually updating that’s what’s happening here I can create an object item year and item total and remember to add these to our Q Tree View I’m going to use that new class Q standard item so I’m adding a year and I’m adding a total I can then append a row this method I’m using with Q Tre view specifically to append a row which means a row is going to have more than just one item in there remember that we said we need to add a list my item year is column one my item total is column two now this is kind of strange what’s going on here well a string format specifier this allows us to format all of our floating points with two decimal places this specific syntax is telling us the number that should be formatted or how many digits afterwards I want two digit digits after the number and you can see here 76 cents or 42 cents that’s what we are formatting where is everything coming from in the app well let’s keep with our color coordination our goal now is to head back into vs code I want to be able to program a calculate interest method that when we call this method it’s going to insert all of our data in into this Q Tree View as an added bonus try to create a reset method when I click the reset button I want all the contents in my treeview my interest rate investment in years I want those to be reset how can you do that using the clear method I’ll see you guys over in our next lesson [Music] it’s now time to calculate our interest rate and display that in our tree view let’s go down and let’s create a new method after our Constructor right here I’m going to make a method and I can call this calc interest giving itself and in the beginning I’m going to create a variable called initial investment I know that it’s going to have a value but currently it’s none we want to try to do a few things I want to take all of our inputs from the top of our app so our initial investment the interest rate and a number of years and I want to convert those to numbers so we need to check and try to do that let’s create a try statement and let’s say okay uh interest rate we have that I am going to get my initial investment and then we’re going to have the number of years for interest rate let’s convert a float and we want to get our uh input something of input text uh rate input we created that initially that’s our q line edit and we can get the text value of a q line edit by using the text method we can do the same thing for our initial investment this is called initial input get the text for number of years well calculating the interest of number of years is usually done in int so whole numbers and so let’s just convert that to an INT get the text awesome if this doesn’t work let’s throw an exception so a value error so you must enter a number you can’t enter a space a letter anything like that or it’s not going to work if this occurs let’s give the user a nice warning so I can do that by using our Q message box warning is it parent is myself we can say Okay error and let’s just say invalid input enter a number like so looks great if that’s the case you can return that we now at this point have three number values that we want to use to calculate our interest do you remember the equation we’re looking for let’s try this calculation I’m going to create a new variable because I don’t want to edit the actual value of my initial investment but I am going to use that as a starting point what I can say here is I can say for every year in the range of one because if I have an investment the minimum is one year and my variable number of years plus one so for every year if I have my investment for 10 years this Loop is going to repeat 10 times every time it repeats I’m going to take my total which the first time this runs that is the initial investment and I would like to add the total but I’m going to multiply that by my interest rate divided by 100 great we have this I can take my item year now in my item year I would like to add an item to my treeview in order to do this at the top I imported a class called Q standard item this allows us to add an item to our treeview which if we go up a little bit we have right here standard item model I’m going to add a standard item to this model model going back what do we want to add as the item year Well I want to add my current index so the year that’s like for I for every year I want to add that current Year to my treeview then I want to have the total how much did I earn that year essentially inside here we want to put and format our code so I can do something a little bit strange here let’s give ourselves some curly braces and let’s go to the end of our total and I want to cut off the last two decimals so I can say to F I can then format my total which we initially collected right here that’s being formatted to only secure two decimal points what we want to do is I want to take my model that we created really our model is that treeview the fancy method append row allows me to append a list in this list in the First Column I want it to be item year and then I want it to be item total just like that this pretty much works as a bonus I asked you to actually Implement a reset method so very quickly I’m going to do that let’s call a method reset and say self for this we didn’t really have to do too much what do you want to reset well we’re going to reset our rate input we’re going to reset our initial input and then finally we’re going to reset our years input we can just use clear because each of those is a q line edit what is left to do well let’s go up here now we just need to go at the bottom of our init and we need to take our buttons so I have a cal button and we have a clear button and we want to say when the clear button is clicked we want to connect to our reset method when the Cal button is clicked we can connect to well you guessed it we want to connect to the Cal interest method all right let’s run it let’s see if we can take our data calculate the interest and display that into our Q3 view let’s say we have an interest rate of 8% the initial investment can be 10,000 and years to invest 15 years calculate look at that we did that I’m going to make this a bit wider okay but this treeview is working great if I click clear you can see see that we’ve cleared all of our inputs let’s just end this on a high note and add the final two touches let’s make the tree view a little bit wider and then also let’s clear the tree view going up here let’s just change this to a 30% width and a 70% width going down to our reset let’s take our model let’s say self do model clear try it one more time again 8% let’s say say 10,000 let’s say 15 years calculate look at that clear everything is cleared we are looking great we are about to head over into our next lesson and we are going to introduce the new topic of data visualization in Python this can become incredibly useful in your python journey and your career as a data analyst or a python developer I’ll see you in our next lesson for the introduction of math plot [Music] lip it’s time to get our hands dirty and jump into how can we take all of our data in the tree View and how can we use that to generate or create a chart to do this we are going to use a powerful python Library called matplot lib let’s jump in and explore how this new module works and how we can use this to our advantage in order to import map plot lib I’m going to do two things number one I can import map plot lib and I’m going to give it a nickname I’m going to reference it as PLT and this is an extremely popular naming convention that you will see in other code that uses this module I’m giving it a nickname PLT which is like plot that I can use at later stages in my code now Matt plot lib and pqt actually use different backends so we need a way for them to communicate and talk to to each other because we are using M plot lib with pqt we are going to import one additional class for our use I’m going to import from the backend modules of map plot lip I’m going to import a class called Figure canvas QT and this is a really long name so it’s popular to see also renaming that class to figure canvas so I’m importing this class and I’m renaming that as figure canvas this acts as a bridge and it allows us to create charts or canvas objects and that’s acts as a container so it allows us to wrap our chart in a canvas and this allows us then to take this wrapped canvas and put it into an app like pqt this is why we use this class figure canvas take a look pause have a read through I’m using the back end of matplot lib to wrap my chart to use in pqt let’s take a look at some popular methods that we will use for data visualization anytime we’re working with this module map plot lib this is one of our most powerful Tools in Python when it comes to data visualization you will most likely see two popular librar while working with python one being matplot lib and for its Simplicity in used in scientific studies but two another popular module that you could use is called plotly in this course we are just going to jump in here and use matplot lib as it’s easier to start and easier to understand you can hit the ground running with your data visualiz Iz ation we can use this to create simple plots line graphs scatter graphs anything like that what we are focusing on in this specific project is going to be a line graft for us to see how much interest we’re earning screenshot or write this down take notes anytime you see a table with me explaining these new methods it means you’re going to be using them more than just once it’s a good idea to write them down to understand this new library as a whole the first method we have is called subplots this can generate one or more plots in a single figure so imagine for example here is one plot what if I want four plots well that’s one figure now I break it into four plots I can use this method to do that we have the plot method and this will try to plot the data that we give this method so this method does take an argument it takes the data you want to see and it’s going to try to plot that you’ve seen this method with pqt it’s also a part of Matt plot lip once we have this plot we want to show this plot for readability for anyone using your app it’s good to give your app names and more specifically your chart your x axis your y axis in the overall title of this chart the xaxis it could be the length of time years and your y AIS could be how much money you’re earning the title of your chart could be something like interest rate we have a method called Figure and we use this to generate a new figure or if we already have a figure I can get a reference from that but for this app and to start off we are specifically focused on creating a new figure and finally we are going to see the draw method and this is used to redraw a figure and update its contents think about that let’s take a look at how we can now set up a plot if you remember when you initially designed your app you initially designed your app in the chart portion of it as a q label we said in our code self. figure equals Q Lael well now it’s time to change that we are going to change it from Q Lael to say plot remember we imported map plot lib and we’re going to call the figure method creating a new figure now that I have a figure I’m going to be working with this figure in pi QT so I need to give it to the class that we imported this figure canvas class allows us to work with Matt plot lib and Pi QT together we are giving it the plot that we created then we are just adding it to our row so you can do this entirely on your own it’s just updating and tweaking a few parts of your design your initial layout returning to our method now we have one method for calculating interest in our application our code for generating this plot is going to go within that method now these steps are not in any order at all can you reorganize them and put them in the order that they should be in based on the way our code is running if I take them let’s reorganize them okay you can see all the methods that I previously introduced I’m using here to generate my plot my chart we are creating a new plot and I’m making a list of years based on the input that was collected from our q line edit all right I’m using a list it’s going to range a certain amount of times we’re obviously going to start with at least one year and then we want to go for however many years we entered into our q line edit I’m adding one because python starts on zero remember that we are creating a list of Interest over the years and what you see here is called list comprehension this is a slightly more advanced python Topic in your python Journey you may have used list comprehensions before or seen them around but don’t worry in the next few slides I will break down this specific example for you the final three points we have are we want to try to plot the data and then that data we plot it’s going to make a chart I want to give all the titles to my xaxis my y AIS and just the chart in general our chart is 100% set up I now want to update my chart so we can see it on the screen another thing you see here is ax you could call this anything but you will see as a popular naming convention the variable ax is used when working with matplot lip what is list comprehension now when I break that down what are we trying to achieve in this list example well let’s break it down what I want to do is I have a list and this list is called totals and I want to add a certain number of elements to this list if I’m going to invest money for 10 years I want there to be 10 different elements in my list so in my example I have said I’m going to invest for 15 years so I’m going to repeat something 15 times every single time I repeat this Loop I’m taking my list and I’m appending something to it I’m taking my initial investment and I’m multiplying it by the interest rate in the current year this is like how much money you would earn after a year for example if I Chang these numbers and I said 10,000 10% interest rate I would be appending the number 11,000 to my list the first time that ran the next time this ran what do you think we would be having well it’s not going to be 11,000 anymore can we use our input values instead instead of hardcoding these numbers we can remember that we collected the value of everything we entered into the inputs and we converted those to numbers so we already have those as variables let’s now use them initial investment interest rate that’s what we did we went from this we changed it down to this now I’m not hardcoding anymore I’m using the value of of my variables which could be changing it’s whatever the user enters into the app let’s take this one step further we now have this how can I combine these three lines of code into one this is list comprehension now that you understand what we’re trying to achieve in this list let’s combine them in our code you can see that I’m defining a new list called totals you can see my square brackets then the calculation for each element in the list and this just takes our initial investment in the interest rate and it’s squaring it based on the year so all in all this is just one number this is like 11,000 from my previous example then the comprehension is I’m putting a for Loop in my list and I want to repeat the number number of years that we entered in our input remember we stored that in a list years that we created previously let me return now to what we initially saw this was the setup for our code can you implement this let’s try it I want to start to see some charts on our screen let’s head over to VSS code and I will see you guys in the next lesson it’s time to implement map plot lib [Music] you now have a basic introduction to how we can take data and create visual visualizations using this data we have that Library called matplot lib or matplot Library let’s get that into our code at the top we need to get the standard pip plot library or module from matplot lib let’s import matplot lib but the ply plot as PLT that’s the popular naming convention then remember that map PL lib in pi QT have two different backends so there’s a special import we can use when working with matplot lib in pqt we can say here from matplot li. backends backend qt5 a what I want to say here is I want to import specifically figure canvas QT and I can nickname that now as figure canvas so PLT and figure canvas are already popular naming conventions you may see in other code when working with map plot lib with pqt okay I’m going to Mark those we now have this new module imported for our data visualization I want to go down remember that our app has this Q label so I have a property called self. figure but initially I set this to a q Lael we now want to redo that the value of Q Lael is going to be a figure of some sort now this figure I need to create and convert to a canvas remember that a canvas is like a giant container that’s going to hold my figure in pi QT so this canvas is going to be an object actually and we’re going to use that class we imported this is like a wrapper and it’s going to wrap my figure in my canvas we can then just go down and we have actually added in here already I have taken my column I’ve added my figure let’s just change where it says figure let’s now add our canvas marking that off we’ve created this new mat plot lib figure wrapped it in a canvas for pi QT and then set the canvas to our column two okay the design part is done we now need to take that data and convert that and display this in our chart going down here we’re going to do this inside our calc interest method the first part of what we did here was we got our data we converted it and calculated the interest to display inside our Q Tree View what I want to do here is I want to like update my chart with our data this can be done so the first thing I want to do is I want to take my figure and I want to clear it off from any old data we don’t want that then by popular name I’m going to say ax this is like our axis I’m going to create a plot and I’m I’m going to say figure. subplots method this will allow us to generate a chart and if we wanted to I could create one figure or I could have four figures within one so I’ve generated a chart that’s now called ax for all intents and purposes let’s create a list of years so this is potentially going to be the x axis on my chart because as the years go on my interest goes up so my years is going to be a list how many elements do I want in this new list well remember if I enter that I will invest for 10 years I should have 10 elements in this list 1 through 10 So within this list let’s say it’s going to have a range of one all the way to the number of years plus one just like we did up here for our for Loop we have our years I now want to calculate my initial investment for this we are going to do some list comprehension now remember I talked about this in the slides in the lesson this kind of gave you an intro to what list comprehension is and how we can nest in a list to repeat a very similar task so I have a list of totals I’m going to start with calculating the first element so the first element I want to take my initial investment and we’re going to multiply it by our interest rate so that’s going to be 1 plus our interest rate divided by 100 what we want to do is I want to take this and raise it by the year that’s just one element okay all this is working together as one now I want to repeat this for a number of times so I can say here for year in years remember that years is a list we just created so it’s going to Loop for however many years we have in this list every time it’s calculating the interest for the current year and adding it to this list called totals that saves us a lot of code and this is more advanced python that we will see as we progress through our journey next up I have my data that I want to plot so I’m going to take my figure and I’m going to try to plot what do I want to plot well I want to plot the years and I want to plot the totals now that we’ve given some space there let’s take it and let’s give a title so I can use the set title method I can uh use the set X Lael method and we can use the set y label method let’s give a name to everything I’ve now given the names to the Chart the last thing I’m going to do here is I am going to take my canvas and I want to draw on that canvas using that method let’s also go go down here and I’m going to add in two more clears so when we click the reset button I want my figure to also clear I would like the wrapper my canvas to also clear our app is pretty much ready to run let’s go through we cleared any old charts we created a subplot then we generated data so my years is a list my total is all my interest calculated then we set that data to our plot giving it a title an X label a y oh our y label and then we drew on our canvas we can run the app let’s say an interest rate of 10% with a $115,000 investment over 20 years calculate look at that we took our data it’s not only displayed in treeview it’s also displayed in an image a picture this looks incredible our app is almost ready to go I want to have the ability to save this data as a CSV file and this chart as a picture let’s head into the next lesson and let’s talk about how we can save all the data we’ve just generated I’ll see you guys there [Music] we’ve come so far we have implemented not only a new tree view which is like a table but we’ve also implemented a chart using map plot lib our app has come to life it’s now time to add the saving functionality I want us to be able to save all of our table data as well as our chart let’s take a look at how we can achieve this does this look familiar well it should this is our method from our image app that we built in that image app we made a save method and the job of this method was when it was called it was going to save our newly edited photo within a new folder so remember we use the OS module to achieve this OS is our operating system we used our path to join or more specifically to link our directories together we’re going to use that now again we can also use the function make dur which allows us to make a new directory or specifically make make a new folder so start to think how could you create this how could you create a save method for this new app we’re making using the OS module let’s take a look at how we can do this here’s my code written now so in this method I want to be able to create a save folder and it’s going to save my Q tree view data as a CSV file okay then it’s going to take our chart and it’s going to save the chart as a PNG or as a picture so I need to do a few things here we need to get our existing directory remember we have used this before we use this and our image app our Q file dialogue and our get existing directory if we have our path then I want to make a new folder called saved in this folder this is where all of our charts and our CSV files will be saved within our app then what we could do is I can create a new file path and it just links just like the image app remember we created a new edited folder and we took this new folder and we linked it onto the end of our directory the same thing is happening here I create a new saved folder and I link that to the end of my directory now

    that I have this new directory I’m taking this new directory and I am adding my CSV file that I’ve just created using my data to it now that we have that we can open this new file and I I want to write inside of this the name in my CSV file is going to be year and total it’s like two columns then for every Row in my tree view remember our treeview is called self. Model let me repeat that for every Row in my tree view I am going to get two things a year and a total and I’m taking this from the index the position of the First Column zero in my triw the second column is at position one that contains my total I can use the data method to do that once we have this new data for my row then I want to write in my CSV file I’m going to write two things with a comma in between they are going to be formatted to year year will be in the first one total will be in the second one that is what we see Happening Here pause the video read through break it down in our own words we’re going through every row into our Q Tree View and what we’re trying to do is we are going to get the data from the row and save that into our CSV file the code you see here this only applies to our CSV in order to save our chart it’s actually much easier thankfully matplot lib has a method for us called save fig this method works just like the save method we’ve used previously in our apps I can use Save fig and I’m going to give it the full folder name so previously the folder was saved here you could call it results and I’m giving the name to this picture as a friendly reminder at the end what you could do is you could include a q message box or a popup and just tell the user or give them some reassurance that hey yes your data has been saved you can use your Q message box with the information method and the warning method and we can link a few things and say hey congratulations your save was successful or no you actually didn’t select where you want to save to Let’s jump back into vs code and let’s begin to wrap things up the first thing we need to do to wrap up is to add our save functionality I’ll see you guys in our next lesson [Music] it’s time to add our saving functionality remember when we added the save method within our image editing app we needed something called Q file dialogue I’m going to import that right now we can next go down to the bottom of our class after our calc interest I’m going to go right here before reset I’m going to create a method called save data giving itself inside here I want to create a path or my directory path so let’s say directory path is equal to our qfile dialogue do get existing directory we’ve used this before you’ve seen it it’s going to allow us to choose that directory that we want inside here we want to give it self and I’m going to give it a caption so like select directory let’s make sure I spelled self correctly I’m then going to check if this is true so if I did indeed capture a directory we need to make sure that we selected something if we did I want to create a new folder so like a folder path now to do this remember I need OS we don’t have OS yet go up and let’s import OS right down here I’m just going to say import OS all right back down OS path I want to join together what do I want to join well I want to join the directory path that I’ve just made and then I want to join like a new folder so let’s call it like a saved right this is our saved folder it’s going to contain a CSV file as well as an image of our chart I’m then going to access my OS and let’s say OS make dur inside here we can say our folder path that’s the path to make we’re good we’re ready to go now that I have this new folder called save what I can try to do now is I want to save this CSV file and join that to my new path so let’s create a file path and say OS path I would like to join together what do I want to join together well I now have this new path called folder path and it’s going to add results which is going to be a CSV file we can now open this new file path I’ve just created which technically is a CV file we can give it the nickname file anytime that we use this word file now it’s like a nickname and it refers to this file this file is our working directory with our saved folder with our new CSV file so I want to open this CSV file giving it the nickname file inside the headers of this CSV file I’m going to write some stuff inside I’m going to write year and I’m going to write total before putting all the new information on a new line then for every Row in the range of my tree view so I want this Loop to repeat for however many items we have in our model which which is our treeview to do this I can just take our model and I’m going to say okay whatever that row count is of the model that’s how many times this Loop is going to repeat every time this Loop repeats I’m getting a year and I’m getting a total that I’m going to add into the CSV file my year how can I capture the year well let’s take our model let’s index let’s get the position I of the model the row is going to be whatever the current row we’re on that’s just the index of our for Loop what column is the year going to be in well the columns in year one which is at position zero next up let’s just get the data from that the total is going to be the same thing I can take my model I can index the current Row the column is one let’s get that data looks great inside our file I can take my file let’s write these new contents in our file so every row it’s capturing the year and the total and it’s going to write in the CSV line after line after line what do we want to write in every row well let’s just say I’m going to have data here it’s going to have a comma and then I’m going to have more data here I can then format that data how I want it to look and I want it to look like year and then total so let’s format it like that great we’ve saved the data from treeview as a CSV file what we can do now is I can take my map plot lib library and I’m going to say save fig I want to save my chart as a picture and I want to save it in my saved folder right finally at the end here let’s just give a nice little message to the user and say hey um either it’s saved or it didn’t save so just be like save results maybe that sounds nice what would you like to tell the user like uh results were saved to your folder then else I’m making this a part part of the initial condition so else I was not able to find a path to use then I’m going to give the user a warning and I need to alert them to this problem and say save results I can put no directory selected this looks great I’m actually done right here but there’s one thing we’re missing I have a save data method I should have a save button going up we don’t have a save button so I’m going to jump in here and I’m going to make one I’m going to call this save button let’s say save button is once again A Q push button going down let’s just add it right here in column one let’s say column one add widget let’s say save button okay then down with our events we can take our save button let’s give our have a final test all right let’s enter 12% let’s say 25,000 let’s say 20 years calculate let’s click save this is good it asks us where we want to save I’ll say open I’m given an error let’s take a look at how we saved this okay let’s do a few things here so I’m going to trash this the first thing I’m missing is I’m actually I need a command am I reading this file a pending or writing well I’m writing in this file the next thing let’s change this from makor let’s say makers instead make directories and if the directory already exists is that okay let’s just say yeah that’s that’s okay I can save multiple things to that file running my code again let’s say 12% 20,000 20 years calculate save where do we want to save it here is fine Open results we save to your folder okay I got that let me move my app or Shrink it let’s take a look now if you check your side folder you’re going to see results here’s my CSV okay and then you’re going to see the chart we saved as well it’s working our save functionality if I return to our app make it bigger we can press clear and we need to address our clear let’s just change clear to say draw because I want to draw a blank canvas and that’ll fix our issue okay this looks great guys I am so incredibly proud of how far you’ve come let’s jump in now we we going to add some final Advanced design cuz you’ve earned it I’ll see you guys in the next lesson where we’re going to talk about how we can add some styling to our application I’ll see you in the next [Music] video [Music] you can see that every app you’ve built you’ve added a little more styling every app we started with our warmup that random word app and The Styling you learned was the layout and the design you’ve gone to the calculator app we introduced Q font and how you can import a font to our app in the expense app we then introduced CSS and how you can use CSS and style your apps in pqt now for our final app let’s add in some more styling but this is going to be slightly more advanced now that we have a working app you can worry about that dark mode this is not something that you should worry about until you have a working product but it is a fun feature to add and it’s actually easier to implement than you may think in our interest rate calculator how can we add a dark mode Let’s jump in and find out how the last thing we want to wrap up with our app is we’re going to do a bonus dark mode we’re going to tweak any fonts we have add any colors and any styling when we first launch our app this is the template we see but then if we select our dark mode box it’s going to apply that filter to our app you also see that my chart has actually changed I’m going to show you how you can do that as well using map plot lib in order to get our dark mode implemented we will use our CSS styling do you remember how do we use CSS in pqt well you should remember our method set style sheet and we’re going to use that here as well I’m going to create a method and in this method I’m going to check if my checkbox is checked is checked is a method that checks the state of our Q combo box so it checks if you have clicked that now this doesn’t only work for Q combo box if you use a widget called Q radio button for radio buttons you can also use this method to check the state of that we have the method set stylesheet which is going to allow us for our stylesheet when our dark mode is checked I want my background to be a dark color of the whole app my Q labels q line edit Q push button they are going to take a lighter color then my Q Tree View is also going to be a lighter color text with a darker background let’s go back what does the app look like this is what it’s going to look like you can see that my font is now light my input boxes and my buttons Tree View is like this lightish dark gray the main app component is a very dark gray that’s what we’re actually applying here with our styling so remember in CSS we want to Target an element so for example H1 we want to affect anything with H1 and it’s going to take on the color of the text of white the font size the font family well it works the same in pi QT just remember that everything is a string I want to affect my entire app so finance app background color I only want to affect tree view all right so I Target Tree View here now that I created that dark mode I created that apply Styles method this method I am linking to an additional method specifically for toggling or turning on our dark mode we have our object that we made that’s a q checkbox now I want to use a new event this event is called State changed and this event triggers when we change the state of an object or to translate that and break it down this changes when we click a q combo box right I’m changing the state I’m clicking it I’m marking it that is what we want to connect to I want to connect to my toggle dark mode method in return I’m actually checking if my Q combo box is checked if it is it’s going to apply that style let’s wrap things up and let’s head back over into VSS code and wrap up our final application I’ll see you in that [Music] video we are now ready to implement some dark mode and add additional styling to make our app even more unique first thing I’m going to go up top and I want to import Q checkbox this is what we’re going to be using for our dark mode and then going down let’s just create one of an objects here let’s say let’s call this object dark mode and let’s say that is our Q checkbox this Q checkbox is going to say dark mode now that I have that we can add that into our layout so right here I’m going to say self. Row one let’s add in that new object we’ve made at the bottom of in it we have all of our events let’s take that dark mode and let’s say when the state is changed I want to connect to something now we need to make this something so I’m going to mark that right now after in it let’s create a bunch of space here I’m going to create a new method and I’m going to call this let’s call this apply Styles giving itself so first things first let’s set our style sheet remember this is how we do our styling in pqt so I’m going to create this property I’m calling this method set Style sheet and I’m going to give my app some qualities some background colors let me add those in so I’ve created the initial styles for my app when my app boots up it’s going to have these styles with it the initial Styles I can check if my dark mode so I can say if uh self. dark mode is checked we’re using this new method it’s going to check the state to see if it’s clicked so if it is I want to do something and I’m going to change these values so I can take this let’s put it inside and let me tweak these values so you can see now that when my dark mode is checked my background color is changing it was white now it’s this dark color my backgrounds for my other buttons my labels they’re changing as well as my tree view all of these are taking effect when my dark mode is checked great let’s apply these initial Styles remember when the app starts it’s going to have these Styles so I need to automatically apply these up inside in it let’s just go down here and in it and let’s say self. apply Styles and call that method great now carrying on we are going to create a final method and I’m going to call this toggle mode when this method is called the only thing that it’s doing is it’s going to apply Styles it’s going to call the method we made above here what happens is it’s going to hit this condition if it’s checked it’s going to change the styling up in our events right here I can now connect what do I want to connect to well I want to connect to this new method that I just made so let’s say self do toggle mode looking nice I think my app is ready for a quick run Let’s test it okay here’s our app you can see that the styling of everything looks a little different I’m going to click dark mode okay it is working this looks great I can turn that on turn that off turn that off okay let’s style a few more things I’m going to close the app I’m going to return to my Cal interest method right in here let’s go here I’m going to tweak a few things I’m going to say okay uh let’s make sure that every model is cleared before we calculate a new one and let’s take our model and let’s use this we have used this before we’ve said set horizontal header labels inside here here I want my chart to say year and I want my chart to say total okay then the last little tweak I’m going to do is I want my chart to actually have a style so I can take my map plot lib module and I’m going to say PLT cuz that’s referencing it I want to access style and I want to use now you can look up a few of the other styles they have cuz this has changed and it will continue to change but the style I’m I’m going to use and one of the more popular ones is called Seaborn so I’m going to add that in right there let’s run our app and do a final quick run through let’s say 8% interest with 50,000 for 15 years I’m going to click calculate it’s working I’m going to click clear okay we have everything working let’s say 8% let’s say 5,000 let’s say 15 years dark mode working calculate you can see my chart that was working the first time as well looks great I have my total label my year all right let’s click save where do we want to save it open we’re working this is incredible this is absolutely amazing we have shot for exactly what we want in our application you should feel so proud of yourself you have been introduced to so much in this course many new Advanced topics that don’t just include pqt I will see you guys in our next video congratulations and spend some time reviewing your code and seeing how everything came together there for us in the end I’ll see you in our next video [Music] congratulations you have just completed the building apps in Python with pqt course I am so proud of how far you’ve come throughout these last modules you have been introduced to a powerful framework that’s used to create apps in Python this framework is a bridge between C++ and Python and it’s a class-based framework which means you’ve used everything you’ve previously learned in the fundamentals of python and you’ve brought in that knowledge here to create class-based applications you now have four fledged Capstone projects you were introduced to pqt with our calculator app this taught you the layout and the design structure for building apps we let into our image editor app or photo QT here is where you learn that you can use multiple modules to create a single application you then were introduced to SQL in databases through our expense tracking app and for our final project we brought everything together with with our interest rate calculator and data visualization which is a powerful tool in Python I hope that you’ve had as much fun as I’ve had in this course and I look forward to seeing you in other courses that I may have in the zero to KN program congratulations and well done before jumping on to any other courses please spend the next week to hone in the skills you’ve learned and try creating your own project using everything that was taught in this course from data visualization to implementing CSS or adding a database into our applications I’ll see you guys around nicely done

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Python Object-Oriented Programming: Classes, Objects, and Methods

    Python Object-Oriented Programming: Classes, Objects, and Methods

    The provided text introduces object-oriented programming (OOP) concepts using analogies and practical Python examples. It begins by explaining the fundamentals of classes and objects, illustrating these ideas with real-world examples like birds and vehicles. The text then transitions to working with objects in Python, utilizing the Turtle module to visually demonstrate object properties and methods. Subsequent sections cover defining custom classes, including constructors (__init__) and the use of self, followed by explanations and challenges focusing on class inheritance, including single and multiple inheritance. The final part explores special methods (dunder methods) in Python, showcasing their utility in defining object behavior for operators and built-in functions.

    Object-Oriented Programming in Python: A Study Guide

    Quiz

    Answer the following questions in 2-3 sentences each.

    1. What are the fundamental prerequisites for students taking this OOP course, assuming prior Python knowledge?
    2. Describe the core purpose of object-oriented programming (OOP) as highlighted in the introductory lesson.
    3. Explain the concept of “encapsulation” within the context of object-oriented programming.
    4. In OOP, what is the significance of “inheritance,” and how does it relate to classes and objects?
    5. Define the term “object” (or “instance”) in OOP, and provide an analogy used in the source material to illustrate this concept.
    6. Explain the relationship between a “class” and an “object” as described using the “birds” analogy in the lesson.
    7. What are “methods” and “properties” in the context of OOP, and how do they relate to functions and variables?
    8. Why was the “turtle” module chosen as a tool for teaching object-oriented programming concepts in the course?
    9. What is the primary role of the __init__ method within a Python class?
    10. Explain the concept of “multiple class inheritance” and provide a brief example from the source material.

    Quiz Answer Key

    1. Students joining this OOP course should already possess a basic understanding of Python fundamentals. This includes knowledge of conditional statements (like if/else), loops (for/while), functions (defining and using them), and common data structures (such as lists, dictionaries, and tuples).
    2. The core purpose of OOP is to provide a way to organize our code, making it easier to understand, manage, and reuse. It achieves this by treating “objects” as self-contained blocks of code that have their own data and functionality.
    3. Encapsulation in OOP refers to the practice of hiding the internal details and implementation of a specific object from the outside. By concealing these internal workings, it becomes simpler to manage and comprehend the codebase, as interactions with the object occur through a defined interface.
    4. Inheritance is a fundamental concept in OOP that allows for the creation of new classes (derived or child classes) based on existing classes (base or parent classes). This enables the derived classes to inherit properties and methods from the base class, promoting code reuse and the creation of hierarchical relationships between classes.
    5. In OOP, an “object” (often referred to as an “instance”) is a specific realization or example of a class. The source material uses the analogy of building blocks or Legos, where objects are like individual blocks that can be combined to create more complex structures or solve more complex problems.
    6. A “class” is like a blueprint or a family, serving as a template for creating multiple objects with shared characteristics and behaviors. Using the “birds” analogy, the class “Birds” represents the general category, while individual birds like an owl, hummingbird, or canary are distinct “objects” belonging to that class.
    7. In OOP, “methods” are essentially functions that are defined within a class and are associated with the objects of that class, defining the actions an object can perform. “Properties” are variables that are defined within a class and hold the data or attributes of an object.
    8. The “turtle” module was chosen for teaching OOP because, despite seeming like a tool for simple graphics, it’s a valuable resource for strengthening the fundamental understanding of objects. It allows students to visually see how different turtle objects can have their own properties (like color and speed) and perform different actions (methods).
    9. The primary role of the __init__ method (often called the constructor) within a Python class is to initialize the object’s attributes or properties when an instance of the class is created. It is automatically called when you create a new object from a class and sets up the initial state of that object using provided arguments (parameters).
    10. Multiple class inheritance is a feature in OOP where a class can inherit attributes and methods from more than one parent class. In the hybrid car example, the Hybrid class inherited characteristics from the Vehicle, ElectricCar, and GasCar classes, allowing it to possess properties and functionalities from all three.

    Essay Format Questions

    1. Discuss the three core principles of object-oriented programming (encapsulation, inheritance, and polymorphism) as introduced or implied in the provided source material. Provide examples of how these principles contribute to better code organization and reusability.
    2. Analyze the pedagogical approach used in the “zero to knowing object-oriented programming” course based on the provided excerpts. How does the course structure, the use of examples (like the turtle module and the bird analogy), and the inclusion of challenges contribute to student learning and understanding of OOP concepts?
    3. Compare and contrast the concepts of classes and objects, emphasizing their relationship and roles within an object-oriented paradigm. Use examples from the source material, such as the vehicle/car hierarchy or the bird class with its specific bird objects, to illustrate your points.
    4. Evaluate the benefits and potential drawbacks of using inheritance, including single and multiple inheritance, in object-oriented design. Use examples from the course material, such as the superhero classes or the hybrid car example, to support your arguments.
    5. Explain the significance and usage of special methods (dunder methods) in Python classes, particularly focusing on __init__ and __str__ as highlighted in the source material. Discuss how these methods enhance the functionality and representation of objects.

    Glossary of Key Terms

    • Object (Instance): A specific realization or example of a class, possessing the attributes and behaviors defined by its class.
    • Class: A blueprint or template for creating objects, defining the common attributes (properties) and behaviors (methods) that its objects will share.
    • Encapsulation: The bundling of data (attributes) and methods that operate on the data within a single unit (an object), and the hiding of internal implementation details from the outside.
    • Inheritance: A mechanism in OOP where a new class (derived or child class) can inherit properties and methods from an existing class (base or parent class), promoting code reuse and establishing hierarchical relationships.
    • Polymorphism (Implied): The ability of objects of different classes to respond to the same method call in their own specific way. While not explicitly defined, the different behaviors of various turtle objects or bird objects hint at this concept.
    • Method: A function that is associated with an object and defines the actions or behaviors that an object of that class can perform.
    • Property (Attribute): A variable that is associated with an object and holds data or characteristics of that object.
    • Constructor (__init__): A special method in a class that is automatically called when an object of that class is created. It is used to initialize the object’s attributes.
    • Instance Variable: A property that is unique to each individual object (instance) of a class.
    • Module: A file containing Python definitions and statements that can be imported and used in other Python programs.
    • IDE (Integrated Development Environment): A software application that provides comprehensive facilities to computer programmers for software development, such as a code editor, debugger, and compiler/interpreter.
    • Parameter: A variable listed inside the parentheses in a function or method definition. It is a placeholder for a value that will be passed to the function or method when it is called.
    • Argument: The actual value that is passed to a function or method when it is called, corresponding to the parameters in the function/method definition.
    • Data Structure: A way of organizing and storing data, such as lists, dictionaries, and tuples in Python.
    • Conditional Statement: A programming construct (e.g., if, elif, else in Python) that allows different blocks of code to be executed based on whether a certain condition is true or false.
    • Loop: A programming construct (e.g., for, while in Python) that allows a block of code to be executed repeatedly until a certain condition is met.
    • Multiple Inheritance: A type of inheritance where a class can inherit from more than one base class, inheriting their attributes and methods.
    • Dunder Method (Special Method): Methods in Python that have double underscores at the beginning and end of their names (e.g., __init__, __str__). They define special behaviors or operations for objects of a class.

    Briefing Document: Object-Oriented Programming in Python Course

    This document provides a detailed review of the main themes, important ideas, and facts presented in the provided excerpts from an introductory course on object-oriented programming (OOP) using Python. The course aims to move beyond basic Python syntax and delve into the core concepts of OOP, focusing on understanding, management, and reusability of code.

    Main Themes:

    • Fundamentals of OOP: The central theme revolves around understanding the principles and logic behind object-oriented programming. The course emphasizes key OOP concepts and problem-solving using these principles.
    • Practical Application through Challenges: Unlike project-based courses, this is a “challenge-based” course, designed to solidify understanding through practical exercises and coding challenges.
    • Visual and Challenge-Based Learning: The course caters to visual learners with slides and reinforces learning through hands-on challenges.
    • Importance of Foundational Python Knowledge: Students are expected to have a basic understanding of Python fundamentals, including conditional statements, loops, functions, and data structures, before starting the course.
    • Hands-on Coding with the Turtle Module: The course utilizes the turtle module as a practical tool to visualize and understand OOP concepts through drawing and creating art.
    • Defining and Working with Classes and Objects: A significant portion of the course focuses on defining classes as blueprints and creating objects (instances) from these classes, along with understanding their properties (attributes) and methods (functions within a class).
    • Encapsulation, Inheritance, and Polymorphism (Implicit): While not explicitly detailed initially, the course introduces encapsulation (hiding internal details), inheritance (creating classes based on existing ones), and implicitly sets the stage for polymorphism through shared methods with different behaviors across objects.
    • Special Methods (Dunder Methods): The course introduces the concept of special methods (also known as Dunder methods due to the double underscores), highlighting their role in operator overloading and extending the functionality of objects (e.g., __init__, __str__, __del__, __eq__, __add__).
    • Multiple Class Inheritance: The course explores the concept of a class inheriting attributes and methods from multiple parent classes.
    • Dictionaries for Data Management: The course demonstrates the use of dictionaries as a data structure for organizing and managing object information.
    • Customer Loyalty Systems and Bank Accounts as Case Studies: Practical challenges involve building systems like customer loyalty programs and bank accounts to illustrate OOP principles in real-world scenarios.

    Most Important Ideas and Facts:

    • Course Prerequisites: Students should already possess a “basic python understanding such as what are conditional statements Loops functions and the data structures we use in Python.”
    • Course Structure: The course includes “slides for our new topics live coding exercises as well as quizzes.”
    • Importance of IDE: The course guides students through installing Python and an Integrated Development Environment (IDE) like VS Code.
    • “I highly recommend that you get a shortcut and you save this to your desktop or your icon bar at the bottom of your window as we’re going to be using vs code a lot it’ll be handy to have a shortcut.”
    • Definition of OOP: OOP is “a way to organize our code this makes it easier to understand manage and reuse.”
    • Objects: Objects are like “blocks of code” or “building blocks or like Legos” with their own “properties attributes” and “functions methods.” An “instance is an object…an example from a class.”
    • Classes: A class is like a “blueprint” or a “family,” a “group of similar objects Under One Roof.” It’s a template for creating multiple objects with shared properties and methods.
    • Encapsulation: This involves “hiding all the internal details of one specific object from the outside” to improve manageability and understanding.
    • Inheritance: This “allows for the creation of classes…used to create multiple objects with shared properties and methods.”
    • Methods vs. Properties:“A method is a function…specifically it is a function in a class.”
    • “A property is a variable…specifically a variable in a class.”
    • The turtle Module: This module is used for drawing and creating art and is a “Hidden Gem for learning oop” by strengthening the fundamentals of objects.
    • Constructor Method (__init__): This is a special method that is “automatically ran when an object is created.” It’s used to “build our class.”
    • “This method is called __init__…it has two underscores in the beginning and after init that’s very important…we must use this as our Constructor…always the first method in our class…init just means to initialize just means to start.”
    • The self Keyword: “We use the word self in a class now self it’s basically a key and it unlocks the class so we can use all the properties and all the methods within that specific object.”
    • Operator Overloading and Special Methods: Dunder methods extend the meaning of operators.
    • “__str__ Returns the object representation in a string format…commonly used to define human readable strings.”
    • “__del__ called when an object is about to be destroyed…used to perform any final actions before the object is removed from the program’s memory.”
    • “__eq__ allows us to compare the values of two objects using the equal sign operator.”
    • “__add__ allows objects of a class to be added together.”
    • Multiple Inheritance: A class can inherit from multiple parent classes by listing them within the parentheses in the class definition.
    • Dictionaries: Used as a data structure with “key pairs” where a “dictionary key unlocks a value.”

    Quotes:

    • “this is not a project-based course but rather a challenge-based course to really hone in your understanding of o key Concepts in the overall logic we need to solve these problems”
    • “it’s designed for those of you who want programing broken down to a different level of understanding it’s designed for the visual Learners as well as challenge based Learners”
    • “objects are like building blocks or like Legos and they can be used to create more complex problems or if you’re building with Legos more complex designs”
    • “inheritance allows for the creation of classes…this can be used to create multiple objects with shared properties and methods this is going to be a powerful tool as we go forward”
    • “a method is a function in a class A Proper is a variable in a class”
    • “Turtle module is a Hidden Gem for learning oop throughout my years of teaching I have seen Turtle strengthen the fundamentals of objects in my students”
    • “if you remember from lesson one I said to think of a class as a blueprint this still applies now a especially going forward a class is a blueprint”
    • “a class is always capitalized it is one of the very few things in Python you capitalize a class is followed by a set of parentheses capitalized parentheses”
    • “self it’s basically a key and it unlocks the class so we can use all the properties and all the methods within that specific object”
    • “__init__ has two underscores in the beginning and after init that’s very important we must use this as our Constructor this is always the first method in our class in just means to initialize initialize just means to start”
    • “__str__ This method creates a string representation of our object it’s called by the builtin string function”
    • “__del__ this method is called when an object is about to be destroyed destroyed it’s used to perform any final actions before the object is removed from the program’s memory”
    • “dictionary key unlocks a value dictionary key unlocks a value anytime you want the value of a dictionary you need to insert the dictionary key the key unlocks a door the same thing for a dictionary”

    This briefing document highlights the key aspects of the OOP in Python course based on the provided excerpts, emphasizing the learning approach, fundamental concepts, and practical applications covered.

    Object-Oriented Python: A Challenge-Based Course

    1. What fundamental Python knowledge is expected for this course on object-oriented programming (OOP)?

    Students joining this OOP course should already have a basic understanding of Python, including conditional statements (like if, else, elif), loops (for, while), functions (defining and using them, understanding parameters and arguments), and fundamental data structures (like lists, dictionaries, and tuples).

    2. What is the primary learning approach of this OOP course?

    This course is not project-based but rather challenge-based. It aims to deepen students’ understanding of key OOP concepts and the logic required to solve programming problems. It is designed for visual learners and those who learn best through overcoming challenges.

    3. How is the course structured in terms of learning materials and activities?

    The course includes slides for introducing new topics, live coding exercises where concepts are demonstrated and applied in real-time, and quizzes to assess understanding.

    4. What is object-oriented programming (OOP) and what are its core principles as introduced in this course?

    Object-oriented programming (OOP) is a way to organize code to make it easier to understand, manage, and reuse. It treats “objects” as fundamental building blocks of code, where each object has its own properties (attributes) and functions (methods). Key principles introduced include: – Encapsulation: Hiding the internal details of an object from the outside to improve manageability and understanding. – Inheritance: Allowing the creation of new “classes” (blueprints) that inherit properties and methods from existing classes, promoting code reuse and the creation of specialized objects.

    5. How are the concepts of “class” and “object” explained in the context of OOP?

    A class is described as a blueprint or template for creating objects. It defines the general characteristics (properties) and behaviors (methods) that objects of that class will have. An object (or instance) is a specific realization of a class. Think of a “Bird” as a class; an “owl,” “hummingbird,” and “canary” are individual objects (instances) of that Bird class, sharing common traits but also having unique ones.

    6. Why does the course utilize the Python “turtle” module?

    Despite seemingly being for beginners or for creating art, the turtle module is used in this OOP course as a valuable tool to strengthen the fundamental understanding of objects. It visually demonstrates how objects have properties (like color and speed) and can perform actions (methods like moving forward or turning), making abstract OOP concepts more concrete.

    7. What is the relationship between “methods” and “properties” in OOP?

    In the context of a class: – A method is a function defined within a class. It represents an action that an object of that class can perform. – A property is a variable defined within a class. It represents a characteristic or attribute of an object of that class. Both methods and properties are linked to specific objects to work or be accessed.

    8. What is “class inheritance” and how is it demonstrated in the course?

    Class inheritance is a mechanism in OOP where a new class (the derived or child class) can inherit properties and methods from an existing class (the base or parent class). This allows for code reuse and the creation of a hierarchy of classes where more specific classes build upon the foundation of more general classes. The course demonstrates this through examples like a Superhero class being inherited by a Flying subclass, where the flying superhero inherits basic superhero traits and adds specific flying-related attributes and behaviors. Multiple inheritance, where a class inherits from more than one parent class, is also introduced.

    Python Object-Oriented Programming Fundamentals

    Object-Oriented Programming (OOP) is described as a way to organize code, making it easier to understand, manage, and reuse. It’s a crucial and advanced concept in Python and programming as a whole. This course aims to take your Python skills to a higher level by focusing on key OOP concepts.

    Here are some fundamental ideas behind OOP as presented in the sources:

    • Objects: In OOP, code is organized around “objects”. You can think of objects as blocks of code, where each object has its own properties (attributes) and its own functions (methods). An object is also referred to as an instance of a class. Objects can be likened to building blocks or Legos that can be used to create more complex problems or designs.
    • Classes: A class is like a blueprint or a template for creating many objects with shared properties and methods. It’s like a family or a group of similar objects under one roof. A class is always capitalized in Python.
    • Encapsulation: This is a key concept in OOP and involves hiding all the internal details of one specific object from the outside. By hiding these details, it becomes easier to manage and understand the code.
    • Inheritance: Another core concept, inheritance allows for the creation of new classes (child classes or derived classes) that inherit properties and methods from existing classes (parent classes or superclasses). This promotes code reusability. The course will cover class inheritance as well as multiple class inheritance.
    • Methods and Properties: A method is essentially a function within a class, while a property is a variable within a class. Both methods and properties must be linked to an object in order to work.
    • Constructor (__init__): This is a special method within a class that is automatically run when an object is created. Its purpose is to build or initialize the object, often by defining the initial values of its properties. It is always the first method in a class and has double underscores before and after init. The __init__ method takes self as its first parameter, which acts as a key to unlock the class so you can use its properties and methods.
    • The super() function: When a child class inherits from a parent class and needs to initialize properties of the parent class or call its methods, the super() function is used. It allows a child class to inherit properties and methods from its superclass and is particularly important when a child class also introduces its own new properties, requiring a new constructor.

    The course mentioned in the source material, “zero to knowing object orientated programming and python course,” aims to provide a strong foundation in these fundamental OOP concepts. It is designed for beginners to intermediate students who already have a basic understanding of Python fundamentals such as conditional statements, loops, functions, and data structures. The course uses a challenge-based approach to hone understanding of key OOP concepts. The Turtle module is specifically used in the course as a tool to strengthen the understanding of how objects work.

    Furthermore, Python has special methods (also known as dunder methods because of their double underscore prefix and suffix, e.g., __init__) that provide extended meaning beyond their predefined operational meaning. These methods make operator overloading possible. Examples include __str__ (for string representation of an object), __del__ (for actions before an object is deleted), __len__ (to return the length of an object), __eq__ (to compare object values), __add__ (to add objects), and others.

    In summary, OOP is a programming paradigm centered around objects and classes, emphasizing concepts like encapsulation and inheritance to create modular, maintainable, and reusable code.

    Classes and Objects: An Introduction

    Let’s delve deeper into classes and objects, which are fundamental to Object-Oriented Programming (OOP) as discussed in the sources and our previous conversation.

    Classes

    • A class is best understood as a blueprint or a template for creating objects. It defines the structure and behavior that a group of similar objects will share. Think of it as a general overview or a sketch containing the necessary information to create an actual entity.
    • In Python, a class is defined using the class keyword followed by a unique name, which by convention, is capitalized.
    • The code within a class can include methods (functions within the class) and properties (variables within the class). These define what an object of that class can do and what characteristics it possesses.
    • A class can serve as a “family” or a group of similar objects under one roof. For example, “Birds” could be a class, encompassing various types of birds as objects. Similarly, “Vehicles” could be a class with objects like “car,” “truck,” and “van”.
    • Classes can have special methods, the most crucial being the constructor method, __init__. This method is automatically executed when an object of the class is created. Its primary purpose is to initialize the object’s properties. The __init__ method always takes self as its first parameter, which acts as a reference to the instance being created.
    • Classes can also have other special methods (dunder methods) like __str__, __del__, __len__, __eq__, __add__, etc., which define how objects of the class behave with built-in Python operations.

    Objects

    • An object is an instance of a class. It is a concrete entity created based on the blueprint provided by the class.
    • Each object has its own set of attributes (properties), which are like variables that hold data specific to that object. For instance, if “Car” is a class, individual car objects might have different values for properties like “color,” “model,” and “number of wheels”.
    • Objects can also perform actions through their methods, which are like functions that operate on the object’s data.
    • When you create an object, you are essentially calling the class like a function, which in turn invokes the __init__ method to set up the initial state of the object. For example, T1 = Turtle() creates an object named T1 which is an instance of the Turtle class. Here, Turtle is the class, and T1 is the object.
    • The value of an object is its class.
    • Methods must be linked to an object to be executed. You call a method on an object using dot notation (e.g., car.drive()). Similarly, you access an object’s properties using dot notation (e.g., car.color).

    Relationship between Classes and Objects

    • A class is a definition, while an object is a realization of that definition. You can create multiple objects from a single class, and each object will have the attributes and behaviors defined by the class, but with potentially different values for its attributes.
    • Think of a cookie cutter (class) and the cookies it produces (objects). The cookie cutter defines the shape, but each cookie is a separate instance with its own characteristics (e.g., amount of frosting).

    In summary, classes serve as the templates for creating objects, which are the actual entities that you work with in your program. Classes define the characteristics (properties) and capabilities (methods) that their objects will possess. The process of creating an object from a class is called instantiation. Understanding classes and objects is fundamental to grasping the principles of Object-Oriented Programming and writing well-structured and reusable code.

    Object-Oriented Programming: Class Inheritance Explained

    Let’s discuss class inheritance, a core concept in Object-Oriented Programming (OOP) that we’ve touched upon in our previous discussions. Class inheritance allows for the creation of new classes, known as child classes or derived classes, that inherit properties and methods from existing classes, called parent classes or superclasses. This concept mirrors real-world inheritance, where a child inherits traits and characteristics from their parents.

    Here’s a breakdown of class inheritance based on the sources:

    • Purpose and Analogy: Inheritance is a mechanism for code reusability. Instead of writing the same code multiple times in different classes, you can define common attributes and behaviors in a superclass, and then have subclasses inherit them. The source uses the analogy of family relationships, where a child class inherits characteristics from a parent class. For example, if you have a Car class, you could create a Vintage class that inherits the basic properties of a Car but also has its own specific properties, like price.
    • Superclass and Derived Class:
    • The superclass (or parent class) is the class whose properties and methods are being inherited. It’s the more general class. The source also refers to the superclass as the “main class”.
    • The derived class (or child class) is the new class that inherits from the superclass. It can have its own unique properties and methods in addition to those it inherits.
    • Syntax: In Python, you specify inheritance when defining a new class by putting the name of the superclass in parentheses after the name of the child class. For example, class Vintage(Car): indicates that the Vintage class inherits from the Car class.
    • Two Routes to Inheritance: The sources describe two main approaches to inheritance:
    • Route One: Inheriting only new methods. In this scenario, the child class only needs to add new functionalities (methods) and does not introduce any new properties. Because no new properties are being added, the child class does not need its own __init__ (constructor) method. It will automatically use the __init__ method of the superclass.
    • Route Two: Inheriting new properties as well as new methods. When a child class needs to have its own unique properties in addition to those inherited, it needs to define its own __init__ method. Within this child class’s __init__ method, you must also activate the superclass’s __init__ method to ensure that the inherited properties are properly initialized. This is achieved using the super() function. The syntax would look like super().__init__(…), where … includes the parameters required by the superclass’s __init__ method. After calling super().__init__(), you can then define and initialize the new properties specific to the child class.
    • Method Overriding: When a subclass defines a method with the same name as a method in its superclass, it overrides the superclass’s method. When the method is called on an object of the subclass, the subclass’s implementation is executed.
    • Accessing Superclass Methods: Even when a subclass overrides a method, it can still call the superclass’s version of that method using the super() function (e.g., super().some_method()).
    • Multiple Inheritance: Python also supports multiple inheritance, where a class can inherit from more than one superclass by listing them within the parentheses in the class definition, separated by commas (e.g., class Hybrid(Vehicle, ElectricCar, GasCar):). In such cases, the child class inherits attributes and methods from all the listed superclasses.
    • Examples from the Sources:
    • Vintage inheriting from Car, adding a price property.
    • Clinic inheriting from Animal, adding methods to search for animals by region without needing new properties.
    • Flying inheriting from Superhero, adding a speed property and methods related to flying.
    • Hybrid inheriting from Vehicle, ElectricCar, and GasCar, combining attributes of different vehicle types.
    • FictionBook and NonFictionBook inheriting from BookLogic, each adding a specific property (genre and topic respectively).
    • DevelopedCountry and DevelopingCountry inheriting from Country, each adding specific economic indicators (GDP and HDI).
    • Bird inheriting from Animal and CanFly (an example of multiple inheritance).
    • Customer and Seller inheriting from User.
    • Manager and Staff inheriting from Employee.
    • Football and Basketball inheriting from Sport, each having a team property and specific behaviors.
    • Book and DVD inheriting from Item, and LibraryItem inheriting from both Book and DVD.
    • Bitcoin and Ethereum inheriting from Crypto.

    In summary, class inheritance is a powerful mechanism in OOP that promotes code organization and reusability by allowing you to create specialized classes based on more general ones. By understanding the concepts of superclasses, derived classes, and the use of the super() function, you can effectively leverage inheritance to build more efficient and maintainable Python programs.

    Python Special (Dunder) Methods Explained

    Let’s discuss special methods, often referred to as dunder methods (due to their double underscore prefix and suffix, e.g., __init__), in Python. These methods are crucial for defining how objects of your classes interact with built-in Python operations, functions, and syntax. They enable operator overloading, allowing you to define custom behavior for operators like +, -, ==, and functions like len(), str(), etc., when used with instances of your classes.

    Here’s a breakdown of special methods based on the sources:

    • Definition and Purpose: Dunder methods are special methods in Python that have double underscores at the beginning and end of their names. They provide a way to give extended meaning beyond their predefined operational meaning to your classes and objects. Essentially, they allow you to customize the behavior of your objects in response to various Python operations.
    • Naming Convention: The double underscore naming convention (__method_name__) is a standard in Python to indicate these special methods that have predefined meanings.
    • Automatic Invocation: Python often calls these methods implicitly when you use certain operators or built-in functions on objects of your class. For example, when you use the + operator between two objects, Python will look for the __add__ method in their classes.
    • The __init__ Method (Constructor): This is perhaps the most common special method. __init__ is the constructor for a class. It is automatically called when an object of the class is created. Its primary purpose is to initialize the object’s attributes (properties). The __init__ method always takes self as its first parameter, which refers to the instance being created, followed by any other parameters needed to initialize the object’s state.
    • Examples of Other Special Methods (from Source 09.pdf and 13):
    • __del__(self) (Delete): This method is called when an object is about to be destroyed (deleted from memory). It can be used to perform any final cleanup actions before the object is removed. However, the source notes that it is not very commonly used.
    • __str__(self) (String Representation): This method is called by the built-in str() function and when you use the print() function on an object. It should return a human-readable string representation of the object. This is useful for debugging and displaying object information in a user-friendly format. If an object doesn’t have a __str__ method, Python will use a default representation, which is less informative.
    • __len__(self) (Length): This method is called by the built-in len() function and should return the length of the object (if it has a concept of length).
    • __eq__(self, other) (Equal): This method is called when you use the equality operator == to compare two objects. It should return True if the objects are considered equal based on your defined criteria, and False otherwise. The other parameter refers to the object being compared to self.
    • __add__(self, other) (Addition): This method is called when you use the addition operator + between two objects. It should define how the objects are “added” together and typically returns a new object representing the result. The other parameter represents the object being added to self. You can implement type checking within this method to ensure that addition is only performed with compatible objects.
    • __sub__(self, other) (Subtraction): Similar to __add__, this method is called when you use the subtraction operator – and defines how objects are subtracted. It also typically returns a new object.
    • Relevance to Object-Oriented Programming: Special methods are a fundamental part of making your classes behave like native Python objects. By implementing these methods, you can:
    • Make your objects printable in a meaningful way using __str__.
    • Define how equality is determined for your objects using __eq__.
    • Enable the use of arithmetic operators (+, -, etc.) with your objects in a way that makes sense for their domain.
    • Integrate your objects with built-in Python functions like len().
    • Further Exploration: The sources mention that there are endless special methods beyond these examples. As you continue your programming journey, you will encounter and may need to use other dunder methods to customize the behavior of your classes for various purposes.

    In essence, special methods (dunder methods) are a powerful feature in Python that allow you to imbue your classes with rich behavior by defining how their instances interact with the core language constructs. They are a key aspect of writing Pythonic and object-oriented code.

    Python Fundamentals: A Concise Overview

    Let’s discuss some of the fundamental concepts of Python that are essential for programming, particularly as a foundation for Object-Oriented Programming (OOP), as highlighted in the sources.

    According to the sources, before diving into OOP in Python, a solid understanding of the following fundamental concepts is expected:

    • Variables: These are used to store data values. The sources demonstrate the assignment of values to variables within and outside of classes.
    • Functions: These are blocks of reusable code that perform specific tasks. You should understand how to define a function using the def keyword and how to call a function. The concepts of parameters (defined in the function signature) and arguments (the values passed when calling a function) are also crucial. The sources provide numerous examples of defining and using functions and methods (which are functions within a class).
    • Loops: These control structures allow you to execute a block of code repeatedly.
    • for loops are used to iterate over a sequence (like a list) or a range of numbers. The sources show for loops being used for drawing shapes with the turtle module and for iterating through lists of objects.
    • while loops continue to execute as long as a certain condition remains true. One source demonstrates using a while loop with user input.
    • Conditional Statements: These allow your program to make decisions based on certain conditions.
    • if, elif (else if), and else statements are used to create these decision-making structures. The sources illustrate conditional statements for login validation and checking object types.
    • Understanding logical operators (like and, or, not, ==, >, <) is essential for constructing complex conditions.
    • Data Structures: These are ways to organize and store collections of data. The sources mention several key data structures:
    • Lists: Ordered, mutable sequences of items, enclosed in square brackets []. Lists are used to store colors, objects, and grades in the examples. Methods like append() and remove() are also used.
    • Dictionaries: Unordered collections of key-value pairs, enclosed in curly braces {}. Dictionaries are used to store country information and crypto portfolio details. The syntax for accessing values using keys is highlighted.
    • Tuples: Ordered, immutable sequences of items, enclosed in parentheses (). While not extensively used in the provided code snippets, they are a fundamental data structure in Python.
    • Sets: Unordered collections of unique elements, enclosed in curly braces {}. Sets are used to manage unique team names in the sports challenge.
    • Modules: These are files containing Python definitions and statements. The import statement is used to bring modules into your current program. The turtle module for graphics and the random module for generating random numbers are used in the examples. The syntax from module import * imports everything from a module.
    • Basic Python Lingo: This refers to understanding common terms and syntax used in Python programming.
    • Input and Output: The input() function is used to get user input, and the print() function is used to display output.
    • String Formatting: Techniques like f-strings (formatted string literals, using f’…’) are used to embed expressions inside string literals for more readable output.
    • File Input/Output: The open() function is introduced for working with files, specifically writing to text files using the ‘w’ mode and the write() method. The with open(…) as file: construct ensures proper file handling.
    • Built-in Functions: Functions like sum() to calculate the sum of elements in a list and len() to get the length of a sequence are used.
    • Operators: Understanding various operators, including arithmetic operators (+, -, *, /), comparison operators (==, !=, >, <, >=, <=), and the in operator for checking membership in a sequence.
    • isinstance() Function: This built-in function is used to check if an object is an instance of a particular class.

    The sources emphasize that a good grasp of these Python fundamentals is crucial because OOP in Python builds upon these concepts. For instance, methods within classes are essentially functions, and they often utilize loops, conditional statements, and data structures to implement their logic. Understanding how to work with modules allows you to extend the functionality of your programs by using pre-built libraries like turtle and random. Even special methods (dunder methods) operate within the framework of these fundamental concepts.

    Therefore, mastering these Python fundamentals will significantly enhance your ability to understand and effectively utilize object-oriented programming principles as taught in the provided course.

    Object-Oriented Programming with Python in 2024 | 7-Hour FREE Course for Beginners

    The Original Text

    if you’re ready to take your python skills up a level this is the video for you over the next 7 hours I’m going to take you on an objectoriented Journey with oop program taking you through these Advanced crucial Concepts in Python and we’re really going to focus on two key Concepts encapsulation and inheritance this course Builds on your core foundational skills so far in programming and it’s an extension of my python for absolute beginners course that I released at the beginning of the month right it’s still absolutely free that’s the best part 7 hours of more premium content coming at you for free if you guys enjoy this stuff do me a favor for this course like And subscribe to this I know right but liking helps this course reach more students people who could really use this course and comment your thoughts below if you’ve been feeling overwhelmed by this topic o right let me break it down for for you I’ve got you covered by the end of this course you’re going to have mastered a crucial concept not only in Python but in programming Concepts as a whole with over 7 years in the education space I’ve created interactive lessons in materials as well as live coding exercises that’s right all these challenges to further your understanding l p if you’re ready I’ve been ready let’s Dive In [Music] welcome to a code with Josh special don’t skip this part guys all right the next few minutes are the most important few minutes of this course because I’m going to break down who this is for is it even for you all right and who this is going to work best for how to go through this course all right so just give me a few minutes here right this is my extension to really break down a key crucial Concept in programming right o or objectoriented program all right now this is a topic that I did Cover in my course python for absolute beginners I’ll put that here all right that was still free for you right but it’s a rather crucial and advanced concept this course is dedicated to furthering your understanding in this crucial concept of oop through encapsulation and inheritance all right now if you’re new to programming this is not the course for you okay you should understand python as a whole already right control structures functions modules all right you should maybe have worked with classes before if you haven’t that’s okay right because I’m not going to teach program the basics of that I’ve done that in my previous course all right now here is going into o we’re going to further that and I want to emphasize too this is not a Project based course all right I do have projects in this but I want you to think of these projects as more like challenges or scenarios as we work through and introduce you to more advanced oop Concepts now guys also this is still 100% free right I’m not getting paid anything for this but I’m hosting this course as well as my other course for you guys on my own platform Zer towing.com I’m going to put that as the first link in the description all right head on over there and you get a boatload of free resources for you right my handcrafted python guide you get an Interactive Learning Community to chat with others and learn that’s key all right if you’re going to hold yourself responsible and you want to progress and learn don’t sit here and watch a YouTube video it’s not going to happen all right by learning engaging asking questions answering questions that is how we learn right so check out the platform it’s absolutely free it’s the link in the description all right um and that’s just going to bring you guys a smoother viewing experience right it’s still free and uh so use it all right now this course guys I have timestamps use the timestamps if there are topics you know Skip ahead to that topic indulge in it comment ask questions all right and code along the way all right I’m really excited for this right any questions let me know all the resources I have for you guys are in the description all right I think I think that’s it over to the course [Music] enjoy hi and welcome to the zero to knowing object orientated programming and python course my name is Josh with over five years in the education field for which two of the last have been specifically with python I’ve taught teens all the way to young adults I’ve taught hundreds of students and I’m here to share my knowledge with you let’s jump into a general course overview of what you can expect throughout this class throughout this class you are going to build a strong foundation in the fundamental concept of objectoriented programming you’re going to use your existing python skills as we grasp New Concepts and you learn new ways to implement your logic the knowledge you gain in this course is going to be instrumental in your programming Journey from here on out and as we go through our lessons we are going to build on each previous lesson and this is going to give you a good understanding of O and the general concepts that come with it I’ve seen many students struggle with this topic or try to speed past this topic topic of objectoriented programming this course is designed to give you a strong foundation in those important fundamentals that we will use in any o language many online courses have too much and some of the fundamental concepts get brushed over because of too much material all-in-one courses don’t spend enough time strengthening your foundation skills I’ve broken this course down to a level that’s easy for you to understand this course is structured in the best possible way so as you progress through it’s gradually going to get harder building on the skills that you’re learning from the previous lessons throughout this course you will get an overall idea of what is objectoriented programming you will spend time working with different objects spend time defining your own classes and objects we together will grasp the concept of class inheritance as well as the concept of multiple class inheritance and finally to end this course you are going to learn about Dunder methods or the special methods that come with objectoriented programming in Python who is this course designed for this course was created for beginners to intermediate students in mind and will not teach you the fundamentals of python but rather the fundamentals of oop students who join this class should already have a basic python understanding such as what are conditional statements Loops functions and the data structures we use in Python this is not a project-based course but rather a challenge-based course to really hone in your understanding of o key Concepts in the overall logic we need to solve these problems it’s designed for those of you who want programing broken down to a different level of understanding it’s designed for the visual Learners as well as challenge based Learners throughout this course you will have slides for our new topics live coding exercises as well as quizzes I can’t wait for us to get started and to take a closer look at object or orientated programming I’ll see you guys in [Music] class before we get started with our course this video is for those of you who do not have python installed on your computer and do not have an IDE like vs code if you have both of those you can skip this video and head into the first lesson if you don’t this is the right video to help you get set up first up let’s get Python and install that on your local environment your system on Google I would like you to just Google Python and it should be the first list link or it’s going to be the first unsponsored link I’m going to click welcome to python it takes you to the python page now here is where you can find any documentation or anything to help you with python what I’m interested in is I want to scroll down and we see all these subtitles I have get started download docs today we’re interested in download and I’m going to click the latest version python Pyon 3.11 now do not worry by the time you watch this video this version of python may have changed and that’s okay because currently what I’m on is python 3.10 as you can see this is 3.11 so it’s it’s fine at the very bottom you are going to see these files now it’s very important here if you are in a Mac you are going to click the Mac universal installer if you’re on a Windows you can click the windows installer 64bit I’m going to click Mac CU I’m on a Mac and then in the top it is going to download python once python is done downloading you need to go through the steps for installation so open it run it and go through those steps I’m not going to do so only because I already have this on my system great over on Google we need to get a an IDE now you have plenty of options for this you could use Sublime atom or what I personally use is VSS code so I’m going to go into Google and I’m going to search for VSS code there it is it is the first link visual studio.com visual studio is great and it’s wildly popular amongst developers around the world if we go in here you can just click the first link it takes you to the homepage you’re GNA see a big blue button here now depending on your operating system this will change I am on a Mac so it tells me to download Mac universal if you’re in a Windows it’s going to tell you to download the windows Universal you can click here and then just like python it’s going to download in the top right once VSS code is done downloading you can open it and go through the steps for installation I I highly recommend that you get a shortcut and you save this to your desktop or your icon bar at the bottom of your window as we’re going to be using vs code a lot it’ll be handy to have a shortcut I’ll see you guys in the next setup [Music] video [Music] hi and welcome to the zero to knowing object orientated programming course this is lesson one before we jump in and start coding or anything like that we need to start at the very beginning and we need to discuss what is is object orientated programming or simply put O Let’s jump in to further discuss and break down what exactly oop is I have made a list of bullet points it’s a way to organize our code this makes it easier to understand manage and reuse all objects that they are like blocks of code and they each have their own properties attributes in their own functions methods simply put if I could explain it like this is objects are like building blocks or like Legos and they can be used to create more complex problems or if you’re building with Legos more complex designs in O there’s a big word and it’s called encapsulation and this is hiding all the internal details of one specific object from the outside by hiding this it makes it easier for us to manage and for us to understand the code then the Holy Grail of oop we have inheritance this makes programming with objects amazing inheritance allows for the creation of classes now going forward I want you to think of a class as a blueprint and this can be used to create multiple objects with shared properties and methods this is going to be a powerful tool as we go forward let’s take a look at what an object really is so on the screen each object right so I have object one object two object three they each have their own attributes so in this example an attribute could be considered color they each look different they have their own color and they have their own unique actions but at the end of the day all of these are objects or all of these are squares per se all right so just remember an object has its own properties its own attributes as well as its own actions what can this object do here’s a fun example I’ve put together and going forward in the coming lessons I’m going to use examples like this here is an example of objects now they are all birds we can see that they’re all birds and they share some of the same properties but then they all have unique properties of their own so some common characteristics of all of these objects they all have two legs and they all can fly those are shared properties some unique properties for example is I have a type of bird hummingbird this hummingbird is only found in the Americas these are unique properties that only this bird has so you can see we have four different objects and an object I want you to remember this word instance I prefer to use the word object but in other programming documentation you will probably see this word instance more than once an instance is an object it’s an example from a class so this object is from this class now a class is like a family it’s a group of similar objects Under One Roof all of these are unique Birds but at the end of the day they are all birds if I asked you what animal is that you would tell me it’s a bird if I asked you to be very specific what type of bird is that well that bird is a parrot and that bird is an object this is how object orientated programming is broken down let’s move on a little more I’m going to give you guys a brainstorm Challenge and I want you to take the next five minutes I would like you to think of three different classes remember family and for each class I would like you to think of three objects as an example if I go back I have one family Birds then three objects would be owl hummingbird Canary that’s one example I would like you guys to think of three more classes each class with three objects pause the video here write down down what you come up with pause the video here and write down what you come up with before moving on great some examples that I’ve come up with I have put in the source code for this lesson and I’ve also put it here these could be three examples that I came up with I have a class A family of vehicles right each of these are different object at the end of the day they’re all vehicles but when you get specific one object is a car one is a truck one is a van and one is a luxury vehicle they’re all different types I have a class for furniture but Furniture is very broad what are some objects that come from this class chair sofa table bed finally I had a class of countries and then we have us Thailand Vietnam and France they’re all different countries at the end of the day they are all a country they come from a class countries great I would love to hear what you guys came up with so be sure to put it in the Q&A of this lesson before moving on to working with objects in lesson two at this point in your python Journey you should all already have a decent understanding of the following variables functions Loops conditions as well as some basic python lingo you can see on the screen I’ve made some categories in the first one I have functions now when it comes to functions you should understand both of these how to define a function and if I use the word parameter or argument you should understand what that is too with loops you should know how to set up W loops and for loops and why we use both of these you should understand our conditions and conditional statements which means creating your own and all the logical operators that come with that you should know some basic data structures this could be your dictionaries as well as lists and tles all of these were acquired over the fundamentals of python which you should have learned going forward with object orientated programming this is more of an intermediate to an advanced topic I will be using function Loops conditions and data structures throughout this program if you’re unfamiliar with any of these please look some of them up before moving on I will see you guys in lesson two working with [Music] objects welcome back to lesson two in the last lesson we introduced what exactly is objectoriented programming in this lesson we are going to begin working with objects in Python this will strengthen your understanding of what an object is and how we use this to work with objects I am going to introduce a special python module to work with object objects I am going to introduce a special python module this module is called turtle and turtle is a module in Python which allows us to draw and create art but you’re probably asking Josh I signed up for a course on object-orientated programming why are we doing this module although this seems like something for kids Turtle module is a Hidden Gem for learning oop throughout my years of teaching I have seen Turtle strengthen the fundamentals of objects in my students that is why I’m using it in this course and this module is going to give you a strong understanding of how objects work in programming and how we can use them throughout our code in the picture on the left we have nine objects all of which are turtles each turtle though has its own properties so its own color and it very well may have its own speed and they all have different actions that can do different tasks now two new key words that I introduced in the last lesson what are methods and properties let’s dive in and let’s take a look a method is a function all right so simply put if we boil everything down a method is a function do not forget that specifically it is a function in a class a property is a variable specifically a variable in a class if you have to say that a few times that’s okay a method is a function in a class A Proper is a variable in a class I want you to think about how do you use variables how do you define variables good got it how do you make a function how do you use a function you should know those and you should start to think about those on the left I have three different properties I have a color a speed and a width if we think of these like a variable which you should I have my variable and then the value to the variable is here so our color its value is maroon parrot speed its value is five Canary width its value is two now a property and a method must be linked to an object in order to work so color is linked to the object owl speed is linked to the object parrot and width is linked to the object Canary if you guys remember from the last lesson I showed us an illustration we had a class or a family which I called birds in the bird family we had four objects we had an owl hummingbird Canary and parrot and those are the objects that I am linking to my properties very good on the right I have an example of three methods it looks the same as a normal function it has a unique function name and it’s followed by a set of parentheses just like a property a method must be linked to an object in order to run or work just what I had mention right as you can see all my properties and all my methods are linked to a specific object so let’s take a look at how to set up our code we are going to be heading over to VSS code or an IDE of your choosing very shortly now the code on the left here is is actually outputting the image that you see here on the right you should have a basic understanding of how modules work at the top we are importing this module Turtle I am then creating two objects okay so an object is just like a variable but the value of the object is a class so so T1 is an object turtle one the value of T1 is a class my class is Turtle it’s capitalized and it’s followed by a set of parentheses once I’ve created my objects I can then set the properties of each object so T1 is going to have the color of orange T2 has the color purple I am then linking two methods to each object I am giving them actions I’m giving them instructions of what to do next when I run this code we can see the output on the right but let me break that down even further here we have step by step of what’s happening and this is how I like to use turtle and create object we’re importing everything at at the top of our code once we have our Imports I can then create any objects I will use I could create one I could create five as well we are then assigning the color property to each of our objects and then I am linking our two methods to the object in order to get them to move the final function you see here on the screen is done this is a special function that comes with Turtle it allows the drawing to stay on the screen once it is completed great I’ve shown you some basic Turtle code I’m actually going to show you some of the functions the methods and the variables or the properties we will use in this lesson let’s check them out all righty so on the left I have my column of some properties and methods you will use and what they do along the way okay please note that all of these must be linked to an object because they are properties and methods we have the color property and this assigns a color to the object now it’s important to note the color inside is a string the second method is width and this is the width of the line you’re drawing automatically the width of the line is one if you would like to increase that you can put an integer inside which will change your width the turtle is just the name for the object and we can actually change the shape of all the objects you see on the screen you can change it to Circle Arrow Square Turtle as well as a triangle you can use the speed property which speeds up the drawing itself the maximum speed you can do is 10 in order to give your turtle motion or action we have the forward method you can use the word forward or you can use FD inside we put the number of pixels you want to move in that direction and finally on this page we have our directions we have left and right both of these methods take a degree how many degrees do you want to turn left 90° would make you a square if you did that four times very good take a moment if you need to pause the video here take a screenshot I’m going to move on to a few more properties and methods here are a few more so we have a method called up now if you imagine that your object your turtle is just like this pen I have on my screen I’m drawing right now if I want to move to a different location I need to up I need to pick my pen up and move it to a different location I can use the up method to do that I can use go to to justify which coordinates I would like my object to move to now this does take an X and Y position once we’ve moved to a new location I can then put my pen back down and start drawing again great the steps in order to move your object up go to a new position put it back down you can then draw again in one of the challenges I’m going to ask that you make a circle now if you’re up for a good challenge you can try drawing a circle with just your two methods forward and left if you want to make it easier Turtle has a circle method inside you put the radius how big do you want the circle if I said T1 Circle T1 is going to draw me a circle with the radius of 10 n good the final few methods there’s so many that’s why I encourage you to go back through these slides read the documentation online and see what you can do with your objects if you want to fill in your drawing which I’m going to show you shortly but you want to have for example your Square to be a solid color once you’re done drawing you need to use the begin fill method we use this before you start drawing and once you finish drawing you can use the end fill method these two working together will fill in your object with a solid color the very last line of code you should be using is done this allows your drawing to stay on the screen once it’s completed very nice that’s a lot of methods I’ve gone through 12 actually all right so using turtle with the basics of python in lesson one at the end of that lesson I said that you should already have a good understanding of how to make functions Loops conditional statements all of that basic knowledge you can use right here in Turtle to hone in your skills while now we are working with objects so take a look at my code right on the left we see normally I am importing Turtle I then create one object T1 remember an object has the value of a class I assign my object to properties color and width great I am now ready to start doing something with my orange object I want to fill in the shape I draw then I’m using a for Loop you should know how to use a for Loop I’m saying for I in range five that means my Loop is going to repeat five times every time two things are happening my object is moving forward 150 pixels before it turns left 144° once it’s completed it’s going to fill in my illustration which produces an output like this an orange star you can actually see my object here on the left of the screen that is what your turtle will look like if you do not give it a starting shape very good let’s take a look at that example a bit more right so just by using that Loop that 4 I in range five that’s producing the orange star you see on the screen if you did not use a loop it would be very repetitive because you would have to write this four more times I saving you eight lines of Code by using a for Loop right so experiment use the the programming knowledge you already have and tie that together with working with objects in Turtle great taking a look at a more complex example don’t worry I will break this down for you even a bit more at the top we start with importing Turtle okay I’m going to work left to right you always start with your Imports at the top that shouldn’t be anything new then I have defined two functions of my own I made the star function and the circle function for this purpose I am just going to work with the star function my star function takes four parameters it takes an object I’m going to give it a width I’m going to give it a size and a color then just like outside of a function t1. color right I’m taking my object T and I’m assigning it a property what is the color going to be well the color is going to be whatever I give to my parameters the same thing applies to width I’m giving my object a width that is going to be done when I create or call my function this code is the same exact code as you saw in the previous slide if I go back right here you see all of this except in this example I Define the object as T1 specifically in the following example I have defined one object T but T could be anything over in our code then right you can see that I have made T So T equals Turtle I’m going to give this object to my function our program runs we begin with asking for an input this is where I can enter a shape so if my input is equal to Star I’m going to collect a width I’m going to collect a color and I’m going to collect the size this will be my ARG Arguments for my star function I’ll break it down a little bit more but I encourage you to pause the video here and really just read through the code you should understand 80 to 90% of this all right so you can see I’ve colorcoded that those three green variables width call and size they are being used used as the arguments to my star function those arguments are being passed up to the star function and being used as the values within my function the same thing is happening with circle if I enter circle in my input then I am asked for a radius and a color which I am using as the arguments to my circle function they’re passed and they’re used to create a circle pause here give it a good look right I’m about to give you guys your first challenges in vs code here we are I’ve put together five challenges for you guys number one I want you to draw a hollow Pentagon each side of a a pentagon has a different color number two draw four solid squares right so these squares should be filled in with a solid color all different colors but all in different locations how do we change a location you might need to go back a few slides number three I want you to create three functions each function will draw something different when it’s called this is very similar to the previous example in the last slide go back and take a look but come up with your own shapes don’t use a star make something else number four I want you to draw 10 circles each at a random location with a random radius so this might be new to some of you but if you hear the word random in Python you should be thinking about the random module now this one’s a good challenge because it’s going to require you to import the random module and use the randant function if you don’t know how to do this do a little Googling and finally your last challenge I would like you to create three different objects these objects will draw three triangles in a column each triangle is a different color okay now as help you can use the slides to help you please do I encourage you to do that but at this point in your programming Journey you should also be comfortable doing your own research or learning how you can check out the turtle Graphics module documentation just Google that it’s going to be one of the first links you can also use these slides to help you now I’m going to head over into vs code and we are going to code this out I encourage you to try these challenges on your own I’ll see you guys over in vs [Music] code [Music] great welcome guys to VSS code in this lesson we’ve introduced working with objects in python as we’re now in vs code we are going to put some of that to use and get on coding now before I start coding reminder there are so many way ways to solve one specific problem any way you’re able to do it well done amazing you should not have to do it the way I do it if you do it like I do great if you find a different way that’s you being creative that’s fine too all righty you had a chance to read through the tasks of this challenge before watching this video I highly encourage you to try these challenges on your own go back through the slides of this lesson read the documentation for turtle do your best to overcome these challenges if you get stuck watch the video or if you want a guide to follow along with watch the video too I’m going to jump in with our first challenge in the first exercise I asked you to create a hexagon with six sides each side with a different color there are many ways to do this I’m going to try and do this the more efficient way there is a longer way there are other ways choose your path first thing we want to do is we want to import remember all the Imports are at the top of our code so from Turtle I would like to import everything that’s what the star means from the turtle module import absolutely everything I am then going to make an object so for the purpose of this let’s pretend you’re drawing on a piece of paper so I’ll say pencil what is pencil well an object is always equal to a class my class is Turtle great I’ve made an object now I know that each side of this hexagon needs to be different so you could do this a few ways I’m going to make a list list how many sides are in a hexagon well there’s six if you didn’t know so I’m just going to make some colors here uh I’ll say red uh purple orange what other colors do we have I think lime Green’s a color in Turtle I’m going to put that in there uh I’ll say light blue I believe that’s a color what am I at 1 two 34 uh okay cool let’s just say green dark green and then yellow all right we have 1 two three four five oh is that seven I have seven colors let’s take away green okay sweet six colors now I want to repeat a task remembering the basics of python how can we repeat something a loop I can say 4 I in range I want to repeat this well six times right that is how many sides are on a hexagon so six times I’m going to take my object my pencil and I want to change the color of my pencil I want it to be one of the colors in my list specifically I want it to start with red then it’ll go to purple and work its way through the list so to do this I’m going to take my list colors and I need to give it an index a position I’m going to say I so I is the first index the first time this Loop runs right the next time this Loop runs I will be the second element change my color uh let’s just take this let’s say the width of our pencil let’s just put that at five my pencil can now move forward how far are let’s say 100 pixels and then our pencil can move right 90° remember the last line of code I’m going to put here is done this will ensure that the drawing stays on the screen at the end great let’s run our code I’m going to head up there run the code terminal appears I should see a window there we go the window is quite big right so I’m seeing an issue right that’s drawing a square I don’t want that who caught on why is it drawing a square let’s go back to my code because I put 90 de that’s for a square I should be putting 60° 60 * 6 that is equal to 360 that’s the total number of degrees in a circle let’s try that again boom there we go go there’s our hexagon you can see that my turtle Graphics screen in vs code is quite large that’s okay you’re able to see what I’m drawing yours is going to be large too so we have a hexagon different color sides with a width of five one object pretty cool all righty I’m going to trash my terminal I’m going to turn all of this off except my import because I want to continue to used that for my other challenges in our next challenge we wanted to draw four solid colored squares each with different colors each in a different location this is weird this is really weird so in order to get this going we need to think about the word random all right now if you haven’t used it before which you should have with the basics of python playing with modules there is a module in pyth python called random I want that uh I’m going to say from random import let’s say random because that’s all I want I want the randant function I already have Turtle so I can create my object let’s say pencil again pencil is my object what do I want to do well I’m going to have four squares and they’re all going to have to generate a different color a color can be RGB colors so red green blue with the maximum of 255 let’s create a random color for each one red green in blue so I can say for I in range how many squares will we have four I’m going to have red green not Global green and blue let’s start with red R equals random I can say 0 to 255 that way it’s going to choose a random number between 0 to 255 each of those is going to do that because this is going to generate us a color now that I have a color I can just insert in here and I can take my red I’m going to divide that by two 255 we can take our green and our blue that’s going to get us a nice unique color that I can use here in Turtle remember there are other ways to do this not just one now that I have a color we want to Define and create some location our locations are always going to be X and Y so a random location the left of my screen is going to be -200 the right can be positive 200 you should already have a good idea of how coordinates work and this should not be a new topic right but that’s generally going to keep it on my screen I can go left 200 or right 200 with 0 0 being the exact middle every time I draw a square remember how do we move the pencil around well I need to take my pencil and I need to lift it up once the pencil’s up I can take my pencil and I can go to a new position where do we want to go I want to go to my random X and Y that we just created here once I’ve gone to that new position I want to put my pencil back down on the paper great pencil’s in a new position we are ready to draw the square so to draw our Square pencil let’s change the color to the color that we just made our color argument right here is this one that’s a random color we can then begin fill remember if we want to have a solid shape we use begin fill at the start and we will use end fill at the end great now that I’m in my Loop we can go forward 100 this time I can go write RT right you can also spell right and I’m going to say 90 much better once we’ve drawn that shape I would like to end my fill the last thing we’re going to do is say done right let’s run that code we have one object this object oh there we go okay so I have been given an error it’s really coming from line 35 and all of this is being triggered so what I’m going to do let’s color one equals color equals cool let me give that Oro see what I’m working with here there we go boom one square okay two three all decent locations it looks pretty cool I have a lightish blue one a mint green raspberry color and a gray Square that’s the job that’s what we were trying to do random squares in a different location with different colors if you really wanted to take this challenge up a notch you could have done random sizes for the squares too think about that how could you implement that in your code try and find out all right I’m going to close this trash my terminal and I’m going to turn off this code here all of it okay let’s go down here we are now going to move on to the next challenge of working with objects you should start to begin to feel comfortable with what an object is how do we use it remember pencil is the object object the value of an object is a class and the class has all these special functions and properties that come with it pretty cool number three we wanted to create three functions that each will draw a different shape when they’re called functions you should know how to make a function in Python that was the fundamentals of python if not this will be a quick refresh now remember I already have uh I’m just going to comment it out from Turtle import Star I already have that at the top of my code so I’m going to skip that part I’m going to come right back down and we can create our object pencil now I’m going to make some functions so what shapes do we want to draw why don’t I draw a square a circle and a pentagon those are all good shapes so I’ll make a function called square square is going to take really three parameters it’s going to take an object that can be my turtle my pencil it’s going to take a size of the square and it’s going to take a color now that I’m in my function I can do exactly what I have been doing so I’m going to take my object and I’m going to set the color of this object so my object is t t color the color that I want it to be is whatever my color parameter is let me change this I’m going to say P for pencil that it’s going to make it easier to understand so I now have the color that this square is going to be and I’m going to call begin fill on my object as well I can now go through the normal steps for I in range of four remember I’m drawing a square and I want my pencil to go forward how far 100 well you could say that but we have our parameter size whatever I enter as an argument for my function that is going to be the size of my square if I enter 50 cool my square is going to have a size of 50 all right then I’m going to say WR I’m going to start to use these other words now as I don’t want to get too shorthand for you that’s going to get confusing so object pencil is going forward the size amount the object is going to go right for a square 90° great um at the end what’s the last thing we need to do here well I began the fill I now want to end my fill cool um just to kind of show you guys what’s happening I’ll put that in here uh I’m going to run the code real quick I’m not done by any means but let’s just watch what happens I call my function I give it my object pencil I give it a size and I give give it a color let’s run it on my screen we are going to see that red square appear right there and it’s filled now you noticed it cut out real quick cuz we should have done as the last function here let me run it again cool great I know it’s working that was a quick test let’s close that trashing our terminal I’m going to turn off that function I called I’m going to make my circle function so circle is also going to take an object it’ll take a not even a size it’s not going to take that it’ll take a radius and it’ll take our color so I can say color is our color right very good keeping that the same convention I’m going to call the turtle Circle function and I will give it my radius now even before that that’s just going to draw a plain Circle so let’s say begin fill here and we can end with our Nill cool that is our Circle while I’m here I’m just going to make our Pentagon as well Pentagon objects size and the color the same things as the other two functions I can start with my color I’m going to go to my begin fill then because it’s a pentagon I’m going to make a for Loop what’s the range five it’s G to be five inside that there we go okay so every time my object is going to go forward 100 my object can go left you can say right right cuz up here I said right left right up to you um let’s say left for that is actually going to be 72 great a part of the challenge I want a way that I can call these functions more uniquely than this so I’m going to make like a loop and my Loop I’m going to be able to enter as an input what shape I want to draw pretty cool so let’s say start is going to be an input and in here I can say a few things I can say say Square I can say uh Circle or I can say Pentagon and I’m going to make sure that they’re all lowercase linking do lower while my input is not equal to oh I don’t know let’s say stop while input is not equal to stop if my input is equal to square so if I’ve entered Square I want to collect some information here I want to collect a size and I want to collect a color so I’m going to say size is equal to an integer enter a size color because colors in Turtle are a string I can just say enter a color as a string there then we will call our function I’m going to give it an object what is my object pencil what is my size well I’m going to use my input size and my color can be color nice one done I’m going to add an also if Circle in there um if circle is called I don’t need a size I need a radius so I can say radius is our input right uh I will just say enter radius I’m going to copy color cuz that’s not really going to change we need a color for Circle then we will call our Circle function let’s give it our object let’s give it our radius and let’s give it our color nice one okay that brings us to our last shape so let’s make one more elith and say also if our Pentagon was called what I can do is cuz I’m going to use a size and color I’m going to take what we said here from our Square the only difference is I’m going to call the Pentagon function give it a size give it a color too no good conditions completed without an else so I haven’t put any warnings in here I don’t have any exceptions so let’s just say else anything else I’m just going to say uh error shape not found good do you guys remember what’s the last thing we need at the end of a loop well a loop needs a way to break to escape a while loop can go on forever we don’t want that that’s a problem so you need to be thinking about ways to break that Loop the one way to break it is I can just take my input copy that and I’m going to put that at the end of my Loop that way every time my Loop runs it’s going to ask this question again and it will check to see my input at the start of my Loop nice we’ve done a lot go back read through the code most of it should be familiar if there’s something that’s not familiar with you really break that down if you need to watch that part of this video again do so run your code experiment with it and let’s see what happens I’m going to run this code I’m going to make my terminal a bit smaller I don’t really need that cool so as you can see here I need to put this over here Turtle still on the screen at the bottom of here I’m seeing Square Circle Pentagon so I’m actually GNA enter and I’m gonna say Circle enter radius let’s say 25 color blue enter I’m going to go back here there we go I have a blue circle on my screen nice one okay let’s go back I’m going to do Pentagon Pentagon enter size 150 color orange going back oh there we go ah all right so I did not begin and N Fill with the Pentagon it’s not doing anything with that H let me fix that but let’s do the square first Square enter 100 uh purple oh what did I do wrong shape not found Square okay H spelled Square wrong so I fix that before I move on let’s just go to Pentagon let’s just say p. Nill trash my terminal reopen our code to get it working there we go uh let’s go into our code let’s do Pentagon this time Pentagon 200 purple there we go great now it’s filled right so I can now type whatever I want and whatever I type is going to be drawn onto our screen oh matched perfectly that’s cool I’m going to type stop that is going to break my Loop right so then our code is done now very very nice I’m going to turn off all this new code right so what I’m doing here is I’m touching on all the topics that were introduced in the fundamentals of python now you might not be a master at these topics but by going through them now you’re learning two things one how we work with objects and two how we can use our fundamentals of python to build while working with objects great guys I’m going to head over to the next video we are not done with these challenges I just want to give you guys a chance to review what we’ve learned in the next next video I’ll be back here in vs code and we will finish up those final two object challenges I’ll see you guys in the next [Music] video great here we are in the last video for working with objects where I’m going to finish up the final two challenges that I’ve given you guys in the next challenge we need to draw 10 different circles all at a random position and a random size I love random all right so I have Turtle let’s just go up here from random anytime you hear that word random think the random module I’m going to import everything great let’s make our pencil so our pencil that is our object the value is our class what I’m going to do here is I only want it to go when um I enter something into input that way it’s just not going to it’s going to wait for me to start so let’s say like start you don’t have to do this part you can just do a for Loop so I’ll start with that and then I’ll go back to what I wanted to do how many times will we repeat this 10 the challenge is to draw 10 circles every Circle needs something it needs a radius if you want to do a random color that would be a really good challenge I’m not going to put that in here though so so radius is random literally pick anything I could say five to One n to 100 let’s say 5 to 100 I have a random radius I need a random X we will keep with the statistics of2 200 and 200 uh and I need a y like so okay we have everything we need to start drawing what I’m going to do is I am going going to take my objects so pencil pen up or up right either of those two work I’m going to keep with up I want to pick my pencil up I want my pencil to go to a new position using the X and Y that I’ve created here right this is a random value this random value is being used for my X position our pencil can then go back down to begin drawing all we need to do to draw a circle quite handy quite useful we saw this in the previous exercise take our pencil call the circle method and I am just going to call Radius radius that is the input that we collected up top here it’s going to be a random radius awesome let’s run it that’s all we needed to do to get this working when Turtle loads it is slowly going to go through and you can see they’re not being filled in I didn’t ask you to fill them in I did ask you to put them as a random size all in random positions and by saying -200 and positive 200 it’s keeping them all in that general area nice really cool guys I’m going to say done so I used one object from a class and I used that object to draw 10 different things or do 10 different things that’s great okay uh if you wanted to right I could say like start and I could say input and we could say while start is not equal to off then all of this is going to go and we could take our input put that at the end the only difference this is going to do right is it’s going to do that I need to enter something anything right so I could say apple it’s going to go back it’s going to start drawing by using that while loop with input it’s just waiting for the user to tell python to do something before starting additional things from the fundamentals we can use with objects all right that brings us to our last challenge our last challenge I love this one we want to create four different objects each object is going to draw a triangle but these four triangles need to be in a column each triangle is a different color ooh what can we do here for this one so first thing I want to do is I want to create four different objects so far we’ve just been working with one but I can create multiple objects from the same class and that’s what I want to do here so instead of saying pencil I’m going to go shorter I’m going to say T1 I’m working with Turtle so turtle one Turtle class Turtle 2 Turtle I’ll fix that and uh T4 equals Turtle nice so this is going to parallel going into our next lesson I have four different objects remember each object has its own data and can do its own thing what I’m going to do in order to do this now you could have made one object right um the thing is they won’t all go at the same time you will need to wait for one object to draw and then go to a new position I know I’m going to draw a triangle so let’s create a function for triangle my triangle is going to take one of those objects one of those Turtles as an argument it will also take a color right so what I can do here is I’m going to take my object that I’m going to call color give it a color right I can say begin fill because these triangles are going to be a solid color and then we will do our for Loop triangle has three sides our range is three every time our turtle is going to go forward let’s say 100 and let’s say uh left ooh what is our left it’s not 90 be 120 three sides in a triangle 360 / 3 is 120 T and fill very nice our function is done which is great I want a way now that I can iterate through and I can draw these triangles at the same time you could be thinking of different things and you may have already solved this problem what I like to do is I love loops and I love to iterate through things so I’m actually going to make a list called T right and I’m going to put all my objects in this list and for the purpose of this let’s call this Turtles can I do that Turtle that’s better let’s say for every turtle in my list Turtle I want to do something with the turtle I’m on SO the current Turtle That’s T I want T I want that Turtle to go up I want that Turtle to go to a new position now I want them to be in a column so the X X that’s not going to change but the Y is going to change I need a way to change my y hm how can I do that well we could create a counter variable right let’s say y initially is 100 that means the first turtle is going to go to x0 Y 100 100 my turtle can go back down on the paper and then it would do something right but now the next Turtle needs to go to a different position let’s change the value of that y variable and let’s say y – 100 so every object T1 T2 T3 T4 is going to go to to a slightly different y position are you with me pause it read through see what’s happening now the final things we need to do I really just need to call my triangle function and I’m going to say T1 let’s say blue as the first color I’m going to say triangle let’s say T2 let’s say red let’s say triangle let’s say t three give me a color let’s do purple again uh and then triangle T4 excuse me and we will say uh blue did I do blue I’ve already done blue green there we go who remembers the very last line of code done wow you’ve done it let’s run it let’s see what’s happening now boom you see four different objects on the screen too that’s amazing they’re all in a perfect column nicely done if you got any of these challenges on your own you’re off to a good start and you’re going to do well in this course if you found some of them quite challenging that’s okay just know that this course might be a bit harder than you initially expected try to spend some time reviewing the fundamentals as you go through this course such as functions loops and conditions I’ll see you guys over in the next lesson in the next lesson we are going to start to Define your very own classes and objects I’ll see you guys there [Music] hi and welcome back to lesson three of the zero to knowing course in the last lesson I introduced the topic of objects and how to work with objects in Python in this lesson we are finally ready to Define our own classes and objects if you remember from lesson one I said to think of a class as a blueprint this still applies now a especially going forward a class is a blueprint let’s jump in to this lesson if I were to break it down so as I mentioned a class is like a blueprint or it’s a template for creating many objects so on the left I have a sketch or a picture of a house and this sketch is our class it contains a general overview of this type of object or it contains the general information you need in order to make an object on the right we have a completed object and this is what we created from the class using a description an object of a class now I want you to kind of remember from the last lesson do you remember this T1 equals Turtle I want you to say that 10 times if you need to get really annoyed by it T1 equals Turtle T1 equals Turtle T1 is an object the value of an object object is a class turtle is a class so here I have my instance or my object the value of an instance is my class now remember a class is always capitalized it is one of the very few things in Python you capitalize a class is followed by a set of parentheses capitalized parentheses let’s take a look at a few more objects so here we go you remember from the first lesson I introduced a class of birds well let’s take a look at a few more examples as you can see below these are all objects or they’re all animals right at the end of the day it it doesn’t matter in English all of these are animals that is our class they all have additional Properties or actions of their own right so the owl is the outcast object it is an object it’s an animal it has its own name has its own abilities has its own properties okay next up we have three land animals let’s call them and they share two of the same properties each of these objects have four legs and a tail but they each have their own properties such as the type of animal and location as well how many objects do we have four how many classes do we have one our class is animals our objects are owls raccoon lion and giraffe let’s take a look at another so here they are all phones sharing some of the same properties they all have some of the same properties and actions of their own but then they all have their own unique as well creating a class before we create any objects like a raccoon a lion we need to create a family we need to create a class in this class this is where we Define all the unique properties and all the unique methods that our objects will have but first we need to look at an important function this function is called a Constructor function but really it’s called our Constructor method right what is a method a method is a function in a class and this special method is automatically ran when an object is created it creates an instance it creates an object of a specific class this word Constructor what does it look like Constructor looks like construction what is construction build we use the Constructor method to build something to to build our class this method is called in it okay now you can already see and it looks weird you’ve never seen this before it has two underscores in the beginning and after in it that’s very important okay we must use this as our Constructor this is always the first method in our class in just means to initialize initialize just means to start right so every time we start our class or we create an object we automatically use the init method creating our class we’re finally here right we’re starting to see some actual code come together I’m going to break this down for us if you need to rewatch any of this please do because this is a very important topic object orientated programming so on the left we have all of our code and you can see that I’m starting at the top with my class to define a class we use the class keyword and then we give it a unique name just like a function but the first letter is capitalized then all the code inside is just like code outside you would make a function the same way but this is a method why is it a method because it’s a function in a class our first method is our Constructor in it in it is taking one two parameters just like a function takes parameters these parameters are the value to my properties at the end of our class I make an object car the value of an object is a class my class in this example right remember T1 equals Turtle well my T1 is car my turtle is my class I am giving my class two arguments because in it has two parameters that’s very important I can then use my drive method and I can link it to my car object if you’re a little confused don’t worry I’m going to break this down even more but before I do you see a new word on the screen what’s that new word boom we see the word self this is very important we use the word self in a class now self it’s basically a key okay and it unlocks the class so we can use all

    the properties and the methods anywhere we want throughout the class self is a key you must have it as the first parameter in any method okay but it’s important to note that you never use the word self outside of a class all right let’s do some color coordination now okay here we are pause the video okay if you need to just use the color coordination to help you all right so at the top of the screen the first thing I do is we Define we create a basic class I named it my class okay up next the first method in our class is our Constructor method this is where you will Define all the variables all the properties you will use throughout your class okay each parameter is the value to one of the properties next up we Define a method named drive this method this function uses the values from our two properties and gets the sum right so I have a variable X and the value of x are our two properties added together I can use my properties because I am using the word self remember self unlocks our variables and functions to use them throughout the class finally at the end of our code I create an object named car and then I give my two arguments to my class 50 and 60 50 is parameter 1 60 is parameter 2 I then link my drive method to my object and this is how we call a method because a method must be linked to an object right here we go so when I call my drive method the output in our terminal it would say the speed is 110 kilm per hour okay as you can see I added on a little extra there right but because my two arguments are being passed up here they are the value to my parameters I can then use my properties which which I’m adding together here and then I’m converting that integer to a string which is being printed out inside our terminal pretty cool huh everything’s starting to link together this is good all right let’s take a look at another class okay so I want you guys to pause the video read through the class okay I have two questions on the screen at the bottom try to answer those before I do all right I have a class called app you can see that’s created at the top of my screen here is here’s app the first method is our Constructor I am creating three parameters users storage and username for each parameter I am creating a property and remembering the value of my property is my parameter that’s all in it is doing it is a place to keep create and store our variables we will use in the class I then have two methods my first method is login this is just a normal condition if username if my property self. username is equal to owner and self. users is greater than one then I I can print off welcome username your storage is the amount of storage right so right here what is it going to print off think about that then I have a method called increase capacity increase capacity is its own method in my class it takes one of its own parameters I can use my property self. storage and I can add that parameter to it before I return self. storage so were you able to answer my questions what is the name of my class and my objects well let’s take a look okay our class is app our objects we have two product one product two remember the value of an object is a class go find that now my next question for you guys at the bottom of the screen what are the value of my properties pause it answer it there we go the value of my properties are my parameters users storage and username self. storage is equal to storage next question bottom of the screen where are the arguments that will be given to my class right there these are the arguments remember in order right it’s very structured users storage username users storage username right in that order these are being given to my class wonderful okay so here’s a breakdown I took that same class right and all we’re doing is we’re going top to bottom because that’s how we design our blueprint remember our class is like a blueprint we design the blueprint before we create an object before we create the finished product we create a class called app our method login has a condition which checks the properties against a set value that set value is owner and the integer of one we create a method called increase capacity and all this does is increases the current value of our property self. storage then finally once we’ve made our blueprint our class we can create an object called Product one or product two and we can call the methods we want okay so here’s even a bit more right I’ve kept a few of the hints from the last slide but I’ve added a bit more in the new ones I’ve added we set up our Constructor with the properties we will use throughout this class we have a method that increases the value right and then we have our product to what is this going to Output well let’s take a look if you haven’t guessed it yet which your mine should be ticking your wheels should be spinning what will this be outputting well let’s start with our first object our first object was product one right and product one is taking the arguments 35 256 an owner when I call the login method method those are the first two lines it’s going to say welcome owner owner and it’s going to say your storage is 256 then I also called the increase capacity method and I gave it the argument of 50 which is being used as my parameter it’s going to take my original storage which was 256 and it’s going to add a number to it that updates our storage to 306 if I take my second object and I call the login method it’s going to show login denied why well my username is Josh if username is equal to owner do this otherwise login denied so my name was not owner login was denied great a lot of things happening right so go back through these read over these see what’s really happening once we get to vs code it is going to start easy but I’m going to give you a few challenges and it’s going to get harder rather quickly it’s meant to challenge you and it’s meant to help build you that strong object orientated foundation in Python before vs code let’s take a quick flashback to what you were learning before objects here we are a class is a big group of methods and each method contains various elements that you’ve already learned in Python like conditions Loops lists diction Aries and more right so everything you see on my screen you should feel fairly confident with if you don’t I think you should stop now you can go back to Turtle because going back to Turtle you will reinforce your understanding of objects but you can also reinforce and practice your understanding of the basic Python Programming Concepts like conditions loops and functions a quick recap a condition is really just if something is true do this otherwise do something else that’s what a condition is if this is true print hello also if name is Josh Print it’s me Josh anything else print goodbye that’s how a condition is set up a while loop literally translates to while something is true keep repeating if it’s not true stop right so in my Loop while count while input is not equal to zero keep repeating every time I repeat I’m going to ask for a new input and I’m going to check if my input is zero it’s going to keep repeating right our for Loop if I literally translated a for Loop which I do do that for every item inside something I want to do something with that current item right so I have a list ages one two 3 four five six if I take my Loop for every age in my list ages if that current age is less than or equal to 17 I’m going to remove it all right so my Loop is going to go 33 and it’s going to take 33 if 33 is less than 17 nope my Loop is going to keep going and it’s going to check every number oh it gets to 15 if 15 is less than 17 that’s true it’s going to do something right you should feel very comfortable with these all right let’s jump in and check out some challenges do not go back okay this is our first challenge in VSS code where we are building classes this is a point where we should try to avoid going back from and I want you guys to try to recreate the code from the previous slides and use it as an example to build your own first class in vs code now remember that this class has one base class and I called it app inside app we had three methods in it login and increase capacity login checked if the username was equal to owner if it was it printed off welcome as well as the value of your storage increased capacity allows us to add a number to the current storage finally create two objects and both of these objects call both methods head over to vs code give this challenge a try and I will see you guys there for the next few challenges I’ll see you in vs code [Music] all right great guys here we are in vs code in this lesson we have introduced the topic of defin your own classes and your own objects and that’s what we’re about to do here in VSS code is to strengthen those foundations and build on what we have been learning in this first challenge I asked you not to go back and I wanted you to try to create the app class from the lesson here in VSS code in this video that’s exactly what we’re going to do so coming up top here we can use the class keyword to define a new class I’m going to call this class app now remember our class is capitalized everything after is inside the class what’s the first method we need to make who remembers what’s that special Constructor method well it’s in it remember in it means initialize or start and the first parameter inside any method is the word self self acts as a key and it unlocks everything for us to use around our class what were the other three parameters we had users we had storage if I can spell correctly and then we had username for each of these I am going to make a property so self. users equals users self. storage equals storage and self. username equals username like so very good our init is defined the first official method we had was login so I can make login remember give it the key so we can unlock it later this condition check to see if the username was owner and to make sure we had at least one user in the system so I can make a condition and I will say if username but if self. username right because a property it’s just like a variable it’s the same thing but because we’re inside our class in order to pass this variable around we need to use the word self so our variable is called self. username if self username is equal to owner and our self. users is greater than or equal to one we would like to print off a few things the first thing we can print off is is welcome then we want to print off the username so I can say welcome username then I would also like to print off how much storage they have available your storage is let’s just say and we can say self. storage like so very nice a condition doesn’t need to have an else but most of the time I like to put one what would you like to happen otherwise and we can say you are not a user nice that method’s done now remember a method is not the same as a function if I call a function like this and I run my code I’m going to get an error because this function is a method it’s a function in a class it tells me login is not defined it can’t find login anywhere I want you to think about why as I finish out this class great our next method was to increase our storage capacity so capacity there we go first word is self but then we’re going to give it an additional number that I can do stuff with I want to increase my existing capacity so I’ll say Self Storage plus equals that new number great I can then just print something like uh updated storage and we can just now do self. storage that’s our new number very nice before I create that bonus method I’m going to just create our objects so let’s say product one is equal to app um let’s say their users they have 35 users 256 GB of storage and their name can be just like the video let’s say owner we can then call our methods so the reason Logan didn’t work before is because a method must be linked to an object in order to work work so product One login and I’m going to say product two increase capacity let’s say uh 5044 that should give me an even 300 right um I’ll make one more now I’m going to print off an empty space first then we can do product two is equal to app as well uh product two can have 12 users uh they can have 128 GB of storage and their name can be my name Josh for each of these I’m going to say product two do login what’s going to happen there and I can say Product 2 dot I don’t want to upgrade it let’s just leave it for that let’s run the code great we’re going to see a few things happen here so awesome the first part so one two three that’s really being printed right here right welcome owner my name is owner so if username owner and users is greater than one it’s printing off these two then updated storage remember I’m increasing my capacity it so I’ve changed my storage from 256 to 300 very nice in our last one it just tells me I am not a user because I do not meet these two conditions nice one let’s jump into that bonus real quick I asked you to have a bonus right that would check your upgrade so I’m going to call this check upgrade and check upgrade does not take any parameters it does take self right if our users so let’s say if users is greater than or equal to our storage then I need to upgrade my storage so I’ll say upgrade amount so I can collect an input of how much do I want to upgrade it at I’m running out of space for the amount of users I have so let’s just say here upgrade amount like so all I want to do then is I can say self. storage plus equals upgrade amount like so cool very nice that will upgrade it and then um what I want to do then is else so if I do not need to upgrade my storage if I still have enough space I want to print how much storage do I have remaining how can you solve that how much storage I have remaining well let’s print off and let’s I’m going to say something like you still have then let’s do here I need to do a math problem right so I need to do self. storage minus my users but I want to make sure that this is a string so I’m going to convert that to a string then just close off your string and say I don’t know spaces open like so nice one I’m going to come down here for product two and let’s say product 2. check check upgrade I want to see if it’s time to upgrade run our code nice so it says you still have 116 spaces open why is that well 128 minus 12 is 116 that’s exactly what we did here 128 minus 12 incredible guys I hope you have followed along this far let’s head over into the next video and start with challenge two I’ll see you guys [Music] there here we are in challenge 2 now I’m not going to read all this as I’m hoping you guys already have and you’ve broken it down to what we need to do but I am going to read the overall description of what we are going to be building out in this class the code we make it’s going to represent an online course management system we are doing an online course this will help us keep track of online courses students and their grades and it allows us to do things like add new students see the course details and it’s going to allow us to calculate the average grades from our students this is a lot okay so I want you guys to try to work through this one by one don’t do everything at once do small tasks to work into this big problem what’s the first thing we need to do create a class what’s the first method make your Constructor method right step by step all right heading into task two I’m going to start out with us coding this I will build a class called let’s call it online course that’s what it is we will build our Constructor method giving it our key of self what information do we need here here well initially all we need is I need a course like the name of a course and then I need like who is teaching it so an instructor so in this course it’ be me in the course name it would be Zer to knowing object orientated programming these two parameters I am going to create our property for remember every parameter we have we would like to to create a property for okay instructor close enough nice in the last one I’m not going to give my init this method but remember that init is a place we keep all the variables the properties we will use in this class so I can make a variable here too I’m going to say self. students now this is going to be a list that I can use throughout my program that’s all it is right now great your first method that we needed to make was a method to add students to so the first method we needed to make was a method to enroll students let’s just call it enroll students now it’s going to need who who do we want to enroll well that’s going to take a name right it’s going to take a student’s name and what I want to do is any student who is enrolled I want to add them to my list right remember the list we just made here self students append who do we want to append the student name very nice once we have enrolled a student I want to print off their information so to do this I’m going to use in Python you might know this you might not you might have seen this in other languages in Python it’s called an F string I’m going to use an F string here because I just want to keep everything nice and easy and keep it all together so I don’t have to use commas and pluses to add different types of data together this just makes it more convenient I want to print off the name of the student so Bobby has been enrolled in the what course self. course Bobby has been enrolled in the science course right the name of the course would be printed there nice that’s all we’re doing for enroll we add a student to the list and we just print off and say hey this student is now a part of this course all right right our next method is let’s say we want course details I want the information about a course so it’s not going to accept anything it’s literally just going to print off detailed information about our course so here we can print I’m going to use f strings for all of these so the course name and then our course we can just say self doour we are going to print off here and in this print we can just print off the instructor name let’s say instructor name and we can tap into our property self. instructor and then in the last one what I’m going to try to do is I want to print off all the enrolled students in the course now you could just print off the list honestly um I could just literally go here and just say self. students and that’s going to work there’s nothing wrong with that right um if you wanted to get a bit more creative I could do that and let’s let’s add in here and let’s say I’m going to put like a comma right because each name is going to be separated by a comma and then I want to connect I want to join right and we haven’t quite Ted touched on this yet right I’m going to use the join method what do I want to join together I want to join together my students like so all right so I’m given an error uh okay let’s do this let’s change the double quotes let’s put single quotes as our outside ones are already double quotes there we go okay so now it’s going to join together in one line now there are going to be new things that I drop in this course here and there that I didn’t talk about in the lesson but that’s okay because as you’re now in this part of your programming Journey you should understand that certain things you might need to Google or research or find somewhere else and if you’re able to do that that makes you a stronger developer I’ve made a method for course details well let’s call that done okay nice um I’m going to make a method for completion or just call it completed course so like who completed the course when I say who it’s going to need a name again right so if the name I’m checking for I want to see if it’s in my list because if it is I want to remove that student from my list they are not part of my course anymore so if that name is in my list I can use a condition with my in operator then I want to remove that student from my list very nice um I can just print off and you could say something like uh course completed if they completed the course let’s say name has completed the course that’s cool okay else uh let’s just print off and we kind of need to like warn the user and we basically need to say that the name you’re looking for is not even a part of the course is not enrolled in this course nice all right we’ve made three methods right we’re building on everything we’ve been learning that brings us to our last method guys let’s do one for uh average grade I’m it’s going to take self this needs to take multiple grades what could that be well that’s going to be a list I’ve actually given you a list too and you should know how to find the average of something as well right you don’t need to be amazing at math for programming honestly you don’t right the computer can do that for you but you should have some basic understanding of math and this could be just algebra in general so how we find the average of something so to find this average I’m going to create a variable called total and I just want to add together my list so I can use Python’s built-in sum function to do that and I’m just adding everything together now that I have the total we want to create an average and the average is going to be the total divided by the length of our list the total divided by the length of our list okay now that we have our average we can just go through you can print off anything you want to say the average grade is let’s just say that let’s just put here and I’m going to say average awesome uh in the beginning let’s do a few things here let’s make this more unique let’s say course input let’s say name and let’s say student right because this is how a real program would run unless we’re coming from like a database so let’s say input let’s say enter a course uh I’m going to make sure everything’s lowercase okay that’s just good practice uh let’s say enter uh teacher or instructor right instructor that’s what we want there lower and then the last one you can say enter a name because the last one is for our student so we can just say enter a name lower nice one okay we’ve been done with our class class these three inputs will be used as the arguments for our class so I can come down here um I can say create an object called course and this is equal to our class our class needs three well actually our class just needs two arguments it needs our course name which is course input and it will need our instructor which is name the grades I’ve already given you and this is going to be a list so 90 85 92 78 and 80 it’s our list of grades we can use this now we can go through and I want you guys to call all four methods that we’ve just made so take our object course I’m going to link that to average grade and I’m going to give that my list grades I’m going to take my object and I want to enroll a student who do I want to enroll well I can enroll this into here is going to be enrolled in my course I can take my object and I can get my course information the details right let’s just run this for now actually enter our course python instructor Josh name of a student Billy nice one the average grade is 85 that’s the average from the list cool Billy has been enrolled in the python course oh nice all right that’s going up top here uh course python instructor name Josh students Billy it’s printing off the basic course details nice uh I’m going to call the last method here I’m just going to use my name actually so I’m going to say course uh complete completed course uh I need need to give it a name so I’m actually going to say name hardcode this because I don’t have this in the system I’m going to say just Josh for completed course so we’ll say python uh Bob instructor Billy there we go so I’m using my name hardcoded and it says Josh is not enrolled in this course right because well I’m not enrolled in the course if name if Josh in list remove else R I’m not removed nicely done guys that was your first challenge without anything from the lesson that we tried to implement on our own very nicely done I will see you guys in the next video for our next [Music] challenge [Music] all right wonderful welcome back to our next challenge if you haven’t noticed this is actually the code from the previous challenge which in the text file for this one I included as a hint to bring in that code as we’re going to use it what we want to do in this task is we want to redo an extend parts of this class I want to be able to have multiple students and each student is going to have three grades in order for us to calculate them now we can go to the bottom of our class for now because until we continue I don’t want to add anything else you can see that I’ve saved my inputs and my object course from the last Challenge and from here is where I want to extend onward when my program runs after I’m asked for course input and my name I want to be asked for let’s say numb students I would like to see how many students are going to be enrolled in this class so enter number of students very nice I’m then going to create a loop and I’m just going to say for this uh for I no I don’t even need to say I for in range I’m not going to use the index for anything I just want a loop that’s going to repeat for however many students we collected through our input right there every time this Loop runs we’re doing two things we’re asking for a name so who is the next student we are adding to the class roster enter a student name uh for good practice let’s make sure that’s lowercase then we’re going to ask for grades but before I ask for them I want to create where will these grades be stored currently it’s going to go into a list now that I know that we can Loop through how many grades do you want I initially said three you can change this for this purpose I’m going to keep three so in range of three every time this Loops we are asking for a grade which is going to be an integer so in input we can say enter a grade like so then we can take our grade and we can append it add it to our list list of grades great so imagine the loop runs one time the First Time The Loop runs it’s collecting all this information as a matter of fact every time our Loop runs it’s collecting this information a name of the student and for that current student it is going to collect three grades and add those to a list that’s linked to that student nice okay where do I want to keep this information I have two items but for a list I can only add one element at a time and that’s a problem if I have 10 students each with a name and a set of grades I need to keep them together somehow in order to add them to our list to do this we will create a class to store this information I will say class student now this class is nothing except like a database it’s going to hold a name of my student and it’s going to hold a list of their grades for each of those I just need to create a property for where they are going to be held like so I have my one student why don’t I take the information I collected and create an object called student the value of my object is my class and I’m going to give my input student name as the name and my list of grades as the grades nice I can now use this student object and I can use it as an argument in the methods from our initial online course class I am just going to say here I’m going to call course that’s our initial object right so I’m back up to here and for course let’s enroll students who do I want to enroll I’m just going to say student right that’s my object right there uh I can call my course object and why don’t we say average grade I can say that and we’ll give it a student again then at the end let’s get uh our course details so all the info about the course great you can see in those two methods here at the bottom that I’ve passed in the student object which we created here as the argument nice before I run my code I’m going to need to go up and make some adjustments to the methods that we have built how do I use a method well let’s it’s a serious question a method must be linked to an object in order to work we know this from the lesson here is my method it’s linked to my object course how do I use a property well a properties the same way I need to have the property linked to an object which I need to do I have an object student student has two properties name in grades when I want to access these I need to link them to my object student so let’s go up to enroll students and I’m going to start right here so let’s change my argument to my object all right so I’m going to be giving it an object student that object student is what I’m going to now append to my list it’s the same thing as before when I print off who has been enrolled name it needs to find name who remember that name is a property in my student class so I’m going to say student object. name that’s going to unlock the name all right nice let’s come down here to course details right here it’s joining together every name in my list but we’ve changed our list from names to objects so I’m going to I’m going to refactor this I’m going to change this I’m going to say print enrolled students then let’s make a loop and let’s say for every student in my list self. students I want to print the current student their property name that’ll print every student we have enrolled good okay uh coming down completed course let’s go in here and do some things so our completed course we give it a name let’s Loop through our list and let’s say for every student in our list of objects students all right I’m going to do a few things here if my name so if the current Student’s name is equal to the name that we gave as a parameter then I want to remove that current student right so I give this method a name Josh for example for every student in my list if the current student in my list has the name Josh then remove that student from the list that’s what’s happening there I can then print off my name good and I don’t actually need this else anymore I’m just going to bring this print right there so it’s going to print as soon as the loop ends if no students in that list that prints nice all right then refactoring our last method our average grade we are going to do a few things here so all we really need to do is we need to access these grades remember that that’s a property found in our class right here um our average total same thing student. grades and then our average that’s it that’s done good so we’ve used what we built in the last challenge we brought it in here and this was really useful as it taught us a few things it taught us how we can use another class as like a database it taught us how we can access these properties from another class or outside of this class and it also showed us how you can refactor your code to either extend it add more functionality or just refactoring in general really nicely done let’s run this I’ll go through this briefly uh course we can continue with python Josh number of students two students let’s say Bobby has a grade of five five and a three cool so it has Bobby has been enrolled in the python course average grade asks me for another student let’s say cool asks me for another student let’s say Emily Emily has a grade of uh 551 there we go gave me her information and then at the end it printed off the enrolled students Bobby and Emily the one thing I don’t like is all these decimal numbers so in our average grade function our method let’s put in the python built round function and let’s just round it down to one decimal great nicely done I will see you in our next chat [Music] chenge Welcome to our next class challenge before I get started encoding I’m just going to go through and I’m going to read our description I’m assuming at this point you have already read The Challenge and gone through it and you’re ready to jump in and get started for this challenge we are going to be provided code that represents travel planning in a cost calculation system it allows you to input the country you want to travel to the month of travel the type of travel so is it Leisure or business the system provides information about the trip and calculates the total cost based on flight expenses and any additional costs you may have great you know me I love travel and I love making code around travel so I’m going to head over into our code here we are so let’s get started the first thing I want to do is I want to make my class so using our class keyword I can say travel and inside here our class travel must have our Constructor method in it what properties do we need well I need a country we are going to have a month and then we’re going to have like a type of trip right so what type of trip Leisure business right for these three let’s create a property for each of these okay so country we have month and month is actually going to be an integer right uh the type so let’s I can call it type this equal to type that’s fine there we go and the last one I’m going to make a variable here or I should say property for a price initially the price is zero but once we start adding flights and other details that’s going to change very nice our Constructor is all set set up I’m going to create a quick method for all the info relating to my trip so what info should we know for this well a few things I’m just going to check and determine when the user is going if they’re going on a holiday during the winter months I want to alert them and say hey they’re going on a trip to this country in the winter months so how could we do that well well if our month is greater than October equal to October and our month is let’s say less than or equal to March which is three that’s why I converted my property to an integer if that’s the case let’s do a few things so I’ll put an F string I’ll say you are going to Country in the winter this is a style trip so inside here you are going to self. Country and then inside here we can say self. type like so cool okay also if let’s say month is greater than March and our month is oh let’s say less than October cuz that’s where we’re at I can just copy my print statement I’m going to put it here and instead of winter let’s just say summer just in case there’s an issue I’ll say an else and I will say oh I don’t know I don’t know let’s say invalid input there we go invalid input that method is done it’s just providing us the information about our trip you should have gotten that one if you did did nicely done let’s form a new method and this method is going to be responsible for calculating the cost of our trip we do need something though so I’m going to give it a cost as well all right and this cost will be added on to our current price property right so if I give it 10 I’m going to add 10 to our price property and our costs all of them will be held in a list we want this method to repeat as long as cost is not zero as long as you are entering a number it should be repeating and it should be increasing our property self. price right so every cost we’re adding it on to that every cost I am going to also keep track of in my list so I can add it to my list and when the loop finishes we should be collecting a new input right to test against our expression again so I will say enter another cost like so cool right that’s all that one is doing currently all right very nice now before we can complete that method we should be doing a few things here when the loop breaks okay I am going to call another method which I’m going to get to later so I’m going to put a comment here and I’m going to say uh call let’s just say call next method for now right um and then I’m going to want to call O check method I’m going to make a method to like check in order to do that I will need to return two things let’s just say two things for now let’s call that method done okay I’ll come back to that I’m going to create a method called advice now based on how much money I have is going to recommend me the type of trip if I have less than 500 I should probably print off and do something like uh let’s just say low budget cool uh let’s say if the number that I give this okay if that’s over 500 and that is less than let’s say 1,500 then I’m going to print off here and we could say for this that’s a median budget trip right so take a flight to anywhere dot dot dot great and then anything else which means you’re over 1500 essentially uh let’s just say luxury trip nice um I have advice that’s going to give me my advice now my last method is interesting so I can’t exactly budget how much I need for the trip right because anytime you go on a trip you know the overall cost right flight accommodation but the one thing you don’t exactly know is how much you’re going to be spending per day on food you could go to one place and get coffee for € you could go somewhere else and get dinner for eight right and it changes depending on where you go my next method I want to basically kind of create a way to like average and get a good estimate of how much I’m going to be spending on this trip so I want to inspect my list that I made up here okay so I’m going to give this method that list and really let’s say less than 10 any number that’s in my list that’s less than 10 um I’m going to do something with that so to begin I’m just going to say for I in costs for every cost in costs if I if the current cost is greater than or equal to 10 then I’m going to take my counter and I’m going to increase it by one great um anything else right so once that Loop runs basically okay if a cost is less than 10 I’m adding one to this right and every time you go out to eat right coffee $2 uh a burger $8 a drink $3 all of those are less than 10 that’s three items I want to add those three to this counter variable less than 10 my Loop breaks I can now say if that counter variable is less than or equal to 10 okay I’m just going to take my price and I’m just going to add 100 to it right that’s giving me 100 for my food budget uh and I’m just going to go in here I’ll put an F string and I can just say updated price and let’s just print off our new price right it’s better to have extra money than not enough money on a trip um all righty these two new methods we just created I want to use them inside CC cost right CU these two are going to be called based on how much money I have for this trip so let’s do a few things I’m going to create a variable called advice this is going to basically call my advice method remember to access a method you can do so just use self. method name because we’re inside of a class um great advice is going to take a price so it’s going to recommend you advice based on the price of your trip nice um let’s say inspect and let’s do the same thing let’s do list inspect method and here I can give it my list costs brilliant the last thing you need to do is you need to return advice and inspect so we can see those results all right wow nice work our class is done that’s it okay pretty cool outside of our class now we need a location where are you traveling to so enter a country cool uh I actually want to capitalize this let’s get it looking all nice let’s say capitalized okay uh let’s say trip type I can also enter an input here and we can say uh leion if I can spell leisure correctly or business we can also capitalize to make it look nicer all right so I have location that what am I missing month so remember that we don’t need to do int input because month is going to be converted inside our init function enter a month I have month now all we need to do is we need to Jet Set so I need to create an object I need to go travel right um so let’s just say uh test okay that’s my object and that’s going to be our travel class what are we giving to our class as our arguments location trip type that should actually be month right so I can say month just like so great as a test let’s take our object and let’s call our trip info method let’s call that and see what happens I have two commas here enter a country Vietnam uh business month five ooh nice there we go you were going to Vietnam in the summer this is this is a business trip all right looking good let’s now do some flight cost calculation so a flight cost is going to be let’s say an integer input you could do float right so enter flight cost nice one and then we’re going to take our object and we are going to So Cal cost change text to say test there we go and inside here we can put our flight costs all right let’s run it one final time to our country I will do that again I will say Vietnam for a business month the same I know a flight cost uh return ticket to the US for me is probably about 24 million so ,000 enter another cost okay I have now entered My Method that’s collecting the costs right so I have a flight cost th000 now I can enter all my other costs so for example let’s say accommodation 500 eating uh five 4 3 1 2 8 10 done zero there we go so it’s triggered two things advice it tells me luxury trip right and then for our list inspect it gives me an updated price right and it adds an extra 100 onto our initial price right so we basically just created a mini system to help us plan a trip and organize the cost great guys feel free to move on to the next lesson if you’re feeling confident we have just completed working with classes in this lesson with four challenges but if you’re up for it I’ve prepared a bonus challenge for you head over to the next video if you want to check that out I’ll see you guys [Music] there [Music] welcome to the bonus challenge if you’re here you must be ready for a good challenge I hope you are as we are going to touch on a few new things and this one is going to be the most challenging of the prior four now I’m going to read our description here and then we are going to jump into our code this code we’re trying trying to create it’s going to be a guest management system with a loyalty program so I want you to think about hotels or Airlines it allows you to input information about guests like their names their ranks and their ages their rank is like how high are they in the Loyalty program are they a gold member a diamond a platinum something like that the system provides various function fun alties to retrieve guest information track loyalty points and calculate average guest age nice this one’s going to be fun let’s head over to our code so we know we want a class and we know that we want uh name rank and age so I’m going to start with that and build that out let’s say guest so I’m going to go here we will go to init self uh uh I’m going to just say uh last first Rank and age for each of those let’s create our properties so I’ll actually call it last name last uh first name that’ll be first and you can see that last I missed my T here we go my ranks for the purpose of what we’re trying to build here I’d like them to be integers so I will convert that and age we can do the same thing with if we want to find the average I’m going to need that to be an integer form all right very good our first method let’s create one which is going to give us all the basic information about a guest so like who they are um their age and this we are actually going to give it a list of guests if I I have 10 guests then I will have 10 elements in my list and I want to print off the basic information about each guest so let’s just say my all my guests are going to be given here and I can say for every guest in my list we’re going to need a list for this let’s make one uh I’m just going to call it all guests there we go so for every guest in my list all guests I would like to print off a few things here I’m just going to say self. first self. last name I should be saying and then forour age I’m going to do age but let’s just make it look kind of nice let’s say age and let’s say self. AG so forever guests print off all their information very good okay going forward we want a loyalty program so I want to keep track of like who are my gold guests that’s important right um and this will also take my list of guests like so so when I call this method I’m giving it a list of guests and I want to see who has a higher rank and if their rank is high enough I want to add them to a gold members program so to start things off let’s just create a local list so like gold members this is our list so anyone who meets a certain condition is going to be added to this list and let’s say a gold member must have greater than or equal to 10 loyalty points if they do they will be added to this list great so I want to basically take each last name of my guest and I want to add them to this so I’m going to take self. last name right that’s the last name of my guest and for every guest in my list all guests they are being added to this So currently my list Gold members is a list of every guest’s last name but I don’t want that I only want them to be in this if they have at least 10 points what can I do for this well at the end of my list I’m going to say if my rank is greater than or equal to 10 they will be added to this list I’m going to type that out for you guys because these list concatenations they are quite challenging so breaking them down is actually easier so the first thing I do is I create a list for any member any guest who has more than 10 points okay so any guest who has more than 10 points or who let’s change this again to meets certain conditions there we go uh for number two so the second thing we do is for every guest in my list add their last name to the list okay and then the last thing we do is so this condition must be met there we go in order to be added to this list okay so that breaks it down for us all right we have this new list so let’s clean that up so if gold members is true what do I want to do well the first thing I want to do is just naturally I’ll print off a header that says Gold members nice so my header then for every member that makes sense in my list my new list Gold members I will print off their name now let’s do something a little fancy let’s say I want to T their name in it’s going to say guest then it’s going to say the guest’s name their last name great all right that was a lot if you stuck with that great job rewatch that last five minutes of what we just did to break down how this list was generated which is a faster and more efficient way to make lists going on to our final method we are really just getting the guests average age so yeah taking self and we’re going to give it our list of guests again okay now I’m going to create a counter variable initially the total age is zero every age in our list we’re going to add on to this which I can then use to divide to calculate my average let’s make our Loop for every guest in my list of all guests TS my total age counter variable I want to add the self. I want to add the age to my counter variable once I’ve done that then I want to get my average age so let’s just say average age is equal to now I need to calculate that so taking our average and I’m going to divide it by the length of my list all guests that’s us finding the average then we can print off something nice like your average grade so average uh customer age not grade excuse me customer age there we go then we will just print in our average age our class is done it’s just got those three methods in there at the end outside of our class we’re going to do a few things here now so we will create an input for let’s say number of guests and this is our integer input we can use this for the range so enter a number of guests there we go so for I in range we can enter our number of guests input this is going to be interesting here so every time my range Loops I want to ask one input and through one input I want to collect um a name I can do it like this I want to collect a first name a last name I want to collect a rank and I want to collect an age these will be entered as one and they will be separated by a slash from this single input I want to make a list and that list is going to have four elements first name last name rank and age how do we make a list from an input well we can use the split method and I want to split everywhere I have a slash in order to make my list okay now that we have a list I want to add this to our other list of all guests so all guests is like our parent list one element in that is going to be a child list of data so all guests like so I want to append what do I want to append well I want to append an object I want to append an object guest right so I could do do the same thing right and if I make this longer which let’s do the same thing and say guest is equal to guest so guest is our object it’s created every time our for Loop runs and the value is our class guest our class if we go up and look it needs four arguments last name first name rank and age the last name is the first element in our our new list called Data so I’m going to say data index0 that’s the last name data index one I’m going to say integer data index 2 and I can say int data 3 right so I’m taking the elements from my list if I were to make a very quick list let’s say a first name okay uh that is going to be John comma do comma uh rank 8 comma uh age let’s say 45 so data one is targeting John so data zero that’s the first element of my list is targeting John data one is targeting you see how we’re creating that from our data list that we made here right so this is the same thing very good now I do have first last uh rank in age uh let me change this to match that first last Rank and age okay very nice now that we have that we are done with our loop on the outside I want to create a a starting point so just where is my Loop going to officially start so I’m creating a variable and the value is the first element in my list all guests now that I have an object right remember that we are going to append our guest and guest is really an object I can take my object and I can link my methods so loyalty points program is what we call it and I’m going to give it my list all guests I can take my object and I can get the guest info we will give it our list and then I will get the average guest age which we did call guest average that was it giving it our list very nice okay let’s run our program see what we have Happening Here enter number of guests I will say three guests to show us first name last name rank age okay so John SL do rank five age 45 enter our second person let’s say Jane do she has a rank of 10 she’s a loyal customer she’s 33 our final one let’s say is Josh wner score of I get a 15 I’m really I’m a loyal customer and let’s say 25 enter look at what we have going on there I have a few things we want to look at so not a whole lot’s happening actually it just printed off John Doe 45 average customer age 45 now that’s because we have our object our class guest we need to Target the properties which are in guest remember our properties are up here so because we’re passing a list this list just has objects so for each object we need to access the properties for we need to go through our class and instead of like self. name which was our initial property okay we need to go through and I need to link my object guest right because we’re passing the list as the parameter we need to access each element and each element is an object each object has these four properties great uh in our Gold members I’m going to do the same thing okay we are going to say guest last name uh instead of self. rank we can say guest. rank uh there we go and going down to our uh Age We anywhere we have the word self we’re really just going to say guest uh all guests that’s looks good let me try and run this again I’m just going to do two people this time guests to John 8 uh 45 Jane do she has a 12 she is 33 there we are now we have a finished product we have gold members and it prints off John Doe his last name or EXC excuse me it’s probably Jane do right because Jane has 12 they have the same last name it prints off the guest information and then it prints off the average customer age great you just made a reservation system right like a loyalty program very nice that was our bonus challenge we have introduced classes how we work with classes in this overall lesson as we head into the next lesson we are going to talk about a new topic of class inheritance I’ll see you guys in the next [Music] video hi guys guys and welcome back to the next lesson in the last lesson we looked at defining and creating your very own classes now in this lesson we are going to continue on that path and we are going to look at class inheritance but first let me ask you what do you think of when you hear the word inheritance well chances are it’s probably the same for python too let’s stop dive in and take a look at some things we already know so a few things we already know right we have on the screen three classes computers animals and games within these three classes we have currently three objects right so MacBook windows and Linux they all come from the same class they are all computers or for games there are many types of games but at the end of the day they’re all games right so in our example here computers is a class or a family while the three others are objects now I could create a class for each type of computer as well and this would take key data for from the parent that I could give to the child that is the topic of this lesson so here we are we have our class car you can see four objects each object has three properties so in our first example we have this red car I believe the type of car from a long time ago is called a Road Runner that’s the type and then the other two are color and wheels now you can see each object shares two of the same properties color and the number of Wheels but the type of car for each is different we have four objects all coming from a single class but what if I said we could change that what if we could make a child class and give it the attributes of this car class well we can in this example I have a class called vintage let me move me up just a little right there a new class is named vintage and this inherits the car class this is our example of class inheritance so as you can see here I have a new class vintage vintage inside the parentheses is taking an argument this argument is our other class car so it’s really inheriting everything we created in the original car class all the properties and the methods I’m going to go back very quickly as I do I want you to keep an eye on the the Road Runner right we saw that in the last class if I go back you can see the properties of the Road Runner are the same I have type color and wheels that’s a vintage car I’m going into our new child class and you can see that I brought Road Runner with all the original properties now I have three addition objects all of these objects are a part of the Vintage class but they also have properties from the original car class in this vintage class we have one new additional property you can see here at the bottom price this is only applied in this child class let’s break this down even a little more so we’ve learned a new class we have our four objects and we have one new property in this child class vintage that new property is a price we are inheriting our main class now you’re going to hear me start to say some new terms anytime we inherit the class that we do inherit we can call that the super class the super class is being given to other classes pretty cool huh all right we are going to talk about two paths two routes to inheritance super classes and derived classes now you’re going to hear me say two things I like to call a super class the parent class and a derived Class A Child class because a child inherits the properties of their parents the same thing works for classes I’ve put a few examples on the screen so I have all Audi’s are cars all dogs are animals all sofas are furniture and all jeans are pants all of those are true right now if I went to my animal I could make a very special class for dog and I could have dog inheriting some normal attributes from animals that most animals share such as Legs hair right there are many attributes that all animals share that would come from our super class animals for dogs what can a dog do well a dog can bark right that is only a dog we have two routes to inheritance Route One the class is given only new methods so it’s only given new methods we do not create any new properties for this class which makes inheritance extremely easy because we do not need to create our init method that Constructor that we learned learned in the last lesson if we do not have any new properties we do not need to create an init for our child class we can use the super class’s Constructor function that’s root one now in root two the class is given both new properties as well as new methods anytime you create new properties we need to make a new Constructor in that child class and we must also activate the super class as well and I’m going to show us how we can do both of these in this lesson so going back to our first slide of this lesson we saw something similar to this right but now I’ve redone it computers that’s going to be our super class and our derived classes all the children will be Windows MacBook and Linux they are all a class which inherits main properties and methods from the super class games is also the same thing it could be considered our super class we have an RPG a racing and a single player they are all styles of games they could be a child class inheriting everything they need from that super class pretty cool all right I’m going to head over to the next video where I’m going to break down the first path to inheritance I’ll see you guys over in the next video [Music] all right amazing so far in this lesson I introduced the general idea and concept of class inheritance now we are going to take a look at the first path to class inheritance in route one is inheriting everything from our super class let’s take a look at some code creating a child class that only needs new methods that’s a key takeaway from this it only needs new methods we are not giving it any new properties when we make an object an instance of a child class our super class that in it is a automatically called and used for our child class on the left I have my super class main you can see I have an init function as well as one other method then I am creating my child class my child class is inheriting my super class you can see there is no new properties only new methods pretty cool right let’s use some color coordination now you can see that main is being inherited from that super class and then our properties so for example self. property one I can now use that anywhere I want in my child class because we are inheriting those from that super class I don’t need to make those all over over again I can use them as I would all right you can see now I’ve gotten a bit more complex I’ve taken our example and I’ve now put in some Live code we have our super class Main and we have one method in that class user info our child class is user score it’s inheriting that super class as well as creating two of its own methods the first method Cal score is using the property self age from our super class and our second method check age is also using that same property I’m creating a child class called underscore and this will be a class which uses all the super classes properties some color coordination right so everything in green right that’s coming from the super class I don’t have to rebuild we can continue to reuse great amazing all right great this was Route One to class inheritance before we do any coding recap what we just did and we’re going to head over the next video and we are going to check out the rout two the path to to class inheritance I’ll see you guys in the next [Music] video so far in this lesson I have introduced the concept of class inheritance as well as the first root to class inheritance in the first rot we did not create any new properties but often times we want to have new properties associated with a child class this is the second route to class inheritance in this route we are going to look at something called the super function let’s dive in here when creating a child class we are still passing in the super class as a argument and old and new properties are used in this child class as well as new methods so I have my child class user score we are inheriting main The Constructor in this child class we have is right here and you can see some new things are happening specifically right here what is going on here what is this well super is a powerful function super allows us to inherit not just all the methods but it also allows us to inherit all the properties from our super class but we use the super function when we also want to introduce new properties that are only a part of our child class such as score this was created right here in this child class let’s take a look break this down even more this is a bigger concept so everything in GR green that’s coming from our super class everything in blue has been created and it’s only linked and found inside of this child class remember that super is really allowing us to inherit both the properties and the methods but it’s also allowing us to create new properties I’ve put all this in green so inside our child Constructor the first three three parameters are actually the parameters we are inheriting from our super class we can then follow that by making any new properties that this child class is going to have pause the video screenshot the video look at what’s really happening and if you need to try and take notes of your own to show this to encapsulate this what is the topic that I just introduced why are we using super and how can we use super right so here we go when we create an object of the child class remember that the super class Constructor in it is automatically called because we are using super this is basically like saying super Act activate if I create a child object it calls my child init Constructor which then calls my super class Constructor as well here is our example so I took some of the example from root one our super class is Maine Maine has three parameters what are those parameters name age location for each of those I have created three properties which you can see I’m using throughout the method in my super class heading over to our child class user score we inherit that Nifty super class and then we are also inheriting our properties I’m going to move me down for this slide in our Constructor of the child we first pass in the three parameters which are found in our super class we are basically activating those we then are free to create any new properties that we want that are only found in this child class I can use these new Properties or the old properties just like I would any variable okay so I’ve colorcoded this broken this down take a look I love the colors they are all linked to each other right so our child class inherits main we also need to tell Python and activate the original properties before we create any new properties you can see in my method check average that I am accepting a list as a parameter I can then use that list within that method’s code finally at the end of our code I have a list called test list I have an object called user and I am calling my check average method with that test list in the output of our terminal we would result in five amazing all right let’s head over into VSS code I’ve prepared

    some good challenges for us and we are going to build on our class inheritance I’ll see you guys in VSS [Music] code great to kick things off through our first challenge this is going to be route one for class inheritance so as we looked at in our description I’m going to have a class animal and this is going to hold all the info about our animals that we want to know so it’s going to have a region an animal type right like our species uh we could have a color and then I am going to want to know is the animal dangerous or not so I’m creating a property here soon for lethal for each of these go through and create a property so we have our four properties set up and the only thing we really want this method to do is I want to just get a basic animal bio so information about the animal and let’s just kind of call this like our animal passport so it’s like the information about the animal for each animal I want to go through and let’s print off all four of those properties with some basic information so an animal is going to be found in we can put self. region right how would you like to structure our self. animal type let’s say species self thought animal type let’s jump in there for the animal color let’s just say color and we can say self. color and then our last one let’s say dangerous and this is going to be a Boolean value so it’s going to return either uh true or false so self. lethal great our super class is completed right so now I’m going to create a child class a derived class for this child class let’s call this like I don’t know a clinic and it’s going to be given all the animals details and we are able to search through those details and find a specific species or region something like that so I’m going to inherit animal now this because it’s the first path the class inheritance is not going to have any properties of its own therefore we do not need a Constructor in this class our first method can just be called animal let’s call this one animal info keep them different all animal info is going to do is it can say this is a and we’ll do self. species from uh region so self. type no not type excuse me self. region and then over here let’s do this is a so animal type like so very nice then our final method is I’m going to kind of call this uh search let’s call this search and what I want to do is I’m going to give this method an animal so a type of animal and more specifically I’m going to be giving it a list of animals I want to go through this list and I want to find all the animals that are in a specific region of the world so when this method is called I’m going to be asked for a region so let’s say here input and I could just say uh enter a region let’s make sure that’s lowercase to prevent any of our errors and I’m going to go through and I’m going to say for every animal in my list animals if the animal the current animal. region is equal to region animal is my object and I’m linking the property region which is created up here in our super class animal so if the current object’s region is equal to the region that I have just input I want to do something with that and I’m just going to print off and I’m just going to say uh species because I want to know which species are found in that uh location and I can say animal type nice okay my classes are done now on the outside here I am going to create a new list and this is the list that’s going to be given to my search m method right and I want to be able to continuously add animals so if I say hey there’s five animals I want to add five animals as objects to this list now what we can do is I’m going to create a variable called amount of animals and that is going to be an INT input so how many animal in number of animals like so nice for I well this we don’t want in it in for I in range of the amount of animals we have every time this repeats I need to collect the basic information about an animal so I need a region I need a species I need a color and I need lethal which I’ll do a bit differently here then I will create an object object so let’s say animal is equal to our animal class okay so I’m creating an animal for that great so region let’s just take this one enter a region it’s going to be the same uh species let’s say enter a species color we can do the same enter a color now lethal strange so lethal is going to be a Boolean value and it’s only going to be created well right here initially so I’m not going to say enter this I’m going to say let’s say is it dangerous like so so that’s a yes or no question so lethal is going to be true if the input is equal to yes leth will be true great creating our object how can I structure this out well let’s just pass all of our inputs in so region animal type which I call species here uh we have color and then we have a Boolean of lethal there we go finally I can take my animals list and let’s append our animal and and let’s just change my spelling around here uh there we are looking good all right so our Loop’s done if I add five animals they will be in my list animals great on the outside let’s create our object of uh Clinic which should be fine that’s equal to our class clinic now for this I will need to give it a few attributes as well so let’s just start off with region animal type color who does the clinic currently have let’s just say Asia let’s say tiger and let’s say color of orange and let’s say lethal yeah we can say true for that very good I am now going to call all the methods we created so I’ll take Clinic my first method is animal bio so I’m going to call animal bio great so I’ve called animal bio let’s call our other two so Clinic dot we have animal info and then we have our clinic and then we have our search which I can call and search will take my list of animals all right looking good let’s go through and add some animals in let’s say there’s two animals we want to add to our list the first animal I’ll enter the region I will say America let’s say a bear let’s say a brown bear and let’s say yes it’s dangerous our second animal let’s say Asia let’s say snake let’s say green and it is also dangerous awesome what is happening here well when I made my object Clinic I gave it Asia tiger Orin true that’s being printed out as my animal passport which is the method I made in my super class then we are calling our animal info method this is a tiger from Asia finally we called the search method giving it a list of animals and then being asked for an input what’s happening in the search method well for every animal in my list animals if that current animal’s region is equal to the input above I would like to print off that animal species and let’s change this I’m not going to do self. animal type anymore I want to take my object animal and do animal type great I’m going to run this Asia now it’s still saying tiger because we need to rerun the application so trash can I’m going to go up and run this again great let’s do two animals very quickly I’ll go through America let’s say bear Brown yes uh region Asia species snake green yes uh enter region now I’ll say Asia there we go our species was snake because that was what I was looking for that was found in that region amazing nicely done great way to kick things off while working with class inheritance I’ll see you guys in the next challenge video [Music] welcome to the first challenge of class inheritance in the this kickoff challenge I’ve decided not to make it too easy but to make it a bit more fun when we create these two classes revolving around superheroes we need an easy way to kick things off with class inheritance and I believe that this is it this code is all about superheroes and their incredible abilities we’re going to dive in to this exciting world and explain this in simpler terms I’m hoping you’ve already had a read through this challenge description let’s head over into our code okay here we are in our code now I need to create a super class before I create my children classes and in this challenge we’re going to have one super class and one child class we know that our super class is going to be called super hero we know that the first method in a class is in it what does the super class in it need what does every superhero have in common well they’re going to have a name and a power what can they do for each of these we can create our property our variable for this class self. name equals name self. power equals power in the super class we’re going to have a few methods now the first method can be like uh use power right and this is just going to display a little information about our player this can say something like uh player’s name is using something power right and inside here we can put our name and we will put here our power to use them both all right so now anytime we call that method it’ll use the player’s name and the power that they have okay great um we could call one called All right we could make one called intro hero or just intro honestly um and this one could kind of do like the same thing something like that for our hero okay cool let’s make uh two more right so just getting in the habit of using our properties using F strings creating methods here right all these methods are very straightforward into the point so print what do you want to print here I could just say self. name has saved the day right what do each of these methods do well all they’re doing is printing something I’m using the properties that we defined inside our Constructor in different methods around my class let’s create a final one and let’s call this like power level now in here what we can do is I want to know how much power they have and specifically like what is their power for example if I come out here and I say fly or I say strength I want to know how powerful they are or specifically how long they are so fly is three strength is eight that’s the length of the word so I kind of want to figure that out out here because power level self. power is going to be a word so in here I could just say length and we could get the length of our power word right and then the level of power we have we could just say okay whatever their power length is that’s going to be their level but then you can multiply it by something like 10 10 then we can give back our level we can return our level so our super class is done uh for the purpose let’s kind of create one let’s say Batman before we create a child’s class let’s create our object just using the super class okay so let’s say Batman honestly Batman does not have a power but I am going to put flight just cuz his name is Batman very nice let’s run this code now nothing’s going to happen I should be airfree great I’m airfree now after this I could take my object Batman and let’s call like intro hero and let’s call one more and let’s say batman. power level there we go now let’s run these and this this I’m going to print off because I’m returning I won’t be able to see anything there we go I am Batman and I have the power flight and the power is going to be 60 all right because flight is six letters 6 * 10 is 60 our super class is working okay now I’d like to be more specific and I want to create that child class so let’s create a subass and let’s call this flying so this child class will be given to all the superheroes that can fly and they are still superheroes so they can inherit the original superhero class inside here I need to create one new property what do we need to do if we create new properties for a child class well new properties mean in it we need to have in it inside in it I’m going to put the first two parameters of my initial super class name and power so name power then I can create any new properties I may have so let’s just say speed like flying speed how fast can they fly before I create a property for Speed I need to activate my super class we can do this by using the super function linked to the init method just like so inside in it what do I want to initialize well I want to initialize my two parameters name and power then feel free you can create any new properties that this class is going to hold nice our class superhero Constructor is completed and ready to be built out reading through the challenge what two methods do we need here well I would like to have a method called use power use power the only thing this is going to do is I’m going to combine a few things here I am going to print off and we can print off our name right so I’m going to say like Batman is flying at the speed of that’s cool then I’ll put my speed uh miles per hour there we go so in here I can use my self. name and I’m going to use self. speed now remember that this property is being inherited and initialized through my super class because we’re inheriting it and we’re using the word self that is unlocking everything in our super class pretty cool that is the purpose of class inheritance okay um our last method I’m going to say like calc distance right because I want to Cal calculate the distance the superhero can fly and I’m going to give it a flight time how long were they flying for and the distance is going to be a local variable a variable that’s only created and used inside this method and the value is going to be our speed right and I’m going to multiply that by our flight time I can then return my distance variable all righty our classes are fully built that’s it I’m going to head down here to our objects now I’m going to create two objects here I’m going to keep Batman actually um and I am going to create another one called Superman Superman is going to be an object of the flying class that is my child class now here I need to give it a name he will have flight and then because he’s from the child class I need to give him three arguments Batman is from the superhero class which only requires two arguments so for Superman I can say what is our last one speed I will say 250 for Speed let’s change Batman’s to strength like so great on the second object all right I am going to let’s call Superman I am going to [Music] use this method with Superman so I can use intro hero again nice I can use Superman let’s use use power that’s coming from our child class right here then let’s call oo I’m going to call a attack I’m going to create a variable and this can be superman. Cal distance all right then just down here at the bottom let’s just print out some information so I kind of want to say like my superhero can fly a distance of um they can fly a distance of whatever this method returns so I can use attack because that will be the value so superhero can fly a distance of however long miles in what is their flight distance flight distance hours for name I could say Superman right um but I actually want to Target the properties so remember we work with this why not say superman. name superman. name okay let’s give this a worldl we’re gonna see a whole bunch of things happening here okay nice um I could even put a print here so we can even read this more clearly the Batman one runs like normal and then we have our Superman I am Clark Kent I have the power flight right that’s happening right there use power it says Clark Kent is flying at a speed of 200 miles hour okay and then our last one is Clark Kent can fly a distance of 7,000 500 miles in 30 hours wow very nice guys that was our first real introduction to class inheritance we have a super class called superhero this is being given to our child class flying the child class inherits everything from the super class and also has one new property of its own I made two objects our Batman object is taking the class superhero the super class and Superman is using the child class flying very nicely done let’s head over into our next challenge I will see you guys [Music] there [Music] here we are in our Second Challenge I hope the first one really kicked things off for you guys and Spark some interest and understanding of class inheritance this is our Second Challenge in this one our code we are making is going to be a library management system this system is going to allow you to manage a collection of books and our system is going to provide functionalities for adding books displaying all books searching for books by author and searching for books within a specific year range wow so we are actually creating here a library management system we are going to use super classes and we will have children classes as well don’t stress out although we are going to have many different classes a lot of what we’re going to be doing is using our properties to Output strings with print but this is really going to build on the purpose of showing you that you can work with multiple classes all right let’s jump into our library management system I’ll head over to our code in our code to kick things off we need our super class we are in a library what should this be called book logic okay our first method always our Constructor what information do we need to know about a book title author two good things and year when did they publish the book for each of those just go through remember every parameter that we give in it needs to have some type of property we can use throughout our program so I’m creating one S.E equals year nice that’s it now the only thing this super class is going to do is display information about a book how can we do that well let’s just create and let’s just say book info remember all your properties and functions and methods you should be using really specific names to help you understand but help other developers understand too so book info awesome what do we want to print out here well I’m going to print off a title I’m going to print off an author and I’m going to print off a Year oops I should have done an F string there you can say year so in here self. year there we go uh in here here self. author and our final one will be our title property cool that’s it okay so this is completed uh and to kick things right off I will create an object called Harry Potter that we can use to change as we create uh I will call this Harry Potter I haven’t read a Harry Potter book in a really long time uh J K rolling I know that um and then I don’t recall when the books came out like the Sorcerer of stone I’m going to put 200 2005 that’s probably not right let’s take our our new object Harry Potter and I am just going to link the book info method right what do you expect to be output these three lines to run a quick test let’s just make sure the initial super class is working and we can see there in our terminal that it is and it looks great all right so our object is completed it’s always a good idea to keep our classes together that’s why I put all this space right here now what two types of books do we have we have non-fiction and fiction books for each of these let’s create a child class so I can create a class called fiction book I know this is a a child so it will inherit our super class now this child class I would like it to have a genre so if I want to create a genre what do we need in it okay before I continue just remember those two takeaway points most of these challenges I’m trying to get you comfortable with new key terms and new aspects like the super function and things like that if you do not have a new property do not make the Constructor function in your child class you could just start making new methods once you inherit just like from our lesson all right this in it is going to take a few things uh I can just go up here and I’m going to copy these three parameters use them here and then our last one I can create a genre to activate all of those we can say super in it and then put those inside there don’t forget to make a new property for the final parameter nice all righty so fiction book I’m going to create a method to let’s say show info about this book now I want to basically pick up where I left off so when I call this show info method I want this to basically automatically run then I also want to say like genre and I’m going to have myself. genre but that seems a bit counterintuitive that’s just repeating a lot these were already taken from from our super class so let’s use the book info method and let’s say well let’s keep the same names so I can say book info now the problem becomes which one is going to work well if I create an object from my child class it’s going to use the child method when it hits and runs the child method the first thing I want it to do is I want it to call the book info method from my super class then it can print off my genre so let’s give that a run so we can see what’s happening here I’m going to change my class to fiction book uh genre I don’t know is Harry Potter adventure adventure okay you can can see here I’m now calling book info which is actually this method now because I am using my child class run our code there we are so instead of just printing all over again I just activated my book info method that came from the super class okay now going forward changed both of these to book info right and I did that because I’m going to be working with many classes here but if I only had these two classes we don’t need Super if we had our own name in the super class so info I don’t really need to say super doino because it has its own unique name to use it I could use it just like a property and I could say self . info that corresponds to our info method from the super class and I’m inheriting it because we’re inheriting our super class this would do the same thing right so if I only have two classes this is perfectly fine because I have more than two I’m about to make I’m going to keep with using super and I will we’ll keep with the naming Convention of info for now all right our next class the opposite of fiction is non-fiction so let’s say non-fiction book but it’s still a book so it still inherits our super class and our in it is still going to take those properties now a non-fiction book is going to have a topic what’s the book of about so that’s pretty much the same thing as genre but let’s use topic we will do our super init right get all those working again get our parameters in there and then create a property for our new parameter topic okay pretty cool now I want to do the same thing I’m going to copy this method I’m going to take it I’m going to put it in here they are all called info the order the Precedence that they take is the object that you make so when I create my objects I’m going to create three objects one object from each class so we can really see what’s happening whatever object is using that class that’s is what’s going to take precedence now instead of genre I’m going to change this to topic and instead of our property topic great I hope we see what’s happening I hope the gears are turning all righty going down so everything is pretty much completed okay um we do need our last class but let’s get some things running first so Harry Potter um I I don’t know a good non-fiction book so National Geographic that can be nonfiction book okay Nat goo let’s do our info um I don’t have book info anymore right I’ve changed that and then let’s create one more as like the main book so to show us that I can create from the super class so main is just our super class book so I can say test um author I will say me and year let’s say 2023 uh then I will call Main a.info which is the info method in the super class so you see they are all using the info method but remember their info methods are all slightly different okay uh for the purpose of readability let’s put some prints here okay let’s run brilliant there we go let’s make this even bigger this is from our super class test Josh year our fiction book has the three of the same properties and then we have a genre and then our nonfiction book has the same three properties but it has a topic right very very cool all right let’s close this I’m now going to make my last class which will be the most useful one actually what we’ve done so far is kind of like create a database of what type of book is it and what genre it has but now I need to create a library to store everything not just the general descriptions so let’s create a class Library this will not inherit anything which is a good thing for us uh this Library class is going to do a few different things and all the interesting stuff so I will create an init here but in it is not actually going to really do anything it is going to serve as a home for all of our books so let’s create a list where all of our books will be held we can create a method to add add a book I should say one book we’re not adding two at a time so self and then I’m going to give it one book I want to append this book to my list books all right just like so it’s going to go in there okay nice um let’s uh display books I want to show all the books that are in my list pretty much so how could we display all the books think about that I have a list I want to go through it and I want to print all the titles of the books how how can we do that a for Loop for every book in my list books cool I can take book and he guesses what we want to do here info I want to call the info method because I am using the word self after I print off the info of every book I am going to put a space we will see this in action in a little bit but if I have 10 books each book has a name an author and a year I want to see that 10 times so all the information about the books all right um we are able to search by author which is pretty cool so I want the ability that you have a favorite author you can look for that author in the library that sounds useful so in order to do this what I’m going to do is I want to Loop through all the books we have and every book I go through if it has the author I’m looking for I want to take that book and I want to add it to a special list just for that author once I’ve gone through the entire Library I can print off that new list of the books that were written by the author I’m searching for so the first thing we can do in this new method is let’s just say uh found books this is like a local list that any book that I’m looking for written by that author is going to be added for for every book in our list books if the current book author is equal to our parameter the author I’m looking for object property I’m accessing my objects property every time our Loop runs it’s checking for the author and it’s checking to make sure the value of this property is what we entered into our parameter or what we gave to our method so if that’s the case I’m going to take my new list and I want to append that current book I’m on great once the Loop’s done if the new list contains data so if that’s true if there’s books inside that list great I’m I want to print off and I can kind of print off some info about this author so I can say like books by uh and then let’s get our author name in here well I can’t really say uh self. author right because this is a class that’s not inheriting anything so I can say author that’s the info we give here for every book in my new list found books what do we want to do here well book book I want to info I want to call my info method on that book just like we did in the previous one great um I might as well throw an else in here uh just to alert the user that uh no books found by this author you should be really seeing what’s happening we are building on gradually the foundations of python which you should have entered this course with and we are building on object orientated programming so taking those fundamentals and the foundations you already have and turning that into object orientated programming nice all righty uh very nice that brings us to our final method um I did say that we wanted the ability to search by year right so I want the ability for that so I’m going to give it a self right in a year but oo let’s also say start year and an end year right that’s what we should be doing there okay so once again I pretty much want to do the same general idea as the search author I want a child list okay and this child list so for every book in our list books okay great if my start year so that’s my parameter if my start year is we can say less than or equal to the current books Year and that book year is less than or equal to what our end year okay so I’m accessing the current book’s year and I’m saying if the book’s year is greater than this number and less than this number I want to do something um I’m noticing a problem that I could have let’s um do a few things here uh well the problem can be fixed on the outside right just be careful these are using the child class uh these do need to be integers when they’re passed into this class as we are doing some logical Expressions so if this is the case what do we want to do just append it to your list right so what do you want to append I want to append that current book great when that’s done if we do have books in the library that have that then let’s print off just some basic information and you could say like books uh between okay uh I’m going to say start year so books between the year 2000 and the year 2010 I can say that uh nice then for every book in our new list found books what do we want to do drum roll please take the book call the info method on that book to get off our info um um I’m just going to say else print let’s just say error okay errors it’s fine wow look at everything we did take a moment pause me scroll up look at what you’ve done nice very nicely done all right so getting back down here to the bottom okay so I actually already have some books I’m going to use use as my examples okay so I’ll space these out for you be creative here okay so I create an object called Library that’s being right there in this Library I have four books I still have Harry Potter I have the Great Gatsby two fiction books they are objects from the child class fiction book I then have two nonfiction books Childs from the non-fiction class now I can actually go through and I can use all of these so library is like our main object and I want to add these books to my library that I can use later how can I do that how can I add these four books to my library well you have have an add book method and this takes a book or an object I can append an object to a list just like we did in the last lesson this object I now have the ability to access their properties because we added an object to our list so library. add book book one I’m going to go through and we’re going to add each book to our list okay so now each book is added right it’s like a database now I can take my library and I can do some pretty useful things here let’s say library let’s call display books method that’s going to print all the info about the books run it wow look at that that’s cool nice so we have each book’s information just like a normal Library database system very useful very nice let’s call library search author who do I want to look for let’s go up and let’s take F Scott Fitzgerald Let’s search for him okay uh and then while I’m here let’s say library . search year uh now it takes a start year and an end year so where am I at here let’s specifically look for this book so I’m going to say the year 2000 until the year 2020 that’s two decades let’s turn off display books there we go so I searched for f Scotts Fitzgerald so it says books by fcot Scotts Fitzgerald it prints off the books by him books between 2000 and 2020 prints off that book if you’re still here you stuck with us amazing guys if you struggled at all with this that’s fine slow down okay go back to the previous task take the task and I want you to change elements in it and make it your own make it about a hobby you’re passionate about or something you enjoy break down class inheritance all these new terms I’m using properties methods parameters arguments you should know these now this far into the course if there’s anything you want to review go back and review take a few of the quizzes you’re doing great I’ll see you in the next challenge [Music] here we are in the final challenge of this lesson for class inheritance if anything I’ve called this one the fourth challenge but this might be a bonus this one is going to be quite challenging and use things we haven’t learned yet in this course but through the foundation and fundamentals of python you should have already learned and experimented with we will use dictionaries in this challenge if you are not confident with dictionaries or you’ve only learned that briefly I suggest you go and you spend a few minutes when I say a few minutes I mean 10 or 20 to refresh on what a dictionary is and how we add and access the values of a dictionary I’ll give you a tip here in a few minutes on how to remember how to access elements from a dictionary what we want to do here is we are creating a country information system and it’s going to allow users to retrieve information about different countries our system is built using class inheritance to categorize countries into two types developed countries and developing countries now I’m hoping you read my description for this challenge a dictionary very briefly right here I’m going to type it out I am going to say let’s say we have a dictionary called country okay to access a value dictionary key is equal to a value okay I’m going to type this out so and I’m going to say how I tell my other students is I say dictionary let’s use an arrow so dictionary key unlocks a value okay if you have to say that 20 times do it it annoy yourself go to sleep thinking about that dictionary key unlocks a value dictionary key unlocks a value anytime you want the value of a dictionary you need to insert the dictionary key the key unlocks a door the same thing for a dictionary let’s go into our code all right so our super class is going to be country because we have developed and developing countries so let’s make a class called country our Constructor should have a few details what do you think this Constructor should have I’m going to say a name a capital city and a population that’s a good starting point for a country because a country well a country needs all three of those it needs a name it needs a capital city and a country well hope hopefully needs a population I’m going to say self. pop actually and we still need to use population okay nice now I’m going to get the info about this country but instead of just printing line by line I want to create a dictionary that I can use in other parts of my code because the ultimate goal is I want to return the object’s value in the final lines of code which you’ll see here briefly so I’m going to return I’m going to return a dictionary now in a dictionary remember we have key pairs so the first is our key then the value is what’s next so self. name together these are a key pair I have my key I have my value every key must have a value if I delete the key I automatically delete the value I have a name uh capital and finally population okay brilliant that’s all that this is doing it’s returning a dictionary for me that I can add things to and use as I wish all righty our next class let’s call this developed country so countries who are already developed they will inherit the initial Foundation of our super class and let’s create an init okay so self we can take our three parameters from the super class right there in this class because it’s a developed country let’s give it a GDP okay so super I am free to activate everything from that and we can create a GDP gross domestic product for this child class nice okay now I only want one real method here so similar to what we have been doing guys I can create my info method get info I have that in my super class but this is going to be slightly different I need to access my dictionary but my dictionary is held in my super class any guesses or thoughts on how we can do this I’ll give you bonus points if you actually put in the comments of this lesson what you thought of before I said anything how do we access this dictionary well let’s create a dictionary I haven’t kind of created one yet so let’s say I don’t know my dictionary is called info the value of info let’s initialize and let’s get our dictionary get info okay so now I have a dictionary to work with my dictionary is called info I want to add my gross domestic product to my dictionary so how do we access that again remember dictionary key value say say that three times dictionary key value so my dictionary is called info insert the key what is my key well it’s going to be GDP what is the value self. GDP cool I can now return my new dictionary look at what we’ve done compare this with working with dictionaries and other things you know okay nice this is a data structure we haven’t used in this course yet dictionaries are our friends they are like Advanced lists dictionary key value or a dictionary key unlocks a value very nice Okay um then let’s go down here and let’s make a class for developing country we can still give that our super class country we will still create our Constructor uh let’s give it those three following then I’m going to give it uh HDI there we go that’s for developing countries cuz they can use that uh in it cool paste in those nice and we’re pretty much going to do the same thing here guys so I’ll create my property for HDI and then uh down here I can also create a method for getting info which initially is going to be past the same thing so I’m creating a dictionary from this right and then I need to add a new key pair to the dictionary so I’m going to access my dictionary the new key it’s going to be HDI and the value is going to be our property HDI then we can return this dictionary info what do you guys think right our super classes country we have two children classes now we can create a class that is going to use all three of these so let’s say class world right all the countries around the world how can we add objects to this class well if you said hey Josh why don’t you use a list well you’re on the right path let’s say countries empty list cool what do you think we need let’s add a country right we’ve been working with this so country uh let’s add in a country let’s take our list countries let’s append that single country we’ve just added okay let’s give some more space then our final one I’ve said that we need to create is let’s just say get country uh info keep with that naming convention so I’m going to be giving it a name okay whoops for every country in my list countries if that current country name is equal to the name that I’m searching for we can return there we go return the current country and I can call the method we made inside get info right so whatever country if I’m searching for a developing country and I say country get get info it’s going to give me this if I am searching for a developed country it would give me this they are both called get info but remember that this method is linked to the object itself if the object is a developed country then this method is linked if it’s a developing country this method is linked all right I have returned the info um anything else as like a safety net let’s just return none cool wow objects need to be built now our classes are done so our first object let’s just say world world class I’m going to use that as like the parent the main object now I’ve already come up with some numbers okay for three different countries so let’s just put those in here okay you can read over those be creative guys um do some research on your home countries right so find the information use your country as one of the objects and then find two places you would love to travel to that’s always good if you’re stuck and you don’t know what to put okay so I have my three countries uh us India and China right and I’m going to use these so I got my objects I need to add my objects to my database pretty much right so my database is at world class that’s what’s being used all right so we can add in our actual objects right we are appending those to the class world so I can deconstruct them in the world class and I can use their properties okay at this stage in our code it does nothing right cuz ADD country it does nothing you just have a list that’s all it’s doing right so okay great let’s go down now remember we’re working with dictionaries so as like a test let’s just start off and I’m just going to create a variable but the value is going to be a method so world. get country info cool as you can see get country info takes a name so we need to search for something so let’s say here Vietnam I can create a condition I can say if the country is true okay so if it’s returning something right because it’s either going to return this or return this so if it’s returning something then let’s say like I don’t know country info let’s print off the basic information and I’m going to Loop through now remember our data is held in a dictionary so I want to Loop through and I want to print off the key pairs I want to print off the key and the value to every key pair in my dictionary how do we do that with a for Loop this is slow slightly more advanced with our Loops but let’s break down the idea so for every key and value in my country info it’s my dictionary I want to get their items so I want to if I were to translate this for every key and value in my dictionary I want to get their items okay I can print let’s print off my dictionary [Music] key and my dictionary value cool and then else I’m just going to put here as like prevention I’ll say country not found wow what do you think is going to happen when I run this program okay let’s run it country not found what’s going on I said Vietnam oh I don’t have Vietnam as an object right I’m hoping you guys caught that okay let’s take this let’s now say India country not found that’s also an issue why why is that if I cap capitalize India now there we go there we are okay so before I get on this information I’m going to talk about that initially I said India right you are not putting the object right so for example if I put this object India let’s watch what happens country not found we are not putting an object you are putting the country name okay because get country info it takes a name for every country in my list if the country name is equal to the name I entered return country info right so let me go back now let’s do USA Country not found okay well because the proper name is United States okay prints off country info let me go down here so we can see it says name United States right name is a key the value is United States capital Washington Capital is a key Washington is the value right do you see how we’re unlocking our entire dictionary and using those key pairs very well well done you guys I’m so proud of you for how far we’ve come over the last three lessons you have learned so much about object orientated programming you got an intro to working with objects we learned how to define and create your own classes and objects and in this lesson we talked about class inheritance which has prepared you for our next lesson let’s head over and let’s introduce the next Concept in in objectoriented programming I’ll see you guys in the next [Music] lesson all right Welcome to our next lesson in the last lesson we introduced the idea of class inheritance and how we can create a super class and give that class to other derived classes or child classes in this lesson I’m going to introduce to you the concept of multiple class inheritance now when it comes to this I want you to think about just normal inheritance but instead of accepting just one class we can accept multiple classes great let’s jump in as our example here has we have the animal class and I want you to view the animal class as the Base Class everything is derived everything comes from this animal class and it provides the basic for all the animals each animal can then do something special so we have two sub classes we have can swim and can fly and then finally we have a child class we have a class called bird and bird is inheriting not one but two classes right we have our Base Class we have our classes that Define behavior yes I did not make a l Land class right so animals for land but you could have that right so every animal could have a few things we have our species the type of animal you could have a region of the world this animal is found is it dangerous things like that right and then other special classes for specific animals like a fish a shark a dolphin or can fly right you would apply that to a bird so everything there is being passed down okay we do this the same way we inherit a single class but we do this with two classes so in the example we can do that by entering two classes in in those classes we just need to separate by a comma therefore we can inherit any other classes we want more than just one so take a look at this code this is a very very basic setup of multiple class inheritance but it still does a good job at expressing what’s really happening behind the scenes we have a class for our animal this is the base class this class also holds our Constructor method in it with only one property we also have one method eat and this just prints off the name of the animal is eating great the animal class is complete I then have a subass and this class is called can fly and this will be applied to any object that is an animal and can also fly so my bird finally we set up our child class this is the class that’s inheriting our two other let’s call those parent classes we create a Constructor and we initialize the name from the super class animal I then Justified one additional property for color for the color of the bird right and then I have one method here and this is going to print off the color bird is sleeping so the red bird is sleeping right the blue bird is sleeping at the very bottom then I’m creating an object from my bird class then I’m linking my object my bird to the three different methods we built each method is a part of a different class but we are inheriting all of our classes in one okay let’s space out our alignment here’s the setup for that in order broken down right python reading top to bottom it’s good that you have a good structure for your code now if you haven’t quite caught it I’m going to get an error why is my program going to run an error think about it pause it try and find the air great because initially I did not have the color but because my object is from the bird class I have name in color what color is the bird when I create my object I’m giving the name or the species and then I’m giving the color therefore calling all three methods because we’re using the super function here in the child class we can pass the name to the parent class and to the other classes which need it the most right they’re all kind of hopping around and by using that super function we can therefore take what we want to initialize and pass that around to the other classes that we are inheriting or our super classes right I have my super function and because I’m inheriting these two super classes I can initialize the name to use in my two super classes great let’s take a look at the first challenge that I want to kick things off with here we are so don’t go back okay don’t go back you can try this one on your own before you jump into VSS code and you watch a few of the challenges that I have prepared this may or may not be one of the challenges that you’ll see a video of I want you to try to recreate the code from the previous slide use it as an example to build your own I chose the topic animal with can fly and can walk but you should be choosing a topic that interests you where do your passions lie create one Base Class which is my animal super class and then two Behavior or style classes which mind work can fly and can walk finally create a final class for one child class and you just need to use print to interact with all the classes nothing too complicated just to Showcase your understanding of multiple class inheritance remember to use the super function to pass the arguments around to our different classes I’ll see you guys over in vs code for our first [Music] challenge [Music] all right here we are in the first challenge I’m excited for this one guys let’s go through and check out the description quickly which I hope you’re all brushed up with and Dive Right In so in the world of transportation we are evolving we have Smart Cars we have electric cars hybrids we still have gasoline it’s changing we have a super class called vehicle and this represents the generic vehicle with all the generic attributes mag model year but we also have two specialized classes and this is going to be your electric vehicle and your gasoline vehicle the electric vehicle is going to focus on any vehicle that’s powered by battery and it’s going to include Properties or features like battery capacity and the ability to charge our gasoline vehicle class is going to deal with vehicles that are obviously powered by gasoline and this will have its own properties like fuel capacity and ability to refuel both of these classes have a method called get range which is going to help us calculate the range of a vehicle based on their respective energy sources our job is to make a derived Class A Child Called High hybrid hybrid is going to inherit everything let’s jump in heading over to our code all right to kick things off let’s make our base class right everything is going to have vehicle so I’ll say vehicle I will Define my Constructor in it with our key self we then have a make a model and a year for each of those those you can Define your properties then I am not going to do anything else for this class this class is like a mini database if I have 10 different car objects each object is going to have these three I can hold in one object three values that’s all this is going to do so think of this class like a mini database for each object awesome continuing on let’s make our class for electric car okay um this will actually not inherit anything either so I can create a Constructor and for this I’m creating its own property so remember let’s just create battery capacity that’s a good one and I’m going to say create one so let’s say self. uh let’s say battery cap is equal to battery capacity great then I will create a method for charging all of our electric cars can charge self inside we can just return the battery capacity that’s all we want to do for that finally what is an important thing to know for an electric car well our range now I cannot say range because range is already a special python function so let’s call this get range that’s its own unique name right that’s a much better name our range we can just return our let’s say our battery capacity and let’s say the range on the battery capacity is multiplied by five looking great all righty and our last let’s call Super class or parent class is the last type of C car we have and I’m just going to say gas car the gas car has its own Constructor and then its own property is going to be fuel capacity and we can make one called fuel cap and that’s going to be equal to our fuel capacity parameter inside here we can call one and say refuel or get gas right and all we’re going to do is pretty much the same thing we did for the electric car one so we can say self. battery well not battery in this example it’ll be fuel cap and then we will have self. getet range and for this range we can return something like let’s say you got 20 miles to the gallon right so if you got 20 miles to the gallons we can multiply that by 20 great so we have three parent classes or or super classes here now I want to drop these in to a child class a derived class and this derived class is now a very specific example of a type of car we see out on the road let’s make a final class called hybrid it’s a hybrid car so hybrid hybrid is going to inherit actually everything right it’s going to get the info from the vehicle class it’s going to get the electric car info cuz a hybrid’s half electric and half gas so look what’s happening we can take any other class and we can pass those in I’m giving three classes to a derived class now our hybrid we are going to do a lot here well not actually a whole lot because it’s really just in it doing all the work for us what do I need to put inside in it well I need to put all all the parameters we initially made so all the parameters from vehicle I’m going to go and I’m going to put the parameter from electric car because we’re going to need that uh and then we are going to put in the parameter from gas car which was fuel capacity what do you think I need to do now inside in it I don’t have any new properties I’m inheriting them all I need to activate them each of them so I’m going to say super. init don’t forget your underscores so for this init I’m going to take these first three because that’s coming from my first super class great let’s just copy that row we need two more so I can have my next row for super in it and inside here we just need to activate our battery capacity from the electric car super class our final one we just need to activate our fuel capacity right so now everything is stored locally in this hybrid class which I can call all three of my other classes to use methods and get information ah this is great let’s finish out this challenge what I’m going to do here is I’m going to create an object let’s just call this car and my car is going to be a hybrid type of car what arguments do we need to give here well we need to give it a lot actually so I’m going to start things off with a uh make of car because I have here make model year in order so my make let’s say a Toyota I think you know the model of car I’m going to do I’m going to do a Prius uh let’s say a year uh year let’s do 20 23 uh for battery capacity let’s just give it a round number let’s say battery capacity is five and then finally fuel capacity let’s say it can hold 40 great on my car object I want to call a few things but notice right we are returning when we’re returning from a function or a method the value is going to be used as the value to a variable so instead of taking my object right now I’m going to create a variable and let’s say I want to know my battery capacity what is the value to this variable going to be well the value to the variable is going to be whatever this returns if this returns 20 okay then this should be 20 to get that I need to call My Method so I’m going to take car and I am going to call charge just to run through very quickly if I print off my variable battery capacity it should print off five all right so okay I’m actually given an error let’s go through and address this quickly so missing two required ah all right inside of our init let’s just go in because I’m using three of these uh it’s bouncing around let’s just go inside here and let’s say self for each of these okay I’m using three supers let’s just put in self trash my terminal let’s try it again I should see the number five and in matter of fact we do not see five okay let’s take these let’s not use super three times in a row let’s link our actual class so in the first one vehicle in our second one electric car and our final one let’s say gas car great so I’ve linked the classes within it there we are I’m giving back my number five right because battery capacity is holding the value of whatever this method returns that’s five looking good good tests now now going forward let’s just print off basic information about our car such as battery capacity fuel capacity battery range fuel range okay so we have battery capacity I have my fuel capacity and we have our battery I have two batteries those no battery range when we’ve run our code we are going to see a few outputs here there we go back battery capacity of 5 Kow per hour fuel capacity of 40 gallons we have our battery range of 25 miles and our fuel range of also 25 miles looking great except these last two they’re both saying 25 miles I’m going to throw a really easy fix in there let’s just honestly say get fuel range for this one uh split things up a little bit so let’s say fuel range run it again as our final test and we should see there we go looking much better great I hope this was a very easy way to introduce to you guys the basics and the concepts of multiple class inheritance look back through these videos especially in this video and before going into the next one leave a few comments and a few notes in your code use VSS code as a big notebook I’ll see you guys in our next [Music] challenge all right great let’s kick off our next challenge there is a bank that offers multiple types of accounts to its customers just like any bank we have a type called savings account and our savings account is a special type of account that allows customers to save their money and earn interest although it’s not that high we still get interest this is what we want to build out we are also going to have a few other classes like our main account class our interest account and then all of our transaction history needs to be held somewhere too this challenge is going to be a bit harder than our other ones and we are going to be doing some mathematical operations as well think Banking and think how this can provide a real value to a customer this is a real world scenario problem jumping over into our code let’s kick things off and let’s make our account super class this is strictly going to hold our account number our account balance and then any deposits or withdrawals we make to this account will also be applied here as well so all the basics our Constructor method is going to take our account number and our balance so let’s say account num and uh let’s say our balance like so every user needs to have their account and every user is going to have a balance with that bank as well so balance we need a method for all our deposits now this doesn’t actually have to do a whole lot every time this method is called all that we want to do is we want to take our current balance and we want to add an amount to this so this amount can be declared as a parameter when we call this method we want to give this method an integer or a float to be added to the existing account balance nice pause the video try to make the withdraw method yourself what could go wrong in this method pause the video here all right our withdraw method let’s say withdrawal um withdrawal is also going to need an amount how much do you want to take from the account before we withdraw we need to make sure that the balance well we need to make sure we have enough in the account how can you do that using a conditional statement if your self. balance is greater than um or equal to your amount you can do that right then you’re going to take your current balance and you’re going to subtract your amount what could go wrong well you have no money so let’s print off and let’s say uh not enough funds like so okay um that’s it great the last method I asked for us to make is going to be a get balance method that is just going to return how much money is in the user’s account so I can just say get balance the balance of your account and all we want to do is return and we can return get balance or I should say return the current balance like so very good so our main account is done right a user opens an account at the bank and these are their options with that bank they can deposit and withdraw or get their balance that’s it but now a user wants to go forth and open a savings account so this is going to be an interest type of account let’s create a class for this let’s say interest account this new type of account is going to inherit the current account the base account in this interest account we are going to have its own properties so let’s initialize very quickly let’s say self uh let’s go up here I’m going to take account number and balance pop that in here and then the methods of its own we need a rate right their interest rate before I create their interest rate let’s activate our super methods so let’s pop those in there uh let’s pop in self and let’s create our interest rate property n there we go very nice what do we want in here well the only real method of this is I would like to create like a calc interest I want to calculate the interest so I can return what do I want to return let’s say self dobal balance I want to take my current balance and I want to multiply it by the interest rate which is going to be our new property that we just created here right that would calculate our interest rate how much are we going to receive good our interest account class is completed before we make our actual savings account we want to create a book like for a bookkeeper or a mini database in a way and I need a place that’s going to store all my transactions for me and this will allow us to store them in a list so let’s create a class called transactions this is not going to inherit anything actually this is a new class that I can append things to so let’s say in it and in it doesn’t need any parameters we are just going to create a property for a list okay that I can append things to and remove if you wanted to as well uh every we do so if I deposit I withdraw technically that’s a transaction so I would like to add something to my list let’s say that and let’s say transaction cool uh let’s call our list and let’s append what do you want to append I want to append the singular transaction brilliant finally let’s get our transaction history so let’s just say history uh and for this I’m going to say for every transaction in my list transactions I would like to print off the transaction like so looking great okay so look back through what’s happening so far I’m about to jump in and I’m about to make the final class our savings account because that’s what we’re trying to build right now we’re building a whole system I built the account we built the interest rate account and then we have like a notebook or a checkbook it prints off all of our transactions and keeps those in check great our final class let’s create us a savings account I am going to inherit now here I actually only need to inherit the interest account and our transactions but why why is that going to give me access to everything I need in my account that doesn’t make sense because interest rate is actually inheriting a account for us so I don’t need to pass in three classes like I did in the last challenge because I’m giving interest account the account super class this is like storing two classes in one so I’m only needing to give my savings account class two classes instead of three great in savings account let’s create our in it and we sort of need a lot of things here we need an account number you need your balance and you need your interest rate right which is what we defined everywhere else so let’s pop those in here then I am going to call my two classes so interest account do init right this is like our super. init what am I initializing from interest account well I’m actually initializing account number in balance and interest rate in reality right everything then finally I want to use my transactions class and I don’t need to put inside in it I don’t need to put anything because we don’t have anything inside the init of our transactions class so the only thing we can put in here here is self right our key that unlocks everything all of our classes are completed we can now begin to work with our objects so going down here let’s go forth and let’s create an object called savings and this is going to be our savings account what do we need here well I need an account number so be creative right if it’s a savings account I could do savings account double one I’m the first savings account at that bank right bank balance let’s say I have 5,000 in the account and I am earning an interest rate of 0.08% all right I can take my savings object and I could deposit and

    withdraw from this right so let’s hold off on the deposits and withdrawals until we kind of see everything else is what’s happening right right let’s get and let’s go forth let’s say print transactions well I can’t print transactions yet I have get balance so let’s return the balance currently I’m going to come down here let’s say savings do uh nope let’s just create a variable called uh balance and let’s take our object now and let’s say get balance remember I’m returning a value which can be used us as the value to my variable balance so I’m going to say balance and then let’s say here our balance variable that’s it okay to fix this error let’s just go up uh super. in it but three were given let’s try two things really quickly the first one let’s change super here let’s say account let’s see if that does our trick for us it does right so now it’s printing off the balance of 5,000 and that’s what I wanted to haveen right great okay we have our variable the value is 5,000 okay now I can do a few new things let’s do savings and let’s call the deposit method let’s say cool I’m going to give $2500 so at this point right I should have 7500 but I am also going to make a withdraw and I’m going to say I owe rent so I’m going to withdraw 6 50 okay great I’ve done my withdrawals so let’s calculate our New Balance great New Balance this is how much I have left all righty let’s continue on so now going forth let’s create one called interest that’s going to be a variable and I actually already have a balance so this is going to work out good so interest I want to get a returned value so let’s say savings and let’s say our Cal interest method right now that I have those we can add in our transactions so let’s add two transactions what transactions do we have well we did this one and we did this one so currently for adding transactions you could add the numbers um um for this I’m just going to keep it neat and let’s just make a string let’s say deposit let’s just say 500 okay and let’s say withdraw uh let’s say uh withdraw and let’s not even do that let’s say how much did I put in I deposited 2500 into the initial balance and I withdrew 650 from that balance I have my balance and then let’s get off and let’s print off our uh interest interest and then we can get our variable interests like so looking great I am going to run our program look at that there we have our balance right we then have our interest of 548 now the one thing I’m noticing I didn’t display my transactions here right I should print those off so let’s say saving let’s say h what do we call that I called that history so I want to call the history method all right let’s get that bank info I approve of that looking good we have a deposit of this much withdrawal of this much I have my current balance now and I have the interest that I’m earning on the account looking great I hope the gears are turning guys remember before you watch these videos these Live code videos pause the videos try these problems on your own try and find those Solutions because I’ve given you the text files which breaks a lot of it down so work through a part of it watch the video on maybe how I did it pause me again and then work through the next video that’s how we challenge ourselves and get better remember errors are your friends use them to your advantage to help you solve a problem I’ll see you guys in our next [Music] video great here we are in our next challenge with multiple class inheritance in this one we’re trying to create a customer loyalty system I want you guys to think back on how we did the last Challenge and use the knowledge gained from that in order to implement the correct logic and code to solve this one we are going to create a loyalty system which allows the tracking and managing of loyalty points points earned by customers so start to think about hotels or like Airline points every time you fly you earn points to rank up your status within an airline or an organization we will use class inheritance to organize customers and store their transaction history great I’m hoping you guys have taken the time to read through what we need to do here let’s head over and let’s implement our logic and start coding all righty to kick things off we want to create a single object so I’m going to create a single class to hold the information for our customer so let’s create a Constructor and the only real information is we are going to take a customer ID so like so and then a customer name every name is linked to an ID so let’s create our our properties for these and this is the only information our customer needs at least for the time being so when I create a customer object the value will be this class customer and that single object is going to hold our ID and our name nice let’s proceed and let’s make a class called loyalty points this class will be responsible for earning points redeeming points and checking our balance our Constructor is not going to require the properties we made in the customer class and it’s not going to require any information given to it but we do need one property with the initial value of zero soft do points we can create create a method which will allow us to earn points and earn points will take the number of points so I’ll I’ll say amount how many have we earned and all we can do is take our property points and we’re going to add in our amount great what if you want to spend those points you found a great deal on a flight well you should be able to redeem those points how many do you want to redeem that is our amount now we first need to check if you even have enough points so if the points you have are greater than or equal to the amount your requesting to take out then you are permitted to do so and we can subtract the amount requested in our redeem method else let’s just say here yeah you you don’t have enough points uh so I’m going to say not enough points like so great and then our final one that responsibility is to basically show Point balance and all we can do here is we can return self. points all righty our two classes are done right we have one specifically for for our customer we have one specifically for our points that’s going to handle the earning of points and the redeeming of points let’s create a new class that’s going to inherit both of these who Could That Be Well a special customer a VIP customer what if we make a class called VIP customer and this will get our customer and it will also get our loyalty points inside here not a whole lot’s happening but I want to be able to create one object that inherits the functionality of the two super classes customer and loyalty points so I won’t make any new methods here think of this as a mini database I will create init though and init is just going to initialize our customer class and our loyalty points class so all we need to do here is I’m going to take our parameters from the init of customer paste those in like so and then let’s just initialize both of our classes so customer. init say self paste in those take out that extra comma okay so I’ve initialized that one and then I’m going to come down here and I’m going to initialize our loyalty points class and just give it all righty VIP is done we have three classes all of these correspond in work together and they are held in one class created right here now moving on we will need two more classes actually right this is a great example of O Let’s create our two classes for our transactions my first class is going to be called transaction it’s not doing a whole lot it’ll be like a database just like our customer class to store relevant information about each transaction so making my Constructor the job of this is to hold three things a transaction ID number a customer and an amount so these will be given to to an object three values and they will be stored inside one object instead of three objects great now that I have that class done I can use this within another class so transaction will be each transaction will be one object each object will hold three parameters or three values a transaction ID number a customer ID or a customer name I should say in the amount now I have the ability to create a class called transaction history inside here we want a place to store all of our transactions so I can create a list called transactions we will create a method which will allow us to add our transactions so it’s going to take a single transaction we can take our list we can take our list and we want to append that singular transaction like so let’s fix this that shouldn’t be a semicolon that should be a colon brilliant in our last one I basically just want to show all the transactions it’s a way to check our account so let’s say show transactions and I want to Loop through the list that we created here so for every transaction in my list transactions I would like to print what do I want to display about each transaction well I want those ideally so I’m going to say transaction Let’s uh link our trans transaction ID for now let’s link our customer well let’s link our current transaction customer name and then finally we can link our transaction amount great let’s create our objects and let’s watch what’s really happening here all right we have just made five classes this is the most we’ve made yet these two are working together within our VIP customer and then we have two different classes here one is responsible for our transaction information then one is responsible for our transaction history go back through the code and see what’s happening there all righty our objects let’s just make one object and let’s say I have a VIP customer and he he or she is an object from our class VIP customer I need to give them a customer ID so be creative uh vip1 all right and then a name let’s say I am the VIP customer great let’s my account let’s add a few points to it so VIP earn points how many do I want to earn let’s say I’ve just signed up for a new Airline credit card where they they have an award bonus of 40,000 miles within the first 3 months and then I would like to spend 12,500 points on a quick flight so that’s what’s happening there all right now for each of these I should have a transaction right so let’s make one called transaction one and the value of this can be our class transaction I have two transactions which we see above so let’s make two objects the first argument will be the transaction name or ID number so let’s say uh T1 it’s the first transaction on my account what do we need here I need who well who is my object VIP and finally the amount well the first amount we said 40,000 so I’m going to put that there in our second transaction we have our same object and then this time I spent 12,500 and just because I’m reading this out let’s make this a string so then I could actually say plus just for the purpose of our list and seeing and viewing the transaction history here great great all righty so we have three objects on the screen and we are calling two methods it’s looking nice it’s coming together nice now that we have those let’s make one called transaction history this is going to be an object from our transaction history class now we don’t need to give it any arguments here but we can use those methods so let’s say add transactions what do you want to add well I want to add transaction one I also want to add transaction two remember these are being added to our list up in this class that we built like so there we are so we’re adding those transactions that we created here now that I have transactions added what could we do I want to show all the transactions that we’ve had happen so take our transaction history history and we are going to link the method show transactions great so it’s going to show all of those that are occurring now the last things we need to do is just get our customer ID our customer name and the number of points in their account so because we are returning the number of points in the account I need to make a variable to store that value so let’s say uh balance now balance is our variable the value is equal to our get Point balance so show Point balance there we go then we just need to print off a few things so let’s print off I’m going to say here let’s say customer ID and let’s just drop in their uh customer ID number let’s print off here and let’s say our customer name let’s say our vip. name looking good and our final one let’s just say uh loyalty Point balance and here we can just use our variable balance this looks great we took what we learned from last lesson we implemented key factors here in this Challenge and we even built on it more let’s run our program we have our transactions being listed so transaction one Josh uh I added 40,000 points then we subtracted that and then you can see I’m getting my ID my name and then the balance I have in my account after all those loyalty Point transactions let’s head over into our final challenge for multiple class inheritance I’ll see you there [Music] here we are in our final challenge for multiple class inheritance in this one we are trying to bring in the fundamentals of what you could need to build an eCommerce store or the logic that’s happening in the back end so we’re trying to create an online shopping system which is going to allow the interaction between customers and sellers the system is designed using class inheritance to tell the difference between customers and sellers each with their specific functionalities read through this challenge I’ve put this as the the final one for this lesson but do we need to use multiple class inheritance or just normal class inheritance you tell me I want you to give this one a shot before watching this video how do you solve this challenge this challenge is also going to require us to use the open function from python we haven’t looked at this now this is something you may have to research on your own Maybe you’ve seen it before how do we use the open function what operators do we use with it I’m going to break that down as I go through those parts of this challenge let’s head into our code to kick things off up top we want a class for user now this we are going to create a single object from and it’s going to store a username and the email of the buyer or the person who is signing into the account right if you log on to Amazon this is you for each let’s create the properties we can use as we are building this out we will say self. username and self. email as those are the parameters great I’m going to mark this class like so now we can create a class for customer customer will inherit user we need to access the username and the email inside our customer let’s build our Constructor our Constructor because we are inheriting will take our username our email I will drop down here and let’s just initialize it so with our init and remember to pass in our username and our email like so oops I will make one new property here this property is going to be our shopping cart so all the items you add to your cart will be appended to a list inside customer we would like to have one that’s called add to cart what will this do well this is going to add a product that you want to the card we can append that we can append that we have ad cart uh what if you don’t want the item then you need to be able to remove that item from the cart so what item do you want to remove I want to remove this product if that product we’re searching for is in my shopping cart then we now have the ability to remove it so we can say cart use the remove method remove is the opposite of a pend when working with lists right and then anything else we can print off and just say uh item not in your cart let’s view our cart so what do we currently have in that cart how can we do this let’s go through and let’s just say items in cart then we need to go through so for every product in my shopping cart we would like to print off the name of that product so take our product link the property name are we still here I certainly hope so this brings us to the last method now I want to have the ability to save my cart as a file specifically a text file so all text files they end with our extension txt so for example filename.txt I want to save all this information into a separate file to do this we will use the open function and I need to give it a file name what we can say is with the open function I want to open the file name and I want to write new contents inside this file I’m going to call this file file so with the open function I want to open this file and I am now going to refer to this file using the name file this is like a nickname or a variable we are creating that is linked to this file for every product in my shopping cart I want to write in my file what would you like to write in the file well I can add an FST string and I want to write in the file I want to write the product name and I would also like to write the product price looking great once we’ve appended all of those to a separate text file that’s going to be held somewhere else then we can just print off and I could say something like cart saved to file name it’s done right once we run this code we will see the implementation and the output of it but that is how I could use the open function very basically to work with a text file and append to a text file the two real new key phrases here if you’ve never worked with this before um I’m hoping you did research before watching this challenge is we have the with operator and we have the open function with those we can use the right method to write contents inside our file all of our customer information is completed we now want to build the opposite and we want to build the opposite for the seller so I can create a class for seller we don’t need a class for the sell’s attributes because they can actually inherit user if you are a seller on Etsy you’re still a user if you’re a buyer on Etsy see you’re still a user both of those have a username and an email linked to those accounts which is why I’m using user for both of those going forth with our seller class we will initialize and inside here we will say username and we will say email again I can take what we did here so my super init I’ll take cart I’m going to change that but let’s take it I initialized our super class and let’s change we do need a list but the seller is going to have a list of products instead not a shopping cart a list of products they can do the same thing as we did in the above so without looking I’m going to scroll down can you do the same methods just in the seller class so for for example we have ADD product we have remove product then our last two we would have view your products which brings us to our final one you could have save product can you complete those without scrolling up the same Concepts we’re just changing a few small details within add product we need our keyword self and then we are going to be giving it a list or specifically individual products to be appended to a list so self products append product we can do the same for here we’re going to give it s we are going to give it one product before removing we need to check if that product is in my list of products then I have permission I can remove that from my list what do I want to remove the product that I give as the parameter anything else we can alert the user and say uh products not found great for our view products we are going to print off all the products that I have in stock so list of products we can then Loop through and say for every product in my list of products I would like to print off specifically the product name so I’m going to go here we don’t need that string I’m going to take my product link the name property good if you’re new to the open function what do we do here how do I save the products to a text file well we need to give it a file name to be saved somewhere I am going to say with my open function file name I want to write the contents inside as a file for every product in my list products I would like to take my file and I would like to write contents inside of it what am I trying to write here well I’m trying to write the product name and I am trying to write the price of the product how much am I selling it for once we’re done with that you can just print off and you can say uh products saved to your file name where are they going to be saved amazing we are here for our final class now I do need to create a class right cuz because a product is an object and this object is going to store information about the product itself such as a name and a price which we’ve been working with for each of these let’s create that so name is equal to name your price is equal to price that you are giving the product we then have the basic info so basic info about the product we are just going to go forth and I could say print PR what do I want to print here the name of the product so selfname now that we’re in this class and I would like to also print the price of the product so self. price great classes are done it is time to create our objects which are going to use these methods that we have now built on the outside let’s create two people let’s create create a customer and the customer will be from the customer class and let’s create a seller it’s a simple transaction between a buyer and a seller on an eCommerce platform I need a username so Billy Bob two3 that’s the first username uh an email is going to be Billy at Hulu that sounds like a bad that sounds like a hot mail right our seller is going to be Sarah Jane 88 and her email is going to be Jane at Yahoo because who uses Yahoo anymore all right so we have our two objects customer and seller now the seller is going to have a bunch of products so like product one and we could pretty much add all these so I’m going to copy this and let’s say she has three products in her store the first product can be a shoes pair of shoes so I’ll say shoes she sells her shoes for $65 yeah that’s cool 65 even okay her next product is a ring and she sells the ring for 125 something special about it then lastly she sells a t-shirt this t-shirt can be what 28 bucks we have our three products which are going to correspond to the seller and the seller is going to sell them to the customer going forth all we need to do is let’s take our customer and let’s add those products to the cart right so so what do we want to add to the cart well I want to add here I can say product one product two and product three to our cart now they are in our customer’s cart using the add to cart method that we made we can take our customer and let’s say view cart we can view the contents of the C so if I were to run this let’s watch what happens there we go I have items and cart I have all three of those items that the seller has so shoes ring and t-shirt looking good so far we’re airfree I can continue on and let’s now take our customer and I want to save my cart I need to give it a file name so what do I want the file to be called where I save this so let’s just say customer cart giving it the text extension for the text files then we can have what methods haven’t we used remove from cart haven’t used that yet so let’s remove an item let’s say ooh the ring is too much we don’t want the ring anymore so here I can take my customer and I can say remove I should say remove from cart uh product two I don’t want product two anymore let’s now view the customers update cart I’m going to run that great there we go so cart saved this text extension I will view that here in a bit let’s just complete and let’s go with our seller so I’m going to say seller add product what do we want to add well all of those products we’ve created so the seller is going to have all three of these let’s go product two and product three like so very good then I’m going to take my seller I would like to view the products the seller has and finally what do I want to do I want to save the products where do I want to save it let’s say seller products. txt all right I’m going to run this great look at that items and cart we have our three here we have our text file extension this is our updated cart and then here we have the list of products from the seller now where are the text files that’s the question they’re going to be over here let’s open our text files up top here we have our text file customer card text with the contents we have our seller product text with the contents if we wanted to get these on one line all we would have to do let’s go up here to our open function let’s just put those on a new line and we can do the same for our other one amazing well done guys that was our final challenge for multiple class inheritance I will see you guys in the next video spend some time to review what we’ve done here before going into our next lesson I’ll see you there [Music] we’ve come so far this is our last lesson of of this course for objectoriented programming and this is a great way to end the course as we are going to talk about special class methods only found in Python and only used within a class these are essentially Python’s version of like Special Forces or like the Navy Seals let’s check out what I’m talking about what are these special methods so special methods are automatically ran when an object is created and this is the same thing that happens with in it right because in it means initialize it means start and in it is automatically used and called when we create an object we don’t even think about this it just automatically happens these are double underscore methods in it has two before and two after and these double underscore methods make operator overloading possible now I can say special methods but I could also say Dunder method Dunder means double underscore method it’s a Dunder method and these give extended meaning beyond their predefined operational meaning so you already know one special method in it we’ve been using this this whole course so you have a general idea of what in it is and how in it works but with python we have so many other special methods that we could use we are only going to take a look at a handful in this course once you get a general idea of what they are how they work you’ll be able to implement your own logic in use new ones outside of this course let’s check out a few of these now here is a list of some special methods now the first one I’ve put as in it just to warm things off because you already know that one is down right we use in it to build variables for the object we have a Dunder method called Dell and Dell has the ability to delete an object I want you to think about now how do you delete an object from a dictionary well the same kind of applies for this Dell method we have the dunder method string and this Returns the object representation in a string format so it takes the object and it turns it into a string we have the Len or the length method and this Returns the length of an object we have the equal method which allows us to compare the Val values of two objects using the equal sign operator that’s really useful we then have the addition method and this allows us to add two objects you can start to think if there’s an add method is there a subtract method yeah there is one and we can take a look at that there’s endless special methods where’re only looking at a few here and we’re not going to cover all of these in the next few slides but you know that they have them and in the challenges I might give you one where you use a method that’s not in here think about how can we do that where could you learn about that let’s take a look at the first Dunder method I have which is going to be a string this method creates a string representation of our object it’s called by the builtin string function we have this this this is a normal built-in function that comes with python and it’s commonly used to define human readable strings if you want to have information a person can read we would convert it to a string you can see I have a class person with in it and then under in it I have my string Dunder method it is returning the name and the age of my object which is John 25 when I print my object it’s automatically going to return this to me as a string so I can construct the string using the name and the age properties from our in it and it’ll return a string for us we create an instance of person if you try to print the object without our string method check out out what happens it’s not necessarily an error but it’s just printing off literally the word object here is how that would look so everything done correctly with our Dunder string method here we would get a nice output like this if we try to print an object without the string method we would get this so this is a useful tactic right now why do we use this this string method is helpful for a lot of things debugging and displaying object info that’s in very specifically human readable format you will see this in code examples as you broaden and strengthen your programming career let’s take a look at the next example of a Dunder method next up we have the delete method and this method is called when an object is about to be destroyed destroyed it’s used to perform any final actions before the object is removed from the program’s memory so think about any cleanup tasks or actions you may have any connections we need to close anything that needs to be handled before we delete an object this is why we would use the delete method now it’s not actually very commonly used but it is very useful when you’re trying to achieve that goal and it can be helpful in situations where manual cleanup of your code is necessary we have our class file within it and then we have our Dunder method delete currently all this is doing is printing it’s not doing anything very useful right but it is being called now to use it we create our object and we use the python Dell operator Dell object name this Dell operator is the same operator we use when working with dictionaries in deleting objects from dictionaries so you should have seen this operator before that can be used with our Dell Dunder method great here is how that would look by calling Dell on the object it would call the Dell method and in this example it would say deleting file data. text moving on to another new method our add method now this is quite useful especially when working with integers or trying to do anything like that this allows objects of a class to be added together now really look what’s Happening Here we have in it with two properties an X and A Y then we have that special ad method and this special ad method is taking one parameter other you will commonly see this parameter other it’s like a special keyword or a special parameter used by developers it’s just like with a for Loop for I in range I we just use I we like it right so other is the same and that represents an other object we then enter that and we’re checking if other is also an object of the same class so if that instance is the same as my class Vector that’s what that line translates to if our parameter other is the same object or from the same class as we State here then we can do something so if yes we want to add the corresponding X and Y components of the two vectors together new X New Y we’re taking the current x value and we’re adding it to the other object’s x value we can then return a new object with the new values anything else you can raise a type air for the unsupported type of our addition great in result this creates a new object So currently before the program ran we had Vector one vector 2 result is actually going to be Vector 3 right we are adding them together and getting a result this would be the output our new object has the values of six and eight why well remember we added together the values of our objects so six is 2 + 4 8 3 + 5 that is giving us our output of what we’re looking at we are then taking the object and linking the properties X and Y to get our values of six and 8 this is a lot okay if you need to pause pause the video go back to the previous slide as I find that one incredibly helpful this one broken down how I’ve broken this down read that that’s translated to plain English that helps me a lot when learning and I certainly hope that that helps you if we have the addition method we must have a subtraction method we do our subtraction method works the exact same as the add method well not the exact same it works the exact opposite as that method you can see here I have the same codee the only difference is inside here I am subtracting those values and then at the bottom I am also subtracting those values this does the opposite right so my new object is going to be 2 -4 because 7 – 5 is 2 4 – 8 is -4 that’s the value of my new object if I were to print off Vector 1 that gives me 7 and four and if I were to print off my result or res that would give me two and -4 all of these are working the same that’s great this brings us to the final method here and this will be our equal method and I included this one as this is actually quite useful and it allows us to check if two objects are equal imagine if you have 10 different objects from a class just like in our last lesson’s final challenge we created this eCommerce platform store and we had three products what if a store had a hundred products you can see how this method could be used to our advantage we have a class called rectangle and then we have our equal method inside there now equal also takes the other parameter just like with add and subtract and we can check if the objects are from the same class and if this returns true so if the width of my object is equal to the width of the other object and the height of my object is equal to the height of the other object then true it’s equal those objects those rectangles have the same width and the same height it’s going to return true because they’re the same object now check out how I can use that I can print and I can take my object and I can use the equal operator with my second object R1 is equal to R2 that’s true R1 is equal to R3 no that is false python will call this method on the object to its left so this would be called on the R1 cuz R1 is to the left of the equal operator we check if other is also the same object of the same class if yes check if the objects have the same width same height and if that’s true we can return true which results in a true output amazing that wraps up this lesson now before you jump into my videos for vs code you have a wealth of knowledge now as in we started this course objectoriented programming with the introductions of objects the introduction to how to define a class we looked at class inheritance and then multiple class inheritance that brought us all the way to this final lesson of special methods in Python take the next hour take the next 2 hours spend the rest of the day and try to build classes using all the knowledge you’ve gained from this course and try and include a few of these special methods we’ve learned I’ll see you guys in vs [Music] code [Music] great here we are in the first challenge for the introduction of Dunder methods or the special methods for which we use when working with classes diving in I have worded these challenges slightly different in the explanation to make it hopefully EAS easier or just a different strategy for going through the problem if we go through these one by one ideally we should be creating some pretty cool classes with our objects and our Solutions working correctly in this first one we want to create a system for checking the different roles within a company so I’m about to jump in here and I’m just going to Define my Base Class employee with our init and this is going to initialize the name property and employee ID property let’s jump over into our code up top here let’s create our class and I will call this employee employee is tasked with creating the properties of our name and employee ID for each of these we can create those properties then we’re going to use our string method as in what we want to do is when I print off my object I want it to print off the employees name and their ID so I can do that by using the special string method and we can return what do I want to return well I’m going to return a string like employee then right here let’s do some interpolation let’s say our name so employee name very nice all right so that is going to return us the employee name and that employee ID whenever we print off the object itself that’s the advantage to using this string method is we can print an object and it will automatically return or print something back to us great um moving on let’s create a method for to check if something is equal to something else so we know that we’re going to have other and other is that just that special parameter word you could say anything else but you will popularly see the word other in here as a parameter what we want to do is we want to see if two employees share the same employee ID because that’s not possible and speaking of employee ID let me add in my parameter there my value and to do this we are going to say if I’m going to create a condition and we are going to use the is instance function inside here we are going to say is the other person is the other parameter is that also an object from my employee class that’s what we need to check first to make sure I have a object from the same class if that is then we can check if they have the same employee ID if they do I want to return the value true so how can I do that in one line of code I want to return something if it’s true what we can say is if the employee ID is equal to the other object’s employee ID that’s going to be true else if it’s not true we can return false like so so now I can use this to check first is the other object from the same class using the is instance function and then we are going to return true if they share the same employee ID which is impossible that’s not allowed our last method that I want in this uh super class or this class is I want the ad method the ad method can also take an other and well in this case actually I’m going to create this ad method but it’s going to kind of raise an error actually so I’m going to say raise and let’s say uh value errror what do I want to say what do I want to alert the user to EV value err and I just want to say can not add employees right that’s impossible I can’t add to employees because they’re not numbers they’re objects and those objects those properties one of them is a string we can’t do that so I want to raise an error if we try to add those two together and that can be done by using raise the python keyword and then the type of error carrying on I have my employee class now let’s make a class for uh manager and manager is going to inherit and I want you to think about while I’m making in it here what is it going to inherit well the manager they are still an employee that’s not changing right the manager is just the number one employee in that location so the manager is going to have their their own name and their own employee ID as well as which department are they the manager of that’s important let’s activate that super class quickly here and put like that perfect and let’s create our property of department and say that is the value of our parameter great now that we have that all running we are going to do a few things now each method in this challenge they’re all going to be special methods and they’re to show you what we can really do with those and how we can use these special methods to your advantage right so look at what’s happening and think about in your own projects or your own Creations how could you implement these special methods the first special method here I’m going to do is let’s do another string and when this is ran we want to return a few things so I’m going to give back here like a manager name and a manager ID and their department so when this is called let’s return and let’s say name so the name of the manager and then here we can say like that manager has an ID and that manager has a department let’s just say DPT great there we go so I’m returning the manager’s name ID and their Department next up to bat let’s do the same thing so I’m just going to bring these down actually okay we have the ability to check if the same employee ID is shared and check if a manager was added together okay and then finally our last one right we have a staff and the staff can really inherit everything so I’m going to I’m going to take this I’m going to take the manager class and we can just bring that down and put this here I’m going to ch change manager to staff but it’s still going to inherit employee right so each class is ideally doing the same thing but wait until we create our objects to see the interaction between them so a staff is employee now the staff will not really get a department their only difference is going to be a role so what role in the company do they have so let’s change that to role uh uh let’s say Ru here great looking good cannot add let’s say staff members all righty now comes the creation of the objects and what we really want to do with these so first up let’s create some employees let’s say employee one and I’m I’m going to copy this cuz for each let’s create two objects so let’s say I have two employees I have two managers and then I have staff and so we can really see the interaction between these objects so employee they are going to be an object of the employee class and we can just give them let’s say John do let’s say h what is the other employee ID he can be one employee 2 let’s carry on with that and let’s say janeo she is going to be employee two great our managers we can give them the manager class and they also get a name let’s say uh uh Bruce Bruce okay uh they are employee ID let’s say nine and their department is going to be marketing great uh manager two they can be Sarah Jane her employee ID is eight and she’s going to be ahead of sales our two staff let’s say Mark Jones let’s say Mark Jones is 12 and let’s say his role is going to be he’s a mark marketing Ops Dev and then let’s say our other staff member this is going to be Emily Davis and she can be 14 her job is going to be software engineer now let’s use the classes we’ve built and see how we can use these special methods to our advantage so let’s just go through and I’m just going to go through and I’m going to print off a few things so let’s print off employee let’s print off manager one let’s print off uh staff one right so these are just objects but because we’re doing string representation with our special string method we should actually get back some information while I run my code oops okay so let’s go up and fix this line 20 where is line 20 super let’s change this to employee while I’m up here let’s change this to employee all righty trash our terminal run it again great there we are so the three objects I’m printing employee I have the name and the ID number uh the manager is Bruce Bruce id9 Department marketing and then the staff is Mark Jones id2 position marketing op step oh that’s so cool so we are using that new method to print off our objects and now we can actually return that value great let’s carry on so now that I’ve done that let’s check if some of our objects are equal so I know we have employee one and I want to call the equal method on the object to its left which is employee one and I’m going to check if it’s equal equal to employee 2 I can do one more um ideally both of these should return false false very nice okay they are not equal right they are different staff one you can see these three different Arguments for each object they’re different they cannot be equal great um and then finally let’s try and add the managers together right because I did include the add special function and I want to raise an error let’s go down let’s say manager 1 plus manager 2 let’s watch the error get risen raise cannot add well okay if I’m using the ad I should be giving it a parameter even though we won’t do anything with the value of that parameter let’s create it now that we have all three of those let me trash let’s Replay that code great there we are so I’m still given an error right but then we’re given our value air right here right our value air cannot add a manager and that is raising our value air it was risen great that was the interaction we had between three classes we created one super class employee with two sub classes manager and staff each of these classes use the same Three Special methods and we could see the interaction between those as we created and use our objects at the bottom very nicely done I will see you over in our next challenge [Music] Welcome to our next challenge I decided to put a challenge together for you Sports lovers as I don’t tend to do too many sports challenges they tend to be about Finance or travel something about that so here’s a sports challenge using our special methods now we will have three classes each class will be using the same special methods kind of like in the last challenge although instead of using the addition method you will be using the subtraction method we will be creating sports teams in and using two data types as well you’ll be using lists and sets to complete this challenge let’s jump into our code and start going on our super class the first class we want to put together is going to be a generic class for sport right every sport starts with something similar in this case it’s just going to be a name and we can build off that name so let’s start at the Foundation at the basics and let’s just create a place for us to store a name of a sport here so I can create my init and I will create one property called self. name we can return a string if we print a sport object and really all we can return here is just say this is and then I guess the name of the sport self. name looking good let’s actually just create one final special method and let’s do the ADD but I’m going to make it not possible to add one of the objects from the sport class I don’t want that so similar to the last one we can raise a type air and say not possible and then I know in the other ones I’m going to have the subtraction one so let’s just raise an err in this one as I also don’t want this to be possible using our super class sport right so all of these are very Bland very basic right now now we can start to build the other two classes which are going to start to do a few things we are going to have a class called football football is a sport we can inherit that and football has a few of its own details so besides just a name which I need to inherit um it’s also going to have a team right so who is that team and let’s just take our sport class let’s in it and let’s say self name and then create a team property like so when we print an object so I’m going to create a string representation here here we want to return the name of the team and the teams they match with or the teams that they have so how this would look is I could create an FST string and I could say this is we can put ourself name here then what we can say is all righty we can check if they are equal so I’m going to say self we are going to say other do you remember how to check if they’re equal what do we need to check first we need to check if they’re an instance of who other what are we checking if they’re an instance of the football class if that’s true then we can check to see if the values are equal so we can take the name and we can say if the current object’s name is equal equal to the other object’s name and my object’s team is equal to the other objects team that’s going to be true else oh I don’t even need an else let’s just return false great then the last one we’ll do for this one is I included in the task for you to create a subtraction method so let’s use the sub special method and I am going to have the ability to do something here so this is going to take a parameter of other and before we can do anything we need to make sure it’s an instance from the same class so let’s take our other and let’s put in football now when this is called we want to create a list and this list is going to have team names but specifically it’s going to be a set in a list and remember a set is one of the four data types or data structures in Python the other three being list Tes and dictionaries a set is used to store multiple items within a single variable so seeing that a set is unordered you can’t change it and you can’t have duplicate values that makes it useful because we can’t have duplicate teams so let’s create a list here in a way and let’s say uh let’s call this shared teams that seems like it’ll work let’s say it’s a list and then inside the list we’re going to have a set right now the set we’re going to have our self. team and our other set is going to be other team like so I can then check and I can say okay so if I have elements if I have something in my list shared teams then I can do something then I want to create a new object from the football class using the list values I’ve just created so I can return a new football object and the team name I’m going to put a is an F string and I’m going to use the team name as myself. name like so okay that’s working then we can say for our other one let’s just say uh our list of shared teams and to separate I’ll put like two dots great so I’m returning a new object else if that isn’t case let’s return uh the there’s just no common teams no common teams between them all righty and then lastly if that was not true right then we can just uh return let’s say not possible kind reminder there all right looking great I am going to do the same thing here for the basketball class so let’s take this what do we need to change with this class now well let’s change everywhere it says football we are going to give it a new class okay and this can be our basketball class it’s going to do the same thing as the football class it inherits sport it has a team we are checking if the values are equal and we have the ability to add teams as well using our sets all right now that we’ve gotten through all that the last things we should do is let’s play around let’s see what these values are going to return so let’s create let’s just create a very basic one so this is the most basic class this is our super class right this is super basic all right there we are um if I go through right and if I print and I print basic what do you expect to see well we expect to see this is this is super basic all right that makes no sense but if I go up to my super class that’s exactly what I’m returning okay all right so we know that works this is I’m just going to say super basic that’ll just look better we have that let’s create um objects from the other two so let’s say football one football 2 they are both objects of the football class um the name let’s call them well what sport is that the name yeah what sport is it so football okay and then team I’m actually going to make a list here of teams I’m going to hard code this for a second and I’m going to say well let’s take some football teams here let’s say the Giants and let’s say the Dolphins guys I haven’t watched American football in years so don’t judge me on choosing those teams uh okay let’s say uh football let’s say now the teams let’s say the Steelers and let’s say the Eagles there we are so I have the name of the sport and then a list which contains two teams this list is what’s going to be passed through here and subtracted against we can do the same thing for basketball so let’s say basketball one basketball 2 they are both from that basketball class okay we have a name again so as a string I’m giving the sport of basketball okay and then for your teams you can give a list again uh I’m going to say the Jazz and I am going to to say here the Kings okay uh and then oops our other teams let’s say Golden State and let’s say the Rockets brilliant so we have all of those now that we have let’s go through each one and let’s just make sure that they’re giving us some type of information that we’re looking for so printing off our objects to call our string method here we are this is super basic this is football team matched with teams Giants and dolphins seems like it’s working great trash my terminal now let’s try a few of the other special methods so let’s go through and let’s say oh I don’t know let’s print off let’s check if some teams are equal so let’s check if football one equals football 2 let’s check if basketball ball is equal to football what do we think is going to happen here okay let’s give it a check great so it is working both of these are false how could I check if one of them is true let’s think about that right I want to turn one true what would I need to change if we wanted to do that we change change this and we say like team a in both of these and then the other team we can say is going to be Team B now when I run this the equal operator is going to evaluate those and check because we’re passing those in and you can see that it’s true now it’s true because when I go up we are checking if the objects are both from the the same class and we’re checking if the name and the teams are the same so it’s returning true great that brings us to our last ones let’s try our subtraction method so let’s print off and let’s say basketball one minus basketball 2 what can we do here what is the output going to be let’s run it okay so we’re getting no common teams between them right that’s because each of these teams is completely different what if I change Golden State and I now put Kings there we go this is basketball team matched with teams Kings right that I’m subtracting and it found that it’s in both of these great very nicely done on this challenge let’s move on to our next one and I hope the gear are spinning everything we’ve been working with here is slowly coming together you’re doing great we have two more challenges left and I will see you guys in the next [Music] video [Music] welcome back to our next challenge give a read through now in this challenge we’ve done Library as a topic for multiple class inheritance and that really just focused on one product they had books now imagine a company with multiple products we don’t just have books but if you go go to a library at least when I was a kid I could get books or I could even rent movies and DVDs we want to create a few things on how we can handle this together now let’s head over into our code and start on our Base Class our super class item starting in the code let’s create our class item now everything in the system is going to be an item a book or a movie doesn’t matter they’re both items so that’s why I’m creating this super class which will be given to both of those items now we need to give it a title and an author or director Creator so selfname great now that we have those let’s do a very basic return using the string method and let’s just say here what they’re getting so just return and say self. title self. name is by the director or the author great there we are so we have an item now an item is going to have two attributes a title that name and it’ll also have an author great continuing on let’s create our first class which will inherit so we have a book and this book is an item this book is going to have something of its own so it’s not just a title and an author it’s also going to have the number of pages right just like a movie might have the length of the film so slightly different now let’s initialize and let’s say item in it we are going to say self we are going to say title and we are going to say author then let’s say here let’s create a property for the number of pages Pages great now maybe we want to return the length of that book this is a bit strange but let’s return the length of the book based on the string representation of the length let’s just use Len we haven’t used this one yet and let’s say self and let’s say we want to return the length of self. pages right cuz Len you can’t really return the length of a number but let’s watch what happens with this all right so our book is complete let’s create a movie and let’s say a movie is also an item right or technically a movie is not an item so a DVD is let’s say that uh this is going to inherit some stuff now we are going to inherit title that’s going to come from the item class but then a DVD doesn’t have an author it has a director so let’s say director there and let’s say length or duration how long is the film so we have that which means I can take item we can initialize item very quickly and the only thing we’re actually initializing here is we’re going to initialize our title but then I’m also going to initialize director because director and author are kind of like the same thing although it’s not the same name that’s fine I’m still going to take that as the second parameter from my super class so let’s just for now initialize director then the real new property is our duration let’s say that is equal to our duration okay uh what is the length of this movie going to be well let’s use Len let’s say return let’s say self. duration right now that we have that let me clean this up okay looking Grand continuing downward now I’m going to make one final class now really Watch What Happens here so I’m going to create a class and I’m going to say library item Library item is going to inherit it’s going to inherit book and DVD so let’s say that library book is this X book and DVD are those X’s so I have a tree I just made a tree okay now if you look at that everything started with item so this new class library book has access to the class item even though it does not directly inherit Library item only inherits book and DVD but both of those classes inherit item so I’m passing the item class through other classes for which I can use in this class that’s a new level of inheritance all right so in this final class let’s initialize well everything I want access to pretty much everything I want access to my title my author my pages my director my duration uh and then let’s make a new one how many how many copies does the library have available let’s say copies so I’m going to go through and I’m going to say book in it okay now everything coming from book initialize so title author and Pages everything coming from DVD initialize so what’s coming from DVD we have a title as well we have a director this time and then we have a duration great um and then our new one I’m going to say copies is equal to copy iies wow this is a bigger class we’re putting together here so pause the video just take two or three minutes to look through this new class we just made and see how we’re initializing everything and how it’s being passed down through the classes this is a really important fundamental concept here okay this last class all it’s going to have this is going to have a string method and the addition method which we’ll get to here in a second let’s just start with string and let’s say here for string let’s return an F string okay let’s try that so if I return my library item object I should get the title is by this author the book is this long and my DVD is going to be this long or do something else creative how could you use those properties to return something something in the string method finally I want to create and use the ad method now imagine I have a copy of a book like Harry Potter 1 and then I get more copies of another Harry Potter one I want to be able to add those copies together right because it’s the same book and I’m adding them to my library so I’m going to use the ad method to do so so we have other what do we need here so if we need to check is an instance of the same class so if other is from library item okay and my current title of the book is equal to the other title of the book it means they’re a match they’re the same object and they have the same title so for example I’m inheriting book and DD okay so this is making sure that either the titles of two books match or the titles of two DVDs match I cannot add together a book and a DVD they are different right and I can do that because we’re inheriting two different classes all right what I want to do is let’s say combo again and I want to have a combination I want to add together my current copies with the other copies available that’s how I can do that we can then return a new library item object I can return here the title of the object which was the existing title really okay um the author is the existing author the pages it’s still the same number of pages it’s still the same director all the information is still the same the only information that is not the same is the final attribute the number of copies this is increasing to match the variable we’ve just added combo I’m updating the number of copies by creating this new object finally I’m going to throw an else in here and I’m going to rate a type err and I’m just going to say cannot add two different objects together to alert them just like a friendly reminder hey you can’t do that amazing our classes are completed we are ready to move on to create our objects I’m going to go forth here and I’m going to create an object of each I’m going to say book I’m going to say DVD and I’m going to say a library item so I have one from each we can play with so let’s say book for our book let’s just say Harry Potter okay our author we can say JK rolling um and then what else do we need to know here I’m going to say Pages oh I don’t know let’s say 500 so DVD is going to be an object of our DVD class let’s give it the movie Inception that was a good film let’s say the director was Christopher Nolan okay and then the duration of that let’s say in minutes uh let’s say it was an hour and 30 minutes okay great and then our final item is going to be a library item so I’m going to use my library item class now I’m going to do really two things here I need to include so much information so let’s give it a title let’s say python course let’s say I am the author or director let’s say how many pages let’s say 500 it can be a number um I need a director now because I’m creating an object from the library item which is a bit strange okay I’m going to go through real quick and I’m going to print off off each object let’s give a quick test to that okay so I have been given an error ah it’s because I’m using name not title okay so I’m going to say self. name inherit that that makes more sense so I use that in other places should be good okay there we go so I have Harry Potter is by JK rolling Inception is by Christopher Nolan all in all everything is working generally how we want it to work let’s test a few new things out now so let’s print the length of an object now if we did not have the Len function inside our classes like up in here then [Music] great here we are in our next challenge now I’ve done Financial challenges I’ve done things about travel I haven’t done one about about crypto so I had to include that one here what we’re going to be trying to build is a cryptocurrency management system and we’re going to make a main Base Class of crypto and then two child classes of Bitcoin and ethereum to represent those two most popular cryptocurrencies and their properties our code is going to allow users to create new cryptocurrencies compare them add

    them set prices and calculate the value of their portfolio at the end of this you’re going to be creating a mini portfolio and using a dictionary to create objects based on that let’s head over into our code which I can call here and I can just say crypto it’ll be very generic and this is going to be a very generic class I can have in it and in it is just going to take the name of the crypto okay okay so let’s make our property for that we can return a string representation and all we can return for this cuz we don’t have a whole lot of information just yet we can just say this is okay um we can check if the objects are equal to cuz we can’t have the same names right Bitcoin there’s only one Bitcoin there’s only one ethereum so self other and and here we can check if is an instance if what if other is an instance of the crypto class then we can check if the self. name is equal to the others self. name that would return to us true right else we can return false all right we can expand on this in the coming classes I I going to create an add special method here and I want to have the ability to add two crypto names together so keep in mind they’re just strings so not too many errors should happen and I should be allowed to do this but I do need to check if they an instance of the same class still so I can say other I can say what’s my class crypto now now let’s just create a variable called combo and this is going to be the combination of my strings that will be the value so what do I want to do I want to add together my self. name uh I can say plus uh let’s say a space let’s give a space and then we can say other dot name okay looking good then let’s create a new crypto from this combo name so I can return a new object the name will be combo so I can use that to create a new crypto if only if it actually worked like that um else we can’t perform addition so let me just raise and I’m going to raise a value eror and I’m going to say uh canot preform addition between them okay next let’s create a method to set the price so this can take a parameter price and I’m going to create a property right here because I don’t need to define the value when I create my object only when I use this method set price so I can Define it locally inside this method but because I’m using self it’s a key it unlocks it for which I can use throughout my class let’s say I can add my parameter price onto that now let’s say Def and let’s get the price I have a method to add price or set the price now I want to get the price so the first thing I need to do here is before I get the price I need to check if this object has the attribute price so I’m going to first put in here what do I want to check well I want to check myself my object and I want to see if my object has the price property so I’m going to say price if that’s the case let’s just return the price else let’s just say print print off uh price not set looking good and oh how many methods do we have 1 two 3 four five six including in it let’s finish up the super class with one final method and down here let’s create a method and let’s just say uh Cal value I want to calculate the total value of everything and I’m going to be giving it a quantity so how how much of something do I have so I’ll say Quantity and I can say if we have the attribute if I myself has the attribute of a price then what I would like to do is I would like to return the current price times the quantity that I have like so else once again I can just print off and say price not set great so our super class is done that’s built now before we create any objects let’s create just two child classes so let’s create one for Bitcoin and we can give that crypto cuz that is uh for now let me just type pass and I will create one for ethereum and let’s call that also crypto let’s inherit crypto I should say great now the two classes aren’t going to be doing a whole lot so once I do one I’m just going to copy its components but just to give it a bit more functionality for class inheritance using our special methods let’s give in it and oops I have an extra underscore so inside in it it’s not really going to do anything right but we do want to activate crypto and let’s initialize it and let’s just give it a name because I don’t have the property let’s say Bitcoin now when I create a new Bitcoin when I mint a Bitcoin let’s say string and let’s return what can we possibly return you can be creative here put something you’d like just say uh Bitcoin is decentralized okay then let’s create a method called mine and create return statement that just returns something like oops let’s say mining the next block great I’m going to copy this paste this in ethereum just change a few of your attributes right so instead of Bitcoin we can say ethereum ethereum what do we want to say here ethereum uses smart contracts we can say that and and then instead of saying that let’s say minting tokens all right we have our three class is done the really interesting stuff is happening in our super class and then the two children classes just Bitcoin and ethereum a few things here are happening now let’s start playing around with these classes we’ve made so let’s create some objects let’s create uh some crypto objects so let’s say crypto 1 equals class crypto crypto 2 equals crypto class we can say Bitcoin and we will say ether all right so within each of these right uh Bitcoin and ether do not require any arguments because we hardcoded the name inside the init Constructor so our other cryptos we do need to put something here so I will put Solana as a name and then I will put let’s say cardano Okay um there we have two others so Bitcoin eth soul and adaa now you could print off your objects right if I go through and I print off crypto one that’s going to return a string representation of salana right and we can also check and we can check a few things so all of the other ones work the same I can say Bitcoin is Bitcoin equal to crypto 2 actually let’s say crypto 3 let’s put in crypto 3 here and I’ll do two of these so I’m going to copy that so initially let’s say Bitcoin is equal to crypto 3 and then we are going to say Bitcoin is equal to Ether uh crypto 3 is also Bitcoin so running this is going to result in the same so let’s change this here it’s missing one required let’s give it uh self okay and let’s go up to here and we can also give it great there we are so firstly I’m returning a string repres presentation of this because we are printing off crypto one which is salana and then I’m giving true right so Bitcoin equals crypto 3 that’s true because both of those share the same name Bitcoin all righty looking great let’s run a few more tests so let’s just try to add real quick let’s say ether plus crypto2 right I can try and run that I’m going to turn these off for [Music] now all right so you have adding you could have the subtraction special method then we also added some other methods of our own right we made a get price a set price and a cal value why don’t I take my ether object and I say set price so how much is the price of eth at uh I’m going to Ballpark I think it’s at like 1750 so let’s say 17 uh 50 then we can print off right now if I were to print off my ether object and I say get price I should be given this let’s check we’re also adding together ether and crypto too which those that’s not going to work let’s just create a hardcoded property up here and let’s say self. price initially is equal to zero great running that resolve that right so it is giving me 1750 this is ethereum cardano a cryptocurrency so that is US adding together the cryptos right because actually I’m adding together those strings right there all right so everything there is working I’m not going to call every method that we made you guys can play around with that but at the end here let’s try something different let me create a portfolio this portfolio can be a list right but each element in my list is going to be a little dictionary so let me just enter this and let’s say each item each key pair so my first key pair is going to be crypto and it’s going to be let’s say Bitcoin right and then and my second key pair is going to be quantity and I’m going to say an integer so how many do you have let’s say five um and then let’s call the other one let’s pretty much do the same but this time let’s say ether and let’s say Quantity let’s say let’s say 32 if you know you know let’s let’s just add one more in here let’s say uh our last one can be crypto and for this one I think I have crypto one which is salana let’s say Quantity okay and let’s say 25 okay what could [Music] I congratulations and well done in your endeavors in this course I’m so proud of you guys you’ve made it to the end throughout this entire course we have introduced instrumental Concepts in the fundamentals of objectoriented programming in Python we will use these Concepts throughout our entire programming journey and as we begin to introduce more Frameworks and libraries to work together in Python the understandings and the concepts you’ve gained in this course will be key in determining how you do with that thank you so much and I just want to take a moment to say thank you for your purchase as I know it’s a big deal when choosing an online class stay tuned for any future courses I may have cuz they are coming well done and congratulations I’ll see you in our next class together

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Data Science and Machine Learning Foundations

    Data Science and Machine Learning Foundations

    This PDF excerpt details a machine learning foundations course. It covers core concepts like supervised and unsupervised learning, regression and classification models, and essential algorithms. The curriculum also explores practical skills, including Python programming with relevant libraries, natural language processing (NLP), and model evaluation metrics. Several case studies illustrate applying these techniques to various problems, such as house price prediction and customer segmentation. Finally, career advice is offered on navigating the data science job market and building a strong professional portfolio.

    Data Science & Machine Learning Study Guide

    Quiz

    1. How can machine learning improve crop yields for farmers? Machine learning can analyze data to optimize crop yields by monitoring soil health and making decisions about planting, fertilizing, and other practices. This can lead to increased revenue for farmers by improving the efficiency of their operations and reducing costs.
    2. Explain the purpose of the Central Limit Theorem in statistical analysis. The Central Limit Theorem states that the distribution of sample means will approximate a normal distribution as the sample size increases, regardless of the original population distribution. This allows for statistical inference about a population based on sample data.
    3. What is the primary difference between supervised and unsupervised learning? In supervised learning, a model is trained using labeled data to predict outcomes. In unsupervised learning, a model is trained on unlabeled data to find patterns or clusters within the data without a specific target variable.
    4. Name three popular supervised learning algorithms. Three popular supervised learning algorithms are K-Nearest Neighbors (KNN), Decision Trees, and Random Forest. These algorithms are used for both classification and regression tasks.
    5. Explain the concept of “bagging” in machine learning. Bagging, short for bootstrap aggregating, involves training multiple models on different subsets of the training data, and then combining their predictions. This technique reduces variance in predictions and creates a more stable prediction model.
    6. What are two metrics used to evaluate the performance of a regression model? Two metrics used to evaluate regression models include Residual Sum of Squares (RSS) and R-squared. The RSS measures the sum of the squared differences between predicted and actual values, while R-squared quantifies the proportion of variance explained by the model.
    7. Define entropy as it relates to decision trees. In the context of decision trees, entropy measures the impurity or randomness of a data set. A higher entropy value indicates a more mixed class distribution, and decision trees attempt to reduce entropy by splitting data into more pure subsets.
    8. What are dummy variables and why are they used in linear regression? Dummy variables are binary variables (0 or 1) used to represent categorical variables in a regression model. They are used to include categorical data in linear regression without misinterpreting the nature of the categorical variables.
    9. Why is it necessary to split data into training and testing sets? Splitting data into training and testing sets allows for training the model on one subset of data and then evaluating its performance on a different, unseen subset. This prevents overfitting and helps determine how well the model generalizes to new, real-world data.
    10. What is the role of the learning rate in gradient descent? The learning rate (or step size) determines how much the model’s parameters are adjusted during each iteration of gradient descent. A smaller learning rate means smaller steps toward the minimum. A large rate can lead to overshooting or oscillations, and is not the same thing as momentum.

    Answer Key

    1. Machine learning algorithms can analyze data related to crop health and soil conditions to make data-driven recommendations, which allows farmers to optimize their yield and revenue by using resources more effectively.
    2. The Central Limit Theorem is important because it allows data scientists to make inferences about a population by analyzing a sample, and it allows them to understand the distribution of sample means which is a building block to statistical analysis.
    3. Supervised learning uses labeled data with defined inputs and outputs for model training, while unsupervised learning works with unlabeled data to discover structures and patterns without predefined results.
    4. K-Nearest Neighbors, Decision Trees, and Random Forests are some of the most popular supervised learning algorithms. Each can be used for classification or regression problems.
    5. Bagging involves creating multiple training sets using resampling techniques, which allows multiple models to train before their outputs are averaged or voted on. This increases the stability and robustness of the final output.
    6. Residual Sum of Squares (RSS) measures error while R-squared measures goodness of fit.
    7. Entropy in decision trees measures the impurity or disorder of a dataset. The lower the entropy, the more pure the classification for a given subset of data and vice-versa.
    8. Dummy variables are numerical values (0 or 1) that can represent string or categorical variables in an algorithm. This transformation is often required for regression models that are designed to read numerical inputs.
    9. Data should be split into training and test sets to prevent overfitting, train and evaluate the model, and ensure that it can generalize well to real-world data that it has not seen.
    10. The learning rate is the size of the step taken in each iteration of gradient descent, which determines how quickly the algorithm converges towards the local or global minimum of the error function.

    Essay Questions

    1. Discuss the importance of data preprocessing in machine learning projects. What are some common data preprocessing techniques, and why are they necessary?
    2. Compare and contrast the strengths and weaknesses of different types of machine learning algorithms (e.g., supervised vs. unsupervised, linear vs. non-linear, etc.). Provide specific examples to illustrate your points.
    3. Explain the concept of bias and variance in machine learning. How can these issues be addressed when building predictive models?
    4. Describe the process of building a recommendation system, including the key challenges and techniques involved. Consider different data sources and evaluation methods.
    5. Discuss the ethical considerations that data scientists should take into account when working on machine learning projects. How can fairness and transparency be ensured in the development of AI systems?

    Glossary

    • Adam: An optimization algorithm that combines the benefits of AdaGrad and RMSprop, often used for training neural networks.
    • Bagging: A machine learning ensemble method that creates multiple models using random subsets of the training data to reduce variance.
    • Boosting: A machine learning ensemble method that combines weak learners into a strong learner by iteratively focusing on misclassified samples.
    • Central Limit Theorem: A theorem stating that the distribution of sample means approaches a normal distribution as the sample size increases.
    • Classification: A machine learning task that involves predicting the category or class of a given data point.
    • Clustering: An unsupervised learning technique that groups similar data points into clusters.
    • Confidence Interval: A range of values that is likely to contain the true population parameter with a certain level of confidence.
    • Cosine Similarity: A measure of similarity between two non-zero vectors, often used in recommendation systems.
    • DB Scan: A density-based clustering algorithm that identifies clusters based on data point density.
    • Decision Trees: A supervised learning algorithm that uses a tree-like structure to make decisions based on input features.
    • Dummy Variable: A binary variable (0 or 1) used to represent categorical variables in a regression model.
    • Entropy: A measure of disorder or randomness in a dataset, particularly used in decision trees.
    • Feature Engineering: The process of transforming raw data into features that can be used in machine learning models.
    • Gradient Descent: An optimization algorithm used to minimize the error function of a model by iteratively updating parameters.
    • Heteroskedasticity: A condition in which the variance of the error terms in a regression model is not constant across observations.
    • Homoskedasticity: A condition in which the variance of the error terms in a regression model is constant across observations.
    • Hypothesis Testing: A statistical method used to determine whether there is enough evidence to reject a null hypothesis.
    • Inferential Statistics: A branch of statistics that deals with drawing conclusions about a population based on a sample of data.
    • K-Means: A clustering algorithm that partitions data points into a specified number of clusters based on their distance from cluster centers.
    • K-Nearest Neighbors (KNN): A supervised learning algorithm that classifies or predicts data based on the majority class among its nearest neighbors.
    • Law of Large Numbers: A theorem stating that as the sample size increases, the sample mean will converge to the population mean.
    • Linear Discriminant Analysis (LDA): A dimensionality reduction and classification technique that finds linear combinations of features to separate classes.
    • Logarithm: The inverse operation of exponentiation, used to find the exponent required to reach a certain value.
    • Mini-batch Gradient Descent: An optimization method that updates parameters based on a subset of the training data in each iteration.
    • Momentum (in Gradient Descent): A technique used with gradient descent that adds a fraction of the previous parameter update to the current update, which reduces oscillations during the search for local or global minima.
    • Multi-colinearity: A condition in which independent variables in a regression model are highly correlated with each other.
    • Ordinary Least Squares (OLS): A method for estimating the parameters of a linear regression model by minimizing the sum of squared residuals.
    • Overfitting: When a model learns the training data too well and cannot generalize to unseen data.
    • P-value: The probability of obtaining a result as extreme as the observed result, assuming the null hypothesis is true.
    • Random Forest: An ensemble learning method that combines multiple decision trees to make predictions.
    • Regression: A machine learning task that involves predicting a continuous numerical output.
    • Residual: The difference between the actual value of the dependent variable and the value predicted by a regression model.
    • Residual Sum of Squares (RSS): A metric that calculates the sum of the squared differences between the actual and predicted values.
    • RMSprop: An optimization algorithm that adapts the learning rate for each parameter based on the root mean square of past gradients.
    • R-squared (R²): A statistical measure that indicates the proportion of variance in the dependent variable that is explained by the independent variables in a regression model.
    • Standard Deviation: A measure of the amount of variation or dispersion in a set of values.
    • Statistical Significance: A concept that determines if a given finding is likely not due to chance; statistical significance is determined through the calculation of a p-value.
    • Stochastic Gradient Descent (SGD): An optimization algorithm that updates parameters based on a single random sample of the training data in each iteration.
    • Stop Words: Common words in a language that are often removed from text during preprocessing (e.g., “the,” “is,” “a”).
    • Supervised Learning: A type of machine learning where a model is trained using labeled data to make predictions.
    • Unsupervised Learning: A type of machine learning where a model is trained using unlabeled data to discover patterns or clusters.

    AI, Machine Learning, and Data Science Foundations

    Okay, here is a detailed briefing document synthesizing the provided sources.

    Briefing Document: AI, Machine Learning, and Data Science Foundations

    Overview

    This document summarizes key concepts and techniques discussed in the provided material. The sources primarily cover a range of topics, including: foundational mathematical and statistical concepts, various machine learning algorithms, deep learning and generative AI, model evaluation techniques, practical application examples in customer segmentation and sales analysis, and finally optimization methods and concepts related to building a recommendation system. The materials appear to be derived from a course or a set of educational resources aimed at individuals seeking to develop skills in AI, machine learning and data science.

    Key Themes and Ideas

    1. Foundational Mathematics and Statistics
    • Essential Math Concepts: A strong foundation in mathematics is crucial. The materials emphasize the importance of understanding exponents, logarithms, the mathematical constant “e,” and pi. Crucially, understanding how these concepts transform when taking derivatives is critical for many machine learning algorithms. For instance, the material mentions that “you need to know what is logarithm what is logarithm at the base of two what is logarithm at the base of e and then at the base of 10…and how does those transform when it comes to taking derivative of the logarithm taking the derivative of the exponent.”
    • Statistical Foundations: The course emphasizes descriptive and inferential statistics. Descriptive measures include “distance measures” and “variational measures.” Inferential statistics requires an understanding of theories such as the “Central limit theorem” and “the law of large numbers.” There is also the need to grasp “population sample,” “unbiased sample,” “hypothesis testing,” “confidence interval,” and “statistical significance.” The importance is highlighted that “you need to know those Infamous theories such as Central limit theorem the law of uh large numbers uh and how you can um relate to this idea of population sample unbias sample and also u a hypothesis testing confidence interval statistical sign ific an uh and uh how you can test different theories by using uh this idea of statistical”.
    1. Machine Learning Algorithms:
    • Supervised Learning: The course covers various supervised learning algorithms, including:
    • “Linear discriminant analysis” (LDA): Used for classification by combining multiple features to predict outcomes, as shown in the example of predicting movie preferences by combining movie length and genre.
    • “K-Nearest Neighbors” (KNN)
    • “Decision Trees”: Used for both classification and regression tasks.
    • “Random Forests”: An ensemble method that combines multiple decision trees.
    • Boosting Algorithms (e.g. “light GBM, GBM, HG Boost”): Another approach to improve model performance by sequentially training models. The training of these algorithms incorporates “previous stump’s errors.”
    • Unsupervised Learning:“K-Means”: A clustering algorithm for grouping data points. Example is given in customer segmentation by their transaction history, “you can for instance use uh K means uh DB scan hierarchal clustering and then you can evaluate your uh clustering algoritms and then select the one that performs the best”.
    • “DBScan”: A density-based clustering algorithm, noted for its increasing popularity.
    • “Hierarchical Clustering”: Another approach to clustering.
    • Bagging: An ensemble method used to reduce variance and create more stable predictions, exemplified through a weight loss prediction based on “daily calorie intake and workout duration.”
    • AdaBoost: An algorithm where “each stump is made by using the previous stump’s errors”, also used for building prediction models, exemplified with a housing price prediction project.
    1. Deep Learning and Generative AI
    • Optimization Algorithms: The material introduces the need for “Adam W RMS prop” optimization techniques.
    • Generative Models: The course touches upon more advanced topics including “variation Auto encoders” and “large language models.”
    • Natural Language Processing (NLP): It emphasizes the importance of understanding concepts like “n-grams,” “attention mechanisms” (both self-attention and multi-head self-attention), “encoder-decoder architecture of Transformers,” and related algorithms such as “gpts or Birch model.” The sources emphasize “if you want to move towards the NLP side of generative Ai and you want to know how the ched GPT has been invented how the gpts work or the birth mode Ro uh then you will definitely need to uh get into this topic of language model”.
    1. Model Evaluation
    • Regression Metrics: The document introduces “residual sum of squares” (RSS) as a common metric for evaluating linear regression models. The formula for the RSS is explicitly provided: “the RSS or the residual sum of square or the beta is equal to sum of all the squar of y i minus y hat across all I is equal to 1 till n”.
    • Clustering Metrics: The course mentions entropy, and the “Silo score” which is “a measure of the similarity of the data point to its own cluster compared to the other clusters”.
    • Regularization: The use of L2 regularization is mentioned, where “Lambda which is always positive so is always larger than equal zero is the tuning parameter or the penalty” and “the Lambda serves to control the relative impact of the penalty on the regression coefficient estimates.”
    1. Practical Applications and Case Studies:
    • Customer Segmentation: Clustering algorithms (K-means, DBScan) can be used to segment customers based on transaction history.
    • Sales Analysis: The material includes analysis of customer types, “consumer, corporate, and home office”, top spending customers, and sales trends over time. There is a suggestion that “a seasonal Trend” might be apparent if a longer time period is considered.
    • Geographic Sales Mapping: The material includes using maps to visualize sales per state, which is deemed helpful for companies looking to expand into new geographic areas.
    • Housing Price Prediction: A linear regression model is applied to predict house prices using features like median income, average rooms, and proximity to the ocean. An important note is made about the definition of “residual” in this context, with the reminder that “you do not confuse the error with the residual so error can never be observed error you can never calculate and you will never know but what you can do is to predict the error and you can when you predict the error then you get a residual”.
    1. Linear Regression and OLS
    • Regression Model: The document explains that the linear regression model aims to estimate the relationship between independent and dependent variables. In the context, it emphasizes that “beta Z that you see here is not a variable and it’s called intercept or constant something that is unknown so we don’t have that in our data and is one of the parameters of linear regression it’s an unknown number which the linear regression model should estimate”.
    • Ordinary Least Squares (OLS): OLS is a core method to minimize the “sum of squared residuals”. The material states that “the OLS tries to find the line that will minimize its value”.
    • Assumptions: The materials mention an assumption of constant variance (homoscedasticity) for errors, and notes “you can check for this assumption by plotting the residual and see whether there is a funnel like graph”. The importance of using a correct statistical test is also highlighted when considering p values.
    • Dummy Variables: The need to transform categorical features into dummy variables to be used in linear regression models, with the warning that “you always need to drop at least one of the categories” due to the multicolinearity problem. The process of creating dummy variables is outlined: “we will use the uh get uncore d function in Python from pandas in order to uh go from this one variable to uh five different variable per each of this category”.
    • Variable Interpretation: Coefficients in a linear regression model represent the impact of an independent variable on the dependent variable. For example, the material notes, “when we look at the total number of rooms and we increase the number of rooms by uh one additional unit so one more room added to the total underscore rooms then the uh house value uh decreases by minus 2.67”.
    • Model Summary Output: The materials discuss interpreting model output metrics such as R-squared which “is the Matrix that show cases what is the um goodness of fit of your model”. It also mentions how to interpret p values.
    1. Recommendation Systems
    • Feature Engineering: A critical step is identifying and engineering the appropriate features, with the recommendation system based on “data points you use to make decisions about what to recommend”.
    • Text Preprocessing: Text data must be cleaned and preprocessed, including removing “stop words” and vectorizing using TF-IDF or similar methods. An example is given “if we use no pen we use no action pack we use denture once we use movies once you 233 use Inspire once and you re use me once and the rest we don’t use it SWS which means we get the vector 0 0 1 1 1 1 0 0 zero here”.
    • Cosine Similarity: A technique to find similarity between text vectors. The cosine similarity is defined as “an equation of the dot product of two vectors and the multiplication of the magnitudes of the two vectors”.
    • Recommending: The system then recommends items with the highest cosine similarity scores, as mentioned with “we are going to provide we are going to recommend five movies of course you can recommend many or 50 movies that’s completely up to [Music] you”.
    1. Career Advice and Perspective
    • The Importance of a Plan: The material emphasizes the value of creating a career plan and focusing on actionable steps. The advice is “this kind of plan actually make you focus because if you are not focusing on that thing you could just going anywhere at that lose loose loose loose lose your way”.
    • Learning by Doing: The speaker advocates doing smaller projects to prove your abilities, especially as a junior data scientist. As they state, “the best way is like yeah just do the work if like a smaller like as you said previously youly like it might be boring stuff it might be an assum it might be not leading anywhere but those kind of work show”.
    • Business Acumen: Data scientists should focus on how their work provides value to the business, and “data scientist is someone who bring the value to the business and making the decision for the battle any business”.
    • Personal Branding: Building a personal brand is also seen as important, with the recommendation that “having a newsletter and having a LinkedIn following” can help. Technical portfolio sites like “GitHub” are recommended.
    • Data Scientist Skills: The ability to show your thought process and motivation is important in data science interviews. As the speaker notes, “how’s your uh thought process going how’s your what what motivated you to do this kind of project what motivated you to do uh this kind of code what motivated you to present this kinde of result”.
    • Future of Data Science: The future of data science is predicted to become “invaluable to the business”, especially given the current rapid development of AI.
    • Business Fundamentals: The importance of thinking about the needs-based aspect of a business, that it must be something people need or “if my roof was leaking and it’s raining outside and I’m in my house you know and water is pouring on my head I have to fix that whether I’m broke or not you know”.
    • Entrepreneurship: The importance of planning, which was inspired by being a pilot where “pilots don’t take off unless we know where we’re going”.
    • Growth: The experience at GE emphasized that “growing so fast it was doubling in size every three years and that that really informed my thinking about growth”.
    • Mergers and Aquisitions (M&A): The business principle of using debt to buy underpriced assets that can be later sold at a higher multiple for profit.
    1. Optimization
    • Gradient Descent (GD): The update of the weight is equal to the current weight parameter minus the learning rate times the gradient and so “the same we also do for our second parameter which is the bias Factor”.
    • Stochastic Gradient Descent (SGD): HGD is different from GD in that it “uses the gradient from a single data point which is just one observation in order to update our parameters”. This makes it “much faster and computationally much less expensive compared to the GD”.
    • SGD With Momentum: SGD with momentum addresses the disadvantages of the basic SGD algorithm.
    • Mini-Batch Gradient Descent: A trade-off between the two, and “it tries to strike a balance by selecting smaller batches and calculating the gradient over them”.
    • RMSprop: RMSprop is introduced as an algorithm for controlling learning rates, where “for the parameters that will have a small gradients we will be then controlling this and we will be increasing their learning rate to ensure that the gradient will not vanish”.

    Conclusion

    These materials provide a broad introduction to data science, machine learning, and AI. They cover mathematical and statistical foundations, various algorithms (both supervised and unsupervised), deep learning concepts, model evaluation, and provide case studies to illustrate the practical application of such techniques. The inclusion of career advice and reflections makes it a very holistic learning experience. The information is designed to build a foundational understanding and introduce more complex concepts.

    Essential Concepts in Machine Learning

    Frequently Asked Questions

    • What are some real-world applications of machine learning, as discussed in the context of this course? Machine learning has diverse applications, including optimizing crop yields by monitoring soil health, and predicting customer preferences, such as in the entertainment industry as seen with Netflix’s recommendations. It’s also useful in customer segmentation (identifying “good”, “better”, and “best” customers based on transaction history) and creating personalized recommendations (like prioritizing movies based on a user’s preferred genre). Further, machine learning can help companies decide which geographic areas are most promising for their products based on sales data and can help investors identify which features of a house are correlated with its value.
    • What are the core mathematical concepts that are essential for understanding machine learning and data science? A foundational understanding of several mathematical concepts is critical. This includes: the idea of using variables with different exponents (e.g., X, X², X³), understanding logarithms at different bases (base 2, base e, base 10), comprehending the meaning of ‘e’ and ‘Pi’, mastering exponents and logarithms and how they transform when taking derivatives. A fundamental understanding of descriptive (distance measures, variational measures) and inferential statistics (central limit theorem, law of large numbers, population vs. sample, hypothesis testing) is also essential.
    • What specific machine learning algorithms should I be familiar with, and what are their uses? The course highlights the importance of both supervised and unsupervised learning techniques. For supervised learning, you should know linear discriminant analysis (LDA), K-Nearest Neighbors (KNN), decision trees (for both classification and regression), random forests, and boosting algorithms like light GBM, GBM, and XGBoost. For unsupervised learning, understanding K-Means clustering, DBSCAN, and hierarchical clustering is crucial. These algorithms are used in various applications like classification, clustering, and regression.
    • How can I assess the performance of my machine learning models? Several metrics are used to evaluate model performance, depending on the task at hand. For regression models, the residual sum of squares (RSS) is crucial; it measures the difference between predicted and actual values. Metrics like entropy, also the Gini index, and the silhouette score (which measures the similarity of a data point to its own cluster vs. other clusters) are used for evaluating classification and clustering models. Additionally, concepts like the penalty term, used to control impact of model complexity, and the L2 Norm used in regression are highlighted as important for proper evaluation.
    • What is the significance of linear regression and what key concepts should I know? Linear regression is used to model the relationship between a dependent variable (Y) and one or more independent variables (X). A crucial aspect is estimating coefficients (betas) and intercepts which quantify these relationships. It is key to understand concepts like the residuals (differences between predicted and actual values), and how ordinary least squares (OLS) is used to minimize the sum of squared residuals. In understanding linear regression, it is also important not to confuse errors (which are never observed and can’t be calculated) with residuals (which are predictions of errors). It’s also crucial to be aware of assumptions about your errors and their variance.
    • What are dummy variables, and why are they used in modeling? Dummy variables are binary (0 or 1) variables used to represent categorical data in regression models. When transforming categorical variables like ocean proximity (with categories such as near bay, inland, etc.), each category becomes a separate dummy variable. The “1” indicates that a condition is met, and a “0” indicates that it is not. It is essential to drop one of these dummy variables to avoid perfect multicollinearity (where one variable is predictable from other variables) which could cause an OLS violation.
    • What are some of the main ideas behind recommendation systems as discussed in the course? Recommendation systems rely on data points to identify similarities between items to generate personalized results. Text data preprocessing is often done using techniques like tokenization, removing stop words, and stemming to convert data into vectors. Cosine similarity is used to measure the angle between two vector representations. This allows one to calculate how similar different data points (such as movies) are, based on common features (like genre, plot keywords). For example, a movie can be represented as a vector in a high-dimensional space that captures different properties about the movie. This approach enables recommendations based on calculated similarity scores.
    • What key steps and strategies are recommended for aspiring data scientists? The course emphasizes several critical steps. It’s important to start with projects to demonstrate the ability to apply data science skills. This includes going beyond basic technical knowledge and considering the “why” behind projects. A focus on building a personal brand, which can be done through online platforms like LinkedIn, GitHub, and Medium is recommended. Understanding the business value of data science is key, which includes communicating project findings effectively. Also emphasized is creating a career plan and acting responsibly for your career choices. Finally, focusing on a niche or specific sector is recommended to ensure that one’s technical skills match the business needs.

    Fundamentals of Machine Learning

    Machine learning (ML) is a branch of artificial intelligence (AI) that builds models based on data, learns from that data, and makes decisions [1]. ML is used across many industries, including healthcare, finance, entertainment, marketing, and transportation [2-9].

    Key Concepts in Machine Learning:

    • Supervised Learning: Algorithms are trained using labeled data [10]. Examples include regression and classification models [11].
    • Regression: Predicts continuous values, such as house prices [12, 13].
    • Classification: Predicts categorical values, such as whether an email is spam [12, 14].
    • Unsupervised Learning: Algorithms are trained using unlabeled data, and the model must find patterns without guidance [11]. Examples include clustering and outlier detection techniques [12].
    • Semi-Supervised Learning: A combination of supervised and unsupervised learning [15].

    Machine Learning Algorithms:

    • Linear Regression: A statistical or machine learning method used to model the impact of a change in a variable [16, 17]. It can be used for causal analysis and predictive analytics [17].
    • Logistic Regression: Used for classification, especially with binary outcomes [14, 15, 18].
    • K-Nearest Neighbors (KNN): A classification algorithm [19, 20].
    • Decision Trees: Can be used for both classification and regression [19, 21]. They are transparent and handle diverse data, making them useful in various industries [22-25].
    • Random Forest: An ensemble learning method that combines multiple decision trees, suitable for classification and regression [19, 26, 27].
    • Boosting Algorithms: Such as AdaBoost, light GBM, GBM, and XGBoost, build trees using information from previous trees to improve performance [19, 28, 29].
    • K-Means: A clustering algorithm [19, 30].
    • DB Scan: A clustering algorithm that is becoming increasingly popular [19].
    • Hierarchical Clustering: Another clustering technique [19, 30].

    Important Steps in Machine Learning:

    • Data Preparation: This involves splitting data into training and test sets and handling missing values [31-33].
    • Feature Engineering: Identifying and selecting the most relevant data points (features) to be used by the model to generate the most accurate results [34, 35].
    • Model Training: Selecting an appropriate algorithm and training it on the training data [36].
    • Model Evaluation: Assessing model performance using appropriate metrics [37].

    Model Evaluation Metrics:

    • Regression Models:
    • Residual Sum of Squares (RSS) [38].
    • Mean Squared Error (MSE) [38, 39].
    • Root Mean Squared Error (RMSE) [38, 39].
    • Mean Absolute Error (MAE) [38, 39].
    • Classification Models:
    • Accuracy: Proportion of correctly classified instances [40].
    • Precision: Measures the accuracy of positive predictions [40].
    • Recall: Measures the model’s ability to identify all positive instances [40].
    • F1 Score: Combines precision and recall into a single metric [39, 40].

    Bias-Variance Tradeoff:

    • Bias: The inability of a model to capture the true relationship in the data [41]. Complex models tend to have low bias but high variance [41-43].
    • Variance: The sensitivity of a model to changes in the training data [41-43]. Simpler models have low variance but high bias [41-43].
    • Overfitting: Occurs when a model learns the training data too well, including noise [44, 45]. This results in poor performance on unseen data [44].
    • Underfitting: Occurs when a model is too simple to capture the underlying patterns in the data [45].

    Techniques to address overfitting:

    • Reducing model complexity: Using simpler models to reduce the chances of overfitting [46].
    • Cross-validation: Using different subsets of data for training and testing to get a more realistic measure of model performance [46].
    • Early stopping: Monitoring the model performance and stopping the training process when it begins to decrease [47].
    • Regularization techniques: Such as L1 and L2 regularization, helps to prevent overfitting by adding penalty terms that reduce the complexity of the model [48-50].

    Python and Machine Learning:

    • Python is a popular programming language for machine learning because it has a lot of libraries, including:
    • Pandas: For data manipulation and analysis [51].
    • NumPy: For numerical operations [51, 52].
    • Scikit-learn (sklearn): For machine learning algorithms and tools [13, 51-59].
    • SciPy: For scientific computing [51].
    • NLTK: For natural language processing [51].
    • TensorFlow and PyTorch: For deep learning [51, 60, 61].
    • Matplotlib: For data visualization [52, 62, 63].
    • Seaborn: For data visualization [62].

    Natural Language Processing (NLP):

    • NLP is used to process and analyze text data [64, 65].
    • Key steps include: text cleaning (lowercasing, punctuation removal, tokenization, stemming, and lemmatization), and converting text to numerical data with techniques such as TF-IDF, word embeddings, subword embeddings and character embeddings [66-68].
    • NLP is used in applications such as chatbots, virtual assistants, and recommender systems [7, 8, 66].

    Deep Learning:

    • Deep learning is an advanced form of machine learning that uses neural networks with multiple layers [7, 60, 68].
    • Examples include:
    • Recurrent Neural Networks (RNNs) [69, 70].
    • Artificial Neural Networks (ANNs) [69].
    • Convolutional Neural Networks (CNNs) [69, 70].
    • Generative Adversarial Networks (GANs) [69].
    • Transformers [8, 61, 71-74].

    Practical Applications of Machine Learning:

    • Recommender Systems: Suggesting products, movies, or jobs to users [6, 9, 64, 75-77].
    • Predictive Analytics: Using data to forecast future outcomes, such as house prices [13, 17, 78].
    • Fraud Detection: Identifying fraudulent transactions in finance [4, 27, 79].
    • Customer Segmentation: Grouping customers based on their behavior [30, 80].
    • Image Recognition: Classifying images [14, 81, 82].
    • Autonomous Vehicles: Enabling self-driving cars [7].
    • Chatbots and virtual assistants: Providing automated customer support using NLP [8, 18, 83].

    Career Paths in Machine Learning:

    • Machine Learning Researcher: Focuses on developing and testing new machine learning algorithms [84, 85].
    • Machine Learning Engineer: Focuses on implementing and deploying machine learning models [85-87].
    • AI Researcher: Similar to machine learning researcher but focuses on more advanced models like deep learning and generative AI [70, 74, 88].
    • AI Engineer: Similar to machine learning engineer but works with more advanced AI models [70, 74, 88].
    • Data Scientist: A broad role that uses data analysis, statistics, and machine learning to solve business problems [54, 89-93].

    Additional Considerations:

    • It’s important to develop not only technical skills, but also communication skills, business acumen, and the ability to translate business needs into data science problems [91, 94-96].
    • A strong data science portfolio is key for getting into the field [97].
    • Continuous learning is essential to keep up with the latest technology [98, 99].
    • Personal branding can open up many opportunities [100].

    This overview should provide a strong foundation in the fundamentals of machine learning.

    A Comprehensive Guide to Data Science

    Data science is a field that uses data analysis, statistics, and machine learning to solve business problems [1, 2]. It is a broad field with many applications, and it is becoming increasingly important in today’s world [3]. Data science is not just about crunching numbers; it also involves communication, business acumen, and translation skills [4].

    Key Aspects of Data Science:

    • Data Analysis: Examining data to understand patterns and insights [5, 6].
    • Statistics: Applying statistical methods to analyze data, test hypotheses and make inferences [7, 8].
    • Descriptive statistics, which includes measures like mean, median, and standard deviation, helps in summarizing data [8].
    • Inferential statistics, which involves concepts like the central limit theorem and hypothesis testing, help in drawing conclusions about a population based on a sample [9].
    • Probability distributions are also important in understanding machine learning concepts [10].
    • Machine Learning (ML): Using algorithms to build models based on data, learn from it, and make decisions [2, 11-13].
    • Supervised learning involves training algorithms on labeled data for tasks like regression and classification [13-16]. Regression is used to predict continuous values, while classification is used to predict categorical values [13, 17].
    • Unsupervised learning involves training algorithms on unlabeled data to identify patterns, as in clustering and outlier detection [13, 18, 19].
    • Programming: Using programming languages such as Python to implement data science techniques [20]. Python is popular due to its versatility and many libraries [20, 21].
    • Libraries such as Pandas and NumPy are used for data manipulation [22, 23].
    • Scikit-learn is used for implementing machine learning models [22, 24, 25].
    • TensorFlow and PyTorch are used for deep learning [22, 26].
    • Libraries such as Matplotlib and Seaborn are used for data visualization [17, 25, 27, 28].
    • Data Visualization: Representing data through charts, graphs, and other visual formats to communicate insights [25, 27].
    • Business Acumen: Understanding business needs and translating them into data science problems and solutions [4, 29].

    The Data Science Process:

    1. Data Collection: Gathering relevant data from various sources [30].
    2. Data Preparation: Cleaning and preprocessing data, which involves:
    • Handling missing values by removing or imputing them [31, 32].
    • Identifying and removing outliers [32-35].
    • Data wrangling: transforming and cleaning data for analysis [6].
    • Data exploration: using descriptive statistics and data visualization to understand the data [36-39].
    • Data Splitting: Dividing data into training, validation, and test sets [14].
    1. Feature Engineering: Identifying, selecting, and transforming variables [40, 41].
    2. Model Training: Selecting an appropriate algorithm, training it on the training data, and optimizing it with validation data [14].
    3. Model Evaluation: Assessing model performance using relevant metrics on the test data [14, 42].
    4. Deployment and Communication: Communicating results and translating them into actionable insights for stakeholders [43].

    Applications of Data Science:

    • Business and Finance: Customer segmentation, fraud detection, credit risk assessment [44-46].
    • Healthcare: Disease diagnosis, risk prediction, treatment planning [46, 47].
    • Operations Management: Optimizing decision-making using data [44].
    • Engineering: Fault diagnosis [46-48].
    • Biology: Classification of species [47-49].
    • Customer service: Developing troubleshooting guides and chatbots [47-49].
    • Recommender systems are used in entertainment, marketing, and other industries to suggest products or movies to users [30, 50, 51].
    • Predictive Analytics are used to forecast future outcomes [24, 41, 52].

    Key Skills for Data Scientists:

    • Technical Skills: Proficiency in programming languages such as Python and knowledge of relevant libraries. Also expertise in statistics, mathematics, and machine learning [20].
    • Communication Skills: Ability to communicate results to technical and non-technical audiences [4, 43].
    • Business Skills: Understanding business requirements and translating them into data-driven solutions [4, 29].
    • Problem-solving skills: Ability to define, analyze, and solve complex problems [4, 29].

    Career Paths in Data Science:

    • Data Scientist
    • Machine Learning Engineer
    • AI Engineer
    • Data Science Manager
    • NLP Engineer
    • Data Analyst

    Additional Considerations:

    • A strong portfolio demonstrating data science project is essential to showcase practical skills [53-56].
    • Continuous learning is necessary to keep up with the latest technology in the field [57].
    • Personal branding can enhance opportunities in data science [58-61].
    • Data scientists must be able to adapt to the evolving landscape of AI and machine learning [62, 63].

    This information should give a comprehensive overview of the field of data science.

    Artificial Intelligence: Applications Across Industries

    Artificial intelligence (AI) has a wide range of applications across various industries [1, 2]. Machine learning, a branch of AI, is used to build models based on data and learn from this data to make decisions [1].

    Here are some key applications of AI:

    • Healthcare: AI is used in the diagnosis of diseases, including cancer, and for identifying severe effects of illnesses [3]. It also helps with drug discovery, personalized medicine, treatment plans, and improving hospital operations [3, 4]. Additionally, AI helps in predicting the number of patients that a hospital can expect in the emergency room [4].
    • Finance: AI is used for fraud detection in credit card and banking operations [5]. It is also used in trading, combined with quantitative finance, to help traders make decisions about stocks, bonds, and other assets [5].
    • Retail: AI helps in understanding and estimating demand for products, determining the most appropriate warehouses for shipping, and building recommender systems and search engines [5, 6].
    • Marketing: AI is used to understand consumer behavior and target specific groups, which helps reduce marketing costs and increase conversion rates [7, 8].
    • Transportation: AI is used in autonomous vehicles and self-driving cars [8].
    • Natural Language Processing (NLP): AI is behind applications such as chatbots, virtual assistants, and large language models [8, 9]. These tools use text data to answer questions and provide information [9].
    • Smart Home Devices: AI powers smart home devices like Alexa [9].
    • Agriculture: AI is used to estimate weather conditions, predict crop production, monitor soil health, and optimize crop yields [9, 10].
    • Entertainment: AI is used to build recommender systems that suggest movies and other content based on user data. Netflix is a good example of a company that uses AI in this way [10, 11].
    • Customer service: AI powers chatbots that can categorize customer inquiries and provide appropriate responses, reducing wait times and improving support efficiency [12-15].
    • Game playing: AI is used to design AI opponents in games [13, 14, 16].
    • E-commerce: AI is used to provide personalized product recommendations [14, 16].
    • Human Resources: AI helps to identify factors influencing employee retention [16, 17].
    • Fault Diagnosis: AI helps isolate the cause of malfunctions in complex systems by analyzing sensor data [12, 18].
    • Biology: AI is used to categorize species based on characteristics or DNA sequences [12, 15].
    • Remote Sensing: AI is used to analyze satellite imagery and classify land cover types [12, 15].

    In addition to these, AI is also used in many areas of data science, such as customer segmentation [19-21], fraud detection [19-22], credit risk assessment [19-21], and operations management [19, 21, 23, 24].

    Overall, AI is a powerful technology with a wide range of applications that improve efficiency, decision-making, and customer experience in many areas [11].

    Essential Python Libraries for Data Science

    Python libraries are essential tools in data science, machine learning, and AI, providing pre-written functions and modules that streamline complex tasks [1]. Here’s an overview of the key Python libraries mentioned in the sources:

    • Pandas: This library is fundamental for data manipulation and analysis [2, 3]. It provides data structures like DataFrames, which are useful for data wrangling, cleaning, and preprocessing [3, 4]. Pandas is used for tasks such as reading data, handling missing values, identifying outliers, and performing data filtering [3, 5].
    • NumPy: NumPy is a library for numerical computing in Python [2, 3, 6]. It is used for working with arrays and matrices and performing mathematical operations [3, 7]. NumPy is essential for data visualization and other tasks in machine learning [3].
    • Matplotlib: This library is used for creating visualizations like plots, charts, and histograms [6-8]. Specifically, pyplot is a module within Matplotlib used for plotting [9, 10].
    • Seaborn: Seaborn is another data visualization library that is known for creating more appealing visualizations [8, 11].
    • Scikit-learn (psyit learn): This library provides a wide range of machine learning algorithms and tools for tasks like regression, classification, clustering, and model evaluation [2, 6, 10, 12]. It includes modules for model selection, ensemble learning, and metrics [13]. Scikit-learn also includes tools for data preprocessing, such as splitting the data into training and testing sets [14, 15].
    • Statsmodels: This library is used for statistical modeling and econometrics and has capabilities for linear regression [12, 16]. It is particularly useful for causal analysis because it provides detailed statistical summaries of model results [17, 18].
    • NLTK (Natural Language Toolkit): This library is used for natural language processing tasks [2]. It is helpful for text data cleaning, such as tokenization, stemming, lemmatization, and stop word removal [19, 20]. NLTK also assists in text analysis and processing [21].
    • TensorFlow and PyTorch: These are deep learning frameworks used for building and training neural networks and implementing deep learning models [2, 22, 23]. They are essential for advanced machine learning tasks, such as building large language models [2].
    • Pickle: This library is used for serializing and deserializing Python objects, which is useful for saving and loading models and data [24, 25].
    • Requests: This library is used for making HTTP requests, which is useful for fetching data from web APIs, like movie posters [25].

    These libraries facilitate various stages of the data science workflow [26]:

    • Data loading and preparation: Libraries like Pandas and NumPy are used to load, clean, and transform data [2, 26].
    • Data visualization: Libraries like Matplotlib and Seaborn are used to create plots and charts that help to understand data and communicate insights [6-8].
    • Model training and evaluation: Libraries like Scikit-learn and Statsmodels are used to implement machine learning algorithms, train models, and evaluate their performance [2, 12, 26].
    • Deep learning: Frameworks such as TensorFlow and PyTorch are used for building complex neural networks and deep learning models [2, 22].
    • Natural language processing: Libraries such as NLTK are used for processing and analyzing text data [2, 27].

    Mastering these Python libraries is crucial for anyone looking to work in data science, machine learning, or AI [1, 26]. They provide the necessary tools for implementing a wide array of tasks, from basic data analysis to advanced model building [1, 2, 22, 26].

    Machine Learning Model Evaluation

    Model evaluation is a crucial step in the machine learning process that assesses the performance and effectiveness of a trained model [1, 2]. It involves using various metrics to quantify how well the model is performing, which helps to identify whether the model is suitable for its intended purpose and how it can be improved [2-4]. The choice of evaluation metrics depends on the specific type of machine learning problem, such as regression or classification [5].

    Key Concepts in Model Evaluation:

    • Performance Metrics: These are measures used to evaluate how well a model is performing. Different metrics are appropriate for different types of tasks [5, 6].
    • For regression models, common metrics include:
    • Residual Sum of Squares (RSS): Measures the sum of the squares of the differences between the predicted and true values [6-8].
    • Mean Squared Error (MSE): Calculates the average of the squared differences between predicted and true values [6, 7].
    • Root Mean Squared Error (RMSE): The square root of the MSE, which provides a measure of the error in the same units as the target variable [6, 7].
    • Mean Absolute Error (MAE): Calculates the average of the absolute differences between predicted and true values. MAE is less sensitive to outliers compared to MSE [6, 7, 9].
    • For classification models, common metrics include:
    • Accuracy: Measures the proportion of correct predictions made by the model [9, 10].
    • Precision: Measures the proportion of true positive predictions among all positive predictions made by the model [7, 9, 10].
    • Recall: Measures the proportion of true positive predictions among all actual positive instances [7, 9, 11].
    • F1 Score: The harmonic mean of precision and recall, providing a balanced measure of a model’s performance [7, 9].
    • Area Under the Curve (AUC): A metric used when plotting the Receiver Operating Characteristic (ROC) curve to assess the performance of binary classification models [12].
    • Cross-entropy: A loss function used to measure the difference between the predicted and true probability distributions, often used in classification problems [7, 13, 14].
    • Bias and Variance: These concepts are essential for understanding model performance [3, 15].
    • Bias refers to the error introduced by approximating a real-world problem with a simplified model, which can cause the model to underfit the data [3, 4].
    • Variance measures how much the model’s predictions vary for different training data sets; high variance can cause the model to overfit the data [3, 16].
    • Overfitting and Underfitting: These issues can affect model accuracy [17, 18].
    • Overfitting occurs when a model learns the training data too well, including noise, and performs poorly on new, unseen data [17-19].
    • Underfitting occurs when a model is too simple and cannot capture the underlying patterns in the training data [17, 18].
    • Training, Validation, and Test Sets: Data is typically split into three sets [2, 20]:
    • Training Set: Used to train the model.
    • Validation Set: Used to tune model hyperparameters and prevent overfitting.
    • Test Set: Used to evaluate the final model’s performance on unseen data [20-22].
    • Hyperparameter Tuning: Adjusting model parameters to minimize errors and optimize performance, often using the validation set [21, 23, 24].
    • Cross-Validation: A resampling technique that allows the model to be trained and tested on different subsets of the data to assess its generalization ability [7, 25].
    • K-fold cross-validation divides the data into k subsets or folds and iteratively trains and evaluates the model by using each fold as the test set once [7].
    • Leave-one-out cross-validation uses each data point as a test set, training the model on all the remaining data points [7].
    • Early Stopping: A technique where the model’s performance on a validation set is monitored during the training process, and training is stopped when the performance starts to decrease [25, 26].
    • Ensemble Methods: Techniques that combine multiple models to improve performance and reduce overfitting. Some ensemble techniques are decision trees, random forests, and boosting techniques such as Adaboost, Gradient Boosting Machines (GBM), and XGBoost [26]. Bagging is an ensemble technique that reduces variance by training multiple models and averaging the results [27-29].

    Step-by-Step Process for Model Evaluation:

    1. Data Splitting: Divide the data into training, validation, and test sets [2, 20].
    2. Algorithm Selection: Choose an appropriate algorithm based on the problem and data characteristics [24].
    3. Model Training: Train the selected model using the training data [24].
    4. Hyperparameter Tuning: Adjust model parameters using the validation data to minimize errors [21].
    5. Model Evaluation: Evaluate the model’s performance on the test data using chosen metrics [21, 22].
    6. Analysis and Refinement: Analyze the results, make adjustments, and retrain the model if necessary [3, 17, 30].

    Importance of Model Evaluation:

    • Ensures Model Generalization: It helps to ensure that the model performs well on new, unseen data, rather than just memorizing the training data [22].
    • Identifies Model Issues: It helps in detecting issues like overfitting, underfitting, and bias [17-19].
    • Guides Model Improvement: It provides insights into how the model can be improved through hyperparameter tuning, data collection, or algorithm selection [21, 24, 25].
    • Validates Model Reliability: It validates the model’s ability to provide accurate and reliable results [2, 15].

    Additional Notes:

    • Statistical significance is an important concept in model evaluation to ensure that the results are unlikely to have occurred by random chance [31, 32].
    • When evaluating models, it is important to understand the trade-off between model complexity and generalizability [33, 34].
    • It is important to check the assumptions of the model, for example, when using linear regression, it is essential to check assumptions such as linearity, exogeneity, and homoscedasticity [35-39].
    • Different types of machine learning models should be evaluated using appropriate metrics. For example, classification models use metrics like accuracy, precision, recall, and F1 score, while regression models use metrics like MSE, RMSE, and MAE [6, 9].

    By carefully evaluating machine learning models, one can build reliable systems that address real-world problems effectively [2, 3, 40, 41].

    AI Foundations Course – Python, Machine Learning, Deep Learning, Data Science

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Pandas: Data Manipulation, Filtering, Indexing, and Grouping Essentials

    Pandas: Data Manipulation, Filtering, Indexing, and Grouping Essentials

    The source material presents a comprehensive guide to using the Pandas library in Python. It covers fundamental concepts like importing data from various file formats (CSV, text, JSON, Excel) into dataframes. The video provides instruction on cleaning, filtering, sorting, and indexing data. Also, it highlights the group by function, merging dataframes, and creating visualizations. The guide also teaches how to conduct exploratory data analysis, identifying patterns and outliers within a dataset.

    Pandas Data Manipulation: A Comprehensive Study Guide

    I. Quiz

    Answer the following questions in 2-3 sentences each.

    1. What is a Pandas DataFrame, and why is the index important?
    2. Explain how to read a CSV file into a Pandas DataFrame, including handling potential Unicode errors.
    3. Describe how to read a text file into a Pandas DataFrame using read_table and specify a separator.
    4. How can you specify column names when reading a CSV file if the file doesn’t have headers?
    5. Explain how to filter a Pandas DataFrame based on values in a specific column.
    6. Describe the difference between loc and iloc when filtering data in a Pandas DataFrame using the index.
    7. Explain how to sort a Pandas DataFrame by multiple columns, specifying the sorting order for each.
    8. How do you create a MultiIndex in a Pandas DataFrame, and how does it affect data access?
    9. Describe how to group data in a Pandas DataFrame using the groupby function and calculate the mean of each group.
    10. Explain the different types of joins available in Pandas, including inner, outer, left, and right joins.

    II. Answer Key

    1. A Pandas DataFrame is a two-dimensional labeled data structure with columns of potentially different types. The index is crucial because it provides a way to access, filter, and search data within the DataFrame, acting as a label for each row.
    2. To read a CSV file, use pd.read_csv(‘file_path’). To handle Unicode errors, prepend the file path with r (e.g., pd.read_csv(r’file_path’)) to read the path as a raw string, preventing misinterpretation of backslashes.
    3. Use pd.read_table(‘file_path’, sep=’delimiter’) to read a text file into a DataFrame. The sep argument specifies the separator between columns in the text file (e.g., sep=’\t’ for tab-separated).
    4. To specify column names when a CSV lacks headers, use pd.read_csv(‘file_path’, header=None, names=[‘col1’, ‘col2’, …]). This sets header=None to prevent Pandas from using the first row as headers and then assigns names using the names parameter.
    5. To filter by column values, use boolean indexing: df[df[‘column_name’] > value]. This selects rows where the condition inside the brackets is True.
    6. loc filters by label, using the actual index value (string, number, etc.) to select rows and columns. iloc filters by integer position, using the row and column number (starting from 0) to select data.
    7. To sort by multiple columns, use df.sort_values(by=[‘col1’, ‘col2’], ascending=[True, False]). The by argument takes a list of column names, and ascending takes a list of boolean values specifying the sorting order for each column.
    8. A MultiIndex is created using df.set_index([‘col1’, ‘col2’]), creating a hierarchical index. It allows you to select specific values based on either index (using .loc).
    9. Use df.groupby(‘column_name’).mean() to group data by a column and calculate the mean of each group. This groups rows with the same value in ‘column_name’ and computes the mean of the numeric columns for each group.
    • Inner: Returns rows with matching values in both DataFrames.
    • Outer: Returns all rows from both DataFrames, filling in missing values with NaN.
    • Left: Returns all rows from the left DataFrame and matching rows from the right, filling in missing values with NaN.
    • Right: Returns all rows from the right DataFrame and matching rows from the left, filling in missing values with NaN.

    III. Essay Questions

    1. Discuss the importance of data cleaning in the data analysis process, providing specific examples of cleaning techniques relevant to the source material.
    2. Compare and contrast the different methods for filtering and sorting data in Pandas DataFrames, illustrating the use cases for each method.
    3. Explain the concept of indexing in Pandas and how MultiIndexing can be used to organize and access complex datasets.
    4. Describe how you can perform exploratory data analysis using Pandas and relevant libraries, and why it is important.
    5. Explain the concept of joining in Pandas and how different types of joins can be used to combine related data from multiple sources.

    IV. Glossary of Key Terms

    • DataFrame: A two-dimensional labeled data structure in Pandas, similar to a table, with columns of potentially different types.
    • Series: A one-dimensional labeled array in Pandas, capable of holding any data type.
    • Index: A label for each row in a Pandas DataFrame or Series, used for data alignment and selection.
    • MultiIndex: A hierarchical index in Pandas, allowing multiple levels of indexing on a DataFrame.
    • NaN (Not a Number): A standard missing data marker used in Pandas.
    • Filtering: Selecting a subset of rows from a DataFrame based on specified conditions.
    • Sorting: Arranging rows in a DataFrame in a specific order based on the values in one or more columns.
    • Grouping: Aggregating data in a DataFrame based on the values in one or more columns.
    • Joining: Combining data from two or more DataFrames based on a common column or index.
    • Inner Join: Returns rows with matching values in both DataFrames.
    • Outer Join: Returns all rows from both DataFrames, filling in missing values with NaN.
    • Left Join: Returns all rows from the left DataFrame and matching rows from the right, filling in missing values with NaN.
    • Right Join: Returns all rows from the right DataFrame and matching rows from the left, filling in missing values with NaN.
    • Concatenation: Appending or merging DataFrames together, either horizontally or vertically.
    • Aggregation: Computing summary statistics (e.g., mean, sum, count) for groups of data.
    • Exploratory Data Analysis (EDA): An approach to analyzing data sets to summarize their main characteristics, often with visual methods.
    • Unicode Error: An error that occurs when reading a file with characters that are not properly encoded.
    • loc: A Pandas method used to access rows and columns by label.
    • iloc: A Pandas method used to access rows and columns by integer position.
    • Lambda Function: A small anonymous function defined using the lambda keyword.
    • Heatmap: Data visualization that uses a color-coded matrix to represent the correlation between variables.
    • Box Plot: A graphical representation of the distribution of data showing the minimum, first quartile, median, third quartile, and maximum values, as well as outliers.

    Pandas Python Data Analysis Tutorial Series

    Okay, here’s a briefing document summarizing the main themes and ideas from the provided text excerpts, which appear to be transcripts of a series of video tutorials on using the Pandas library in Python for data analysis.

    Briefing Document: Pandas Tutorial Series Overview

    Main Theme:

    This series of tutorials focuses on teaching users how to leverage the Pandas library in Python for various data manipulation, analysis, and visualization tasks. The content covers a range of essential Pandas functionalities, from basic data input and output to more advanced techniques like filtering, grouping, data cleaning, and exploratory data analysis.

    Key Ideas and Concepts:

    1. Introduction to Pandas and DataFrames:
    • Pandas is imported using the alias pd: “we are going to say import and we’re going to say pandas now this will import the Panda’s library but it’s pretty common place to give it an alias and as a standard when using pandas people will say as PD”
    • Data is stored and manipulated within Pandas DataFrames.
    • DataFrames have an index, which is important for filtering and searching: “as you can see right here there’s this index and that’s really important in a data frame it’s really what makes a data frame a data frame and we use index a lot in pandas we’re able to filter on the index search on the index and a lot of other things”
    • The distinction between a Series and a DataFrame is mentioned, suggesting that this will be covered in more detail in a later video.
    1. Data Input/Output:
    • Pandas can read data from various file formats, including CSV, text, JSON, and Excel.
    • The pd.read_csv(), pd.read_table(), pd.read_json(), and pd.read_excel() functions are used to import data.
    • Specifying the file path is crucial. The tutorial demonstrates how to copy the file path: “you have this countries of the world CSV you just need to click on it and right click and copy as path and that’s literally going to copy that file path for us so you don’t have to type it out manually”
    • The R prefix is used when reading files from a filepath to read the string as raw text.
    • The sep parameter allows specifying delimiters for text files: “we need to use a separator and I’ll show you in just a little bit how we can do this in a different way but with that read CSV this is how we can do it we’ll just say sep is equal to we need to do back SLT now let’s try running this and as you can see it now has it broken out into country and region”
    • Headers can be specified or skipped during import using the header parameter.
    • Column names can be manually assigned using the names parameter when the file doesn’t contain headers or when renaming is desired.
    • Imported DataFrames should typically be assigned to a variable (e.g., df) for later use.
    1. Data Inspection:
    • df.info() provides a summary of the DataFrame, including column names, data types, and non-null counts: “we’re going to bring data Frame 2 right down here and we want to take a look at some of this data we want to know a little bit more about it something that you can do is data frame 2. info and we’ll do an open parenthesis and when we run this it’s going to give us a really quick breakdown of a little bit of our data”
    • df.shape returns the number of rows and columns in a DataFrame.
    • df.head(n) displays the first n rows of the DataFrame.
    • df.tail(n) displays the last n rows of the DataFrame.
    • Specific columns can be accessed using bracket notation (e.g., df[‘ColumnName’]).
    • loc and iloc are used for accessing data by label (location) and integer position, respectively.
    1. Filtering and Ordering:
    • DataFrames can be filtered based on column values using comparison operators (e.g., df[‘Rank’] < 10).
    • The isin() function allows filtering based on a list of specific values within a column.
    • The str.contains() function allows filtering for rows where a column contains a specific string.
    • The filter() function can be used to select columns based on a list of items or to filter rows based on index values using the like parameter.
    • sort_values() is used to order DataFrames by one or more columns. Ascending or descending order can be specified.
    • Multiple sorting criteria can be specified by passing a list of column names to sort_values().
    1. Indexing:
    • The index is an important component of a DataFrame and can be customized.
    • The set_index() function allows setting a column as the index. The parameter inplace = True saves this to the existing dataframe.
    • The reset_index() function reverts the index to the default integer index.
    • Multi-indexing allows for hierarchical indexing using multiple columns.
    • sort_index() sorts the DataFrame based on the index.
    • loc and iloc are used for accessing data based on the index. loc uses the string/label of the index, iloc uses the integer position.
    1. Grouping and Aggregating:
    • groupby() groups rows based on the unique values in one or more columns. This creates a GroupBy object.
    • Aggregate functions (e.g., mean(), count(), min(), max(), sum()) can be applied to GroupBy objects to calculate summary statistics for each group.
    • The agg() function allows applying multiple aggregate functions to one or more columns simultaneously using a dictionary to specify the functions for each column.
    • Grouping can be performed on multiple columns to create more granular groupings.
    • The describe() function provides a high-level overview of aggregate functions, which is a shortcut.
    1. Merging and Joining DataFrames:
    • merge() combines DataFrames based on shared columns or indices. It’s analogous to SQL joins.
    • Different types of joins (inner, outer, left, right, cross) can be performed using the how parameter.
    • Suffixes can be specified to differentiate columns with the same name in the merged DataFrame.
    • join() is another function for combining DataFrames, but it can be more complex to use than merge().
    • Cross joins create a Cartesian product of rows from both DataFrames.
    1. Data Visualization:
    • Pandas integrates with Matplotlib for basic plotting.
    • The plot() function creates various types of plots, including line plots, bar plots, scatter plots, histograms, box plots, area plots, and pie charts, based on the kind parameter.
    • subplots=True creates separate subplots for each column.
    • Titles and labels can be added to plots using the title, xlabel, and ylabel parameters.
    • Bar plots can be stacked using stacked=True.
    • scatter() plots require specifying both x and y column names.
    • Histogram bins can be adjusted using the bins parameter.
    • Figure size can be adjusted to increase the visualization’s scale.
    • Matplotlib styles can be used to modify the appearance of plots.
    1. Data Cleaning:
    • Data cleaning involves handling missing values, inconsistencies, and formatting issues.
    • string.strip() removes leading and trailing characters from strings. Lstrip() removes leading characters, and Rstrip() removes trailing characters.
    • string.replace() replaces specific substrings within strings.
    • Regular expressions can be used with string.replace() for more complex pattern matching. The caret (^) can be used to return any character except.
    • apply() applies a function to each element of a column (often used with lambda functions).
    • Data types can be changed using astype().
    • fillna() fills missing values with a specified value.
    • pd.to_datetime() converts columns to datetime objects.
    • drop_duplicates() removes duplicate rows.
    • The inplace=True parameter modifies the DataFrame directly.
    • Columns can be split into multiple columns using string.split() with the expand=True parameter.
    • Boolean columns can be replaced with ‘yes’ and ‘no’ values to standardize responses.
    • isna() or isnull() identifies missing values.
    • drop() removes rows or columns based on labels or indices. The drop = True parameter drops a former index and creates an equivalent new one.
    • dropna() removes rows with missing values.
    1. Exploratory Data Analysis (EDA):
    • EDA involves exploring the data to identify patterns, relationships, and outliers.
    • Libraries: pandas (pd), Seaborn (sns), Matplotlib (plt).
    • info() and describe() provide high-level summaries of the data.
    • The float format can be adjusted via pd.setor_option.
    • isnull().sum() counts missing values in each column.
    • nunique() shows the number of unique values in each column.
    • sort_values() sorts the data based on specific columns.
    • corr() calculates the correlation matrix, showing the relationships between numeric columns.
    • Heatmaps (using Seaborn) visualize the correlation matrix.
    • Grouping (groupby()) and aggregation help understand data distributions and relationships across groups.
    • Transposing DataFrames (transpose()) can be useful for plotting group means.
    • Box plots visualize the distribution of data and identify outliers.
    • select_dtypes() filters columns based on data type.

    Target Audience:

    The tutorial series is designed for individuals who want to learn data analysis and manipulation using Python and the Pandas library, regardless of their prior experience with data science.

    Overall Impression:

    The series appears to be a comprehensive introduction to Pandas, covering a wide range of essential topics in a practical, hands-on manner. The instructor emphasizes best practices, common pitfalls, and useful techniques for working with real-world datasets. The inclusion of practical examples and visual aids helps make the learning process more engaging and effective.

    Pandas DataFrame: Common Operations and FAQs

    Frequently Asked Questions About Pandas Based on Provided Sources

    Here are some frequently asked questions (FAQs) about using the Python Pandas library, based on the provided text excerpts.

    1. How do I import the Pandas library and what is the standard alias?

    To import the Pandas library, you use the statement import pandas. It’s common practice to give it the alias pd, like this: import pandas as pd. This allows you to refer to Pandas functions and objects using the shorter pd. prefix, which is a widely accepted convention in the Pandas community.

    2. How do I read different file types (CSV, text, JSON, Excel) into Pandas DataFrames?

    Pandas provides specific functions for reading various file formats:

    • CSV: pd.read_csv(“file_path.csv”)
    • Text: pd.read_table(“file_path.txt”) (often requires specifying a separator, e.g., sep=”\t” for tab-separated files)
    • JSON: pd.read_json(“file_path.json”)
    • Excel: pd.read_excel(“file_path.xlsx”) (can specify a sheet name using sheet_name=”Sheet1″)

    You typically assign the result of these functions to a variable (e.g., df = pd.read_csv(…)) to create a DataFrame object, making it easier to work with the data later.

    3. What is a Pandas DataFrame and why is the index important?

    A Pandas DataFrame is a two-dimensional labeled data structure with columns of potentially different types. Think of it as a table with rows and columns. The index is a crucial component of a DataFrame; it provides labels for the rows. The index allows you to filter, search, and select data based on these labels. By default, Pandas creates a numerical index (0, 1, 2, …), but you can set a specific column as the index for better data access.

    4. How can I handle Unicode errors when reading files?

    When reading files with backslashes in the file path, you might encounter Unicode errors. To resolve this, prepend r to the file path string to treat it as a raw string. For example: pd.read_csv(r”C:\path\to\file.csv”). This ensures that backslashes are interpreted literally and not as escape characters.

    5. How can I deal with files that don’t have column headers, or if I want to rename headers?

    When reading files, Pandas may automatically infer column names from the first row. You can override this behavior using the header argument. header=None tells Pandas that there are no existing headers, using the first row as data. You can then specify custom column names using the names argument, passing it a list of strings representing the new column names.

    6. How can I filter data within Pandas DataFrames?

    You can filter rows in a DataFrame based on column values using comparison operators (>, <, ==, etc.) or functions:

    • Filtering by Column Value: df[df[“column_name”] > 10] returns rows where the value in “column_name” is greater than 10.
    • Using isin(): df[df[“country”].isin([“Bangladesh”, “Brazil”])] returns rows where the “country” column contains either “Bangladesh” or “Brazil”.
    • Using str.contains(): df[df[“country”].str.contains(“United”)] returns rows where the “country” column contains the string “United”.

    7. How can I sort and order data within Pandas DataFrames?

    Use the sort_values() method to sort a DataFrame by one or more columns. The by argument specifies the column(s) to sort by. ascending=True (default) sorts in ascending order, while ascending=False sorts in descending order. You can sort by multiple columns by providing a list to the by argument. The order of columns in this list determines the sorting priority. You can also specify different ascending/descending orders for different columns by providing a list of boolean values to the ascending argument.

    8. How can I perform groupby aggregations in Pandas?

    The groupby() method groups rows based on unique values in one or more columns. You can then apply aggregate functions (e.g., mean(), count(), min(), max(), sum()) to the grouped data.

    df.groupby(“base_flavor”).mean() # Mean ratings grouped by base flavor

    You can use the agg() method to apply multiple aggregations to different columns simultaneously. The argument to agg() is a dictionary where keys are column names and values are lists of aggregation functions:

    df.groupby(“base_flavor”).agg({“flavor_rating”: [“mean”, “max”, “count”], “texture_rating”: [“mean”, “max”, “count”]})

    Pandas Library: Data Analysis with Python

    The Pandas library in Python is a tool for data analysis, offering data structures like DataFrames and Series.

    Key aspects of Pandas:

    • Alias When importing the Pandas library, it is common to use the alias PD.
    • DataFrames Pandas uses DataFrames, which are different from standard Python. When importing files using Pandas, the data is called in as a data frame. The index is an important component of a data frame, enabling filtering and searching. Assigning a DataFrame to the variable name DF is a common practice.
    • Series The next video in this series will explain what series are.
    • File Reading Pandas can read various file types such as CSV, text, JSON, and Excel. The specific function used depends on the file type (e.g., read_csv, read_table, read_json, read_excel).
    • File Paths File paths can be copied and pasted into the read function. To avoid Unicode errors, raw text reading may be necessary.
    • Arguments When reading files, arguments can be specified, such as the file path or separator.
    • Display Options Pandas allows you to adjust the display settings to show more rows and columns.
    • Data Inspection You can use .info() to get a quick breakdown of the data, .shape to see the dimensions (rows, columns), .head() and .tail() to view the first or last few rows, and column names to select specific columns.
    • Filtering and Ordering DataFrames can be filtered based on column values, specific values, or string content. The isin() function is available to check specific values. Data can be filtered by index using .filter(), .loc[], and .iloc[]. Data can be sorted using .sort_values() and .sort_index().
    • Indexing The index is customizable and allows for searching and filtering. The index can be set using set_index(). Multi-level indexing is supported.
    • Group By Pandas has the group by function to group together the values in a column and display them all on the same row. You can then perform aggregate functions on those groupings. The aggregate function has its own function (aggregate), where a dictionary can be passed through.
    • Merging, Joining, and Concatenating Pandas enables combining DataFrames through merging, joining, and concatenating.
    • Visualizations Pandas allows you to build visualizations such as line plots, scatter plots, bar charts, and histograms.
    • Cleaning Data Pandas is equipped with tools for data cleaning, including removing duplicates (drop_duplicates), dropping unnecessary columns (drop), and handling inconsistencies in data. The .fillna() function fills empty values.
    • Exploratory Data Analysis (EDA) Pandas is used for exploratory data analysis, which involves identifying patterns, understanding relationships, and detecting outliers in a dataset. EDA includes using .info() and .describe() to get a high-level overview of the data. Correlations between columns can be identified using .corr() and visualized with heatmaps.

    Pandas DataFrames: Features, Functionalities, and Data Analysis

    Pandas DataFrames are a central data structure in the Pandas library, crucial for data analysis in Python.

    Key features and functionalities of DataFrames:

    • Definition A data frame is how Pandas calls in data, differing from standard Python.
    • Usual variable name Assigning a DataFrame to the variable name DF is a common practice.
    • Indexing The index is a customizable and important component, enabling filtering and searching. The index can be set using set_index().
    • Filtering and Ordering DataFrames can be filtered based on column values, specific values using isin(), or string content. Data can be filtered by index using .filter(), .loc[], and .iloc[]. Data can be sorted using .sort_values() and .sort_index().
    • Display Options Pandas allows adjusting display settings to show more rows and columns.
    • Data Inspection Tools like .info() provide a breakdown of the data. The .shape shows dimensions. Methods such as .head() and .tail() allow viewing the first or last few rows.
    • Merging, Joining, and Concatenating Pandas enables combining DataFrames through merging, joining, and concatenating.
    • Cleaning Data Pandas is equipped with tools for data cleaning, including removing duplicates (drop_duplicates), dropping unnecessary columns (drop), and handling inconsistencies in data. The .fillna() function fills empty values.
    • Exploratory Data Analysis Pandas is used for exploratory data analysis, including using .info() and .describe() to get a high-level overview of the data. Correlations between columns can be identified using .corr() and visualized with heatmaps.
    • File Reading When reading files using Pandas, the data is called in as a data frame.

    Pandas: Data Import Guide

    Pandas can import data from a variety of file types. When the files are imported using Pandas, the data is read in as a data frame. The specific function used depends on the file type.

    Types of files that Pandas can read:

    • CSV
    • Text
    • JSON
    • Excel

    Functions for reading different file types:

    • read_csv
    • read_table
    • read_json
    • read_excel

    Key considerations when importing files:

    • File Paths The file path needs to be specified, and can be copied and pasted into the read function.
    • Raw Text Reading Raw text reading may be necessary to avoid Unicode errors. To specify raw text reading, use r before the file path.
    • Arguments When reading files, arguments can be specified, such as the file path or separator.
    • Alias When importing the Pandas library, it is common to use the alias PD.
    • Headers The header argument can be used to rename headers or specify that there is no header in the CSV. The default behavior is to infer column names from the first row. You can set header=None if there are no column names, which will cause numerical indexes to be created.
    • Separator When reading in a file, you can specify the separator. When pulling in a CSV, it will automatically assume that the separator is a comma. When importing text files, you may need to specify the separator.
    • Missing Data When merging data, if a value doesn’t have a match, it will return NaN.
    • Sheet names When importing Excel files, you can specify a sheet name to read in a specific sheet, otherwise it will default to the first sheet in the file.

    Filtering Pandas DataFrames

    Pandas DataFrames can be filtered in a variety of ways.

    Filtering Based on Column Values

    • You can filter DataFrames based on the data within their columns. To do this, specify the column to filter on. Comparison operators, such as greater than or less than, can be used.
    • Specific values can be specified.

    Filtering Based on Index

    • You can also filter based off of the index.
    • The main ways to filter by index are the .filter() function and the .loc[] and .iloc[] indexers.

    The .filter() Function

    • With .filter() you can specify which columns to keep by using items = and then listing the columns.
    • By default, .filter() chooses the axis for you, but you can also specify the axis.
    • You can also use like = to specify a string, and it will filter by the indexed values that contain that string.

    The .loc[] and .iloc[] Indexers

    • .loc[] looks at the actual name or value.
    • .iloc[] looks at the integer location.
    • With multi-indexing, .loc[] is able to specify the index, whereas .iloc[] goes based off the initial index, or the integer based index.

    Pandas DataFrame Sorting: Values and Index

    Pandas DataFrames can be ordered using the .sort_values() and .sort_index() functions.

    Sorting by Values (.sort_values())

    • The .sort_values() function allows you to sort a DataFrame based on the values in one or more columns.
    • Specify the column(s) to sort by using the by parameter.
    • Determine the sorting order using the ascending parameter, which can be set to True (ascending) or False (descending). The default is ascending.
    • Multiple columns can be specified for sorting by passing a list of column names to the by parameter. The order of importance in sorting is determined by the order of columns in the list.
    • You can specify different ascending/descending orders for each column when sorting by multiple columns by passing a list of boolean values to the ascending parameter.
    • Example: To sort a DataFrame by the ‘Rank’ column in ascending order: df.sort_values(by=’Rank’, ascending=True).

    Sorting by Index (.sort_index())

    • The .sort_index() function sorts the DataFrame based on its index.
    • You can specify the axis to sort on and whether the order is ascending or not.
    Learn Pandas in Under 3 Hours | Filtering, Joins, Indexing, Data Cleaning, Visualizations

    The Original Text

    what’s going on everybody welcome back to another video today we are going to be learning pandas in under 3 [Music] hours so in this lesson we’re going to cover a ton of things as well as some projects at the very end you’re going to learn how you can read data into pandas and actually store it in a data frame we’ll be filtering quering grouping and a ton of other things just on that data and then we’ll be diving into Data visualization data cleaning exploratory data analysis and a ton more so without further Ado letun them on my screen and get started so the first thing that we need to do is import our pandas Library so we’re going to say import and we’re going to say pandas now this will import the Panda’s library but it’s pretty common place to give it an alias and as a standard when using pandas people will say as PD so this is just a quick Alias that you can use uh that’s what I always use and I’ve always used it because that’s how I learned it and I want to teach it to you the right way so that’s how we’re going to do it in this video so let’s hit shift enter now that that is imported we can start reading in our files now right down here I’m going to open up my file explorer and we have several different types of files in here we have CSV files text files Json files and an Excel worksheet which is a little bit different than a CSV so we’re going to import all of those I’m going to show you how to import it as well as some of the different things that you need to be aware of when you’re importing so we’re going to import some of those different file types and I’ll show you how to do that within pandas so the first thing that we need to say is PD Dot and let’s read it in a CSV because that’s a pretty common one we’ll say read CSV and this is literally all you have to write in order to call that in now it’s not going to call it in as a string like it would in one of our previous videos if you’re just using the regular operating system of python when you’re using pandas it calls it in as a data frame and I’ll talk about some of the nuances of that so let’s go down to our file explorer we have this of the world CSV you just need to click on it and right click and copy as path and that’s literally going to copy that file path for us so you don’t have to type it out manually you can if you’d like and we’re just going to paste it in between these parentheses now if we run it right now it will not work I’ll do that for you it’s saying we have this Unicode error uh basically what’s happening is is it’s reading in these backslashes and this colon and all those backslashes in there and this period at the end what we need to do is read this in as a raw text so we’re just going to say R and now it’s going to read this as a literal string or a literal value and not as you know with all these backslashes which does make a big difference when we run this it’s going to populate our very first data frame so let’s go ahead and run it and now we have this CSV in here with our country and our region now if we go and pull up this file and let’s do that really quickly let’s bring up this countries of the world it automatically populated those headers for us in the data frame but we don’t have any column for those 0 1 2 3 so if we go back as you can see right here there’s this index and that’s really important in a data frame it’s really what makes a data frame a data frame and we use index a lot in pandas we’re able to filter on the index search on the index and a lot of other things which I’ll show you in future videos but this is basically how you read in a file now if we go right up here in between these parentheses and we hit shift tab this is going to come up for us let’s hit this plus button and what this is is these are all the arguments or all the things that we can specify when we’re reading in a file and there are a lot of different options so let’s go ahead and take a look really quickly really quickly I wanted to give a huge shout out to the sponsor of this entire Panda series and that is udemy udemy has some of the best courses at the best prices and it is no exception when it comes to pandas courses if you want to master pandas this is the course that I would recommend it’s going to teach you just about everything you need to know about pandas so huge shout out to yud me for sponsoring this Panda series and let’s get back to the video the first thing is obviously the file path we can specify a separator which there is no default so when we’re pulling in the CSV when we’re reading in the CSV it’s automatically going to assume it’s a comma because it’s a comma separated uh file you can choose delimers headers names index columns and a lot of other things as you can see right here now I will say that I don’t use almost any of these uh the few that I’m going to show you really quickly in just a second are up the very top but you can do a ton of different things and I’m just going to slowly go through them so that’s what those are you can also go down here this is our doc string and you can see exactly how these parameters work it’ll show you and give you a text and walk you through how to do this again most of these you’ll probably never use but things like a separator could actually be useful and things like a header could be useful because it is possible that you want to either rename your headers or you don’t have a header in your CSV and you don’t want it to autop populate that header so that is something that you can specify so for example this header one and I’ll show you how to do this uh the default behaviors to infer that there are column names if no names are passed this behavior is identical to header equals zero so it’s saying that first row or that first index which it’s like right here that zero is going to be read in as a header but we can come right over here and we’ll do comma header is equal to and we can say none and as you can see there are no headers now instead it’s another index so we have indexes on both the x- axis and the Y AIS and so right now we have this zero and one index indicating the First Column and the second column if we want to specify those names we can say the header equals none then we can say names is equal to and we’ll give it a list and so the first one was country and what’s that second one oh region so right here that’s the first um the first row but we’ll rename it and we’ll just say country and region and when we run that we’ve now populated the country and the region uh we’re just pretending that our CSV does not have these values in it and we have to name it ourselves that’s how you do it but let’s get rid of all that because we actually do want those in there so we’re just going to get rid of those and read it in as normal and there we go now typically when you’re reading in a file what you need to do is you want to assign that to a variable almost always when you see any tutorial or anybody online or even when you’re actually working people will say DF is equal to DF stands for data frame again this is a data frame in the next video in the series I’m going to walk through what a series is as well as what a data frame is because that’s pretty important to know when you’re working with these data frames but we’ll assign it to this value and then we’ll say we’ll call it by saying DF and we’ll run it and that’s typically how you’ll do things because you want to save this data frame so later on you can do things like dataframe Dot and you can uh you know pass in different modules but you can’t really do that it’s not as easy to do it if you’re calling this entire CSV and importing it every time so let’s copy this because now we’re going to import a different type of file so now we’ve been doing read CSV but we can also import text files now you can do that with the read CSV we can import text files let’s look at this one we have the same one it’s countries of the world except now it’s a text file because I just converted it for this video I’ll copy that as a path and so now when we do this oops let me get those quotes in there it’ll say world. txt it will still work as you can see this did not import properly um we have this country back SLT region and then all of our values are the exact same with this back SLT that’s because we need to use a separator and I’ll show you in just a little bit how we can do this in a different way but with that read CSV this is how we can do it we’ll just say sep is equal to we need to do back SLT now let’s try running this and as you can see it now has it broken out into country and region we could also do it the more proper way and this is the way you should do it and I’ll get rid of these really quickly but just want to keep them there in case you want to see that but you can also do read table and let’s get rid of this separator and now we have no separators just reading it in as a table let’s run this and it reads it in properly the first time this read table can be used for tons of different data types but typically I’ve been using it for like text files um we can also read in that CSV so let’s change this right here to CSV we can read it in as a CSV but just like we did in the last one when we read in the text file using read CSV this read table to you’re going to need to specify the separator so I’ll just copy this and we’ll say comma and now it reads it in properly again you can use that for a ton of different file types but you just need to specify a few more things if you don’t want to use the more specific read uncore function when you’re using pandas now let’s copy this again we’re going to go right down here and now let’s do Json files Json files usually hold semi-structured data um which is definitely different than and very structured data like a CSV where has columns and rows so let’s go to our file explorer we have this Json sample we will copy this in as path let’s paste it right here and we’ll do reor Json again these different functions were built out specifically for these file types that’s why you know each one has a different name so now we’re reading this in as the Json let’s read it in and it it in properly now let’s go ahead and copy this and take a look at Excel files cuz Excel files are a little bit different than other ones that we’ve looked at um so let’s just do read uncore cell and let’s go down to our file explorer and let’s actually open up this workbook as you can see we have sheet one right here but we also have this world population which has a lot more data let’s say we just wanted to read in sheet one one we can do that or by default it’s going to read in this world population because it’s the first sheet in the Excel file well let’s go ahead and take a look at that let’s get out of here and let’s say oops I forgot to copy the file path let’s go ahead and copy as path and we’ll put it right here and let’s just read it in with no arguments or anything in there or no parameters when we read it in it’s reading in that very first sheet so this is the one that has all of the data now let’s say we wanted to read in that extra sheet name or the second sheet name we’ll just go comma sheet unor name say is equal to and then we can specify sheet was it sheet one like this yes it was so we just had to specify the sheet name right here and then it brought in that sheet instead of the default which is the very first sheet in that Excel now that definitely covers a lot of how you read in those files again you can come in here and hit shift Tab and this plus sign and take a look at all the documentation and you can specify a lot of different things things that I didn’t think were very important for you guys to know especially if you’re just starting out the ones that we looked at today are what I would say are like the ones that I use almost all the time so I wanted to show you those but if you’re interested in any of these other ones or you have very unique data and you need to do that um you know it’s worth really getting in here and figuring things out a few other things that I wanted to show you just in this kind of first video or this intro video on how to read in files um one thing that you may have noticed especially in this file right here is we’re only looking at the first five and then the last five so if we wanted to see all the data all the data is in these like little three dots right here right we want to be able to see that data but right now we can’t and that’s because of some settings that are already within pandas and all we need to do is change that so this one has 234 rows and four columns so obviously we can see all the columns well let’s just change the rows all we’ll say is pd. setor option now what we need to do is we’re going to change the rows we’re not going to change the columns at least not on this one so we’ll say quote display. max. rows now if we just run this for whatever data we bring in it’s going to be able to show the max rows and then we’ll say 235 although this 34 rows I’m just going to be safe let’s run this and now it has changed it so let’s read in this file again and you’ll see how it’s changed now we have all the numbers and we have this little bar on the right that allows us to go down all the way to the bottom and all the way to the top so now we can actually look and kind of skim and see our values I like that better than just having that you know shorter version um we can do the exact same thing on columns as well so if we look at this one this is our Json file has the same thing right here we have what was it 38 columns but we can only see I think it’s it’s 20 or something like that I can’t remember um but we have 38 we can only see like let’s say 15 of them or 20 of them we’ll do the exact same thing and we’ll just say pd. set options. max. columns and we’ll set that to 40 for that one when we run this oops let’s get over here when we run this one again we can now scroll over and see every single one of our columns now that one is a in my opinion a lot more useful I like being able to see every single column so definitely something that you should be using especially when you have these really large files you want to be able to see a lot of the data and a lot of the columns so when you’re slicing and dicing and doing all the things we’re about to learn in this Panda series you know you know what you’re looking at I also want to show you just how to kind of look at your data in these data frames as well so that’s also pretty important so let’s go right down here and the very last one that we imported was this one right here this read Excel so this data frame is the only one that’s going to read in let’s run it um this is the last one to be run so this variable right here DF uh it won’t be applied to all these other ones um which we can always go back and change those typically you’ll do something like data frame two you want to do something like that um so let’s keep data Frame 2 oops so what we’re going to do is we’re going to bring data Frame 2 right down here and we want to take a look at some of this data we want to know a little bit more about it something that you can do is data frame 2. info and we’ll do an open parenthesis and when we run this it’s going to give us a really quick breakdown of a little bit of our data so we have our columns right here rank CCA 3 country and capital it’s saying we have 234 values in those columns because there’s 234 scroll up here because there’s 234 uh rows that tells me that there’s no missing data in here at least not you know completely missing like null values there is something in each of those rows the count tells me it’s non null so there’s no null values and it tells me the data type so it’s ringing in as an integer an object an object and an object and it also tells us how much memory it’s using which is also pretty neat because when you get really really large data types memory usage and and knowing how to work around that stuff does become more important than when you’re working at these really small You Know sample sizes that we’re looking at we can also do oops let me get rid of that can also do data frame two and we’ll do shape and for this one we do not need the parentheses and all this is going to tell us is we have 234 rows and four columns we’re also able to look at uh the first few values or rows in each of these data frames so we can just say dataframe 2. head and if we do that it’s going to give us the first five values but we can specify how many we want we can say head 10 it’ll give us the first 10 rows right here we can do the exact same thing and let’s go right down here and we’ll say tail so they’ll give us the last 10 rows within our data frame now let’s copy this and let’s say we don’t want to actually look at all of these values or all these columns we can specify that by saying df2 and oops let’s get rid of all of this and we’ll say with a quote we’ll say Rank and now we can take just a look at the rank data now we can’t do that by doing the index or at least not like this if we want to use this index that is right here we can but there’s a very special function called L and I look for that and I’m going to have an entire video on this because it does get a little bit more complex but there’s df2 looc and there’s Lo and IO stands for location and I location that’s only for the indexes whether it’s the x axis or the Y AIS those are the indexes and for location it’s looking for the actual text the actual string of the index so if we come up here that data Frame 2 we can specify 224 and it’ll give us this information right here in a little different format so let’s go bracket and we’ll say 224 and when we run this it gives us our rank CCA country capital with our values over here kind of like a dictionary almost now let’s copy this and we’ll say df2 do IO and right now these look the exact same but we haven’t really talked a lot about changing the index and you can change the index to a string or a different column or something like that and we’ll look at that in future videos the iock looks at the integer location so even if these um let’s go right up here even if this index had changed to let’s say this rank or this CCA three or country or whatever you make this index the ILO will still look at the integer location so that 224 would still be 224 even if it was usbekistan so then when we look at this it’s going to be the exact same but if we had changed that Index this Lo is the one that we could search on and we could search whoan is that you spell us beckan hey I nailed it so that is how you use Lo IO again I just wanted to show you a little bit about how you can look at your data frame or search within your data frame hello everybody today we’re going to be looking at filtering and ordering data frames in pandas there are a lot of different ways you can filter and order your data in pandas and I’m going to try to show you all of the main ways that you can do that so let’s kick it off by importing our data set so we’re going to say data frame is equal to and we’ll say pandas and I need to import my andas so we’ll say import andas as PD that’s pretty important I think um so pd. read CSV and we’ll do R and then we’ll say the world population CSV so let’s run this all our data frame right here and this is the data frame that we’re going to be filtering through and ordering in pandas so let’s kick it off the first thing that we can do is filter based off of The Columns so the data within our columns so Asia Europe Africa or whatever data we may have in that column so let’s go right down here we’re going to say DF and then within it we’re going to specify what column we’re going to be filtering on so we’re going to say DF with another bracket and we’ll say rank so we’re going to be looking at this rank column right here and then we’ll say in that rank column we want to do greater than 10 and that’s actually going to be a lot of them let’s do less than so when we run this it’s only going to return these values that are less than 10 we can also do less than or equal to you know all of these um comparison operators so less than or equal to so now we have all of the ranks 1 through 10 now if we look at these countries we can specify by specific values almost exactly like we did here but instead of doing a comparison operator like we did right here and including those names let’s say Bangladesh and Brazil we can use the is in function almost like an in function in SQL if you know SQL so let’s go right down here and we’re going to say specific underscore countries so right now we’re just going to make a list of the countries that we want and then we’ll say Bangladesh and Brazil so let’s go right down here and we’ll say okay for these specific countries from the data frame let’s do our bracket we’ll say in this country column so we’ll do data frame and then another bracket for Country so in this country column we can do do is in and then an open parenthesis and then look for our specific countries so we’re looking at just this column and we’re saying is in so we’re looking at are these values within this column and we’re getting this error and this looks very very odd let me um this doesn’t look right there we go I just had some syntax errors I apologize made it way more complicated than it needs to be but here’s how you use this is in function so we’re looking at Bangladesh and Brazil and we return those rows with Bangladesh and Brazil really quickly I wanted to give a huge shout out to the sponsor of this entire Panda series and that is udemy udemy has some of the best courses at the best prices and it is no exception when it comes to Panda courses if you want to master pandas this is the course that I would recommend it’s going to teach you just about everything you need to know about pandas so huge shout out to you and me for sponsoring this Panda series and let’s get back to the video we can also do a contains function kind of similar to is in in except it’s more like the like in SQL as well I’m comparing a lot of this to SQL cuz when you’re filtering things I always my brain always goes to SQL but in pandas it’s called the contains so let’s do let’s actually copy this because I don’t want to make the same mistake again let’s do that and we’ll do the bracket but instead of dot is in we’re going to do string do contains and then an open parenthesis so we’re going to be looking for a string if it contain if it contains let’s do United almost like United States or or any other United so let’s run this and as you can see we have United Arab Emirates United Kingdom United States United States Virgin Islands so we can kind of search for a specific string or a number or a value within our data or within that column of country now so far we’ve only been looking at how you can filter on these columns we can also filter based off of the index as well and there’s two different ways you can do it or two of the main ways there’s filter and then there’s Lo and IO Lo stands for location and I look stands for integer location and if you’ve seen other previous videos I’ve kind of mentioned those so we can take a quick look at all of those so really quickly we need to set an index because the index right now is uh not the best we’ll set our index to Country so let’s say df2 is equal to D DF do setor index and we’ll say country I’m just doing df2 because later on I want to use that data frame again so I’m just going to assign it to another data frame so that we can just easily switch back and forth so now we have this index as the country and what we can do is use the filter function so let’s go down here we’ll say df2 filter and we’ll do an open parenthesis and now we can specify our items so these these are actually going to be specifying which columns we want to keep so we’re going to say items is equal to then we’ll make a list we’ll say continent hope that’s how we spell continent I’m always messing up with my uh my stuff here my spelling then we’ll do CCA 3 because why not you can specify whichever ones you want when we run this it’s going to only bring in those two columns Now by default it’s choosing the axis for us but we can also specify which axis we want to search on so if we say axis is equal to zero it’s actually going to search this axis this is the zero axis this is the one axis so where our columns are is one so if we go back and do one we’re searching on that one Axis or those header accesses again and this is the default but you can specify that so if you just want to search on uh you know filtering right here you can do that and let’s actually copy this and do that right down here just so you can see what it looks like but let’s let’s search for Zimbabwe and we’ll do Zimbabwe and we’ll be looking at the zero axis which is the up and down on the left hand side and when we filter on that we can filter by Zimbabwe by looking just at the country index we can also use the like just like we did before and I’ll show you the exact same demonstration that we did which you can say like is equal to and instead of having to put in a concrete um text you can just say United just like we did before and we’re searching where the AIS is equal to zero which again is this left-handed access so now we’re looking for United and it’s going to give us all of the countries or all the indexed values that have United in it like we were talking about before we also have Lo and ILO so we can say data frame 2. Loke now this is a specific value so we’ll do United States so location is just looking at the actual name or the value of it not its position so if we search for United States it’s going to give us this right here where it gives us all of the columns for United States and then all of the uh values for United States or we can do the io which is the energer location which is not the exact same because we’re looking at the string for the L we’re looking at this string but underneath it there still is a position that’s that integer location let’s do a completely Rand random one let’s just say three if we look at the third position it’s going to give us ASM which I’m not exactly sure what it is but it still gives us basically the same kind of output which is the columns and the values so that’s another way that you can search within your index when you’re actually trying to filter down that data now let’s go look at the order bu and let’s start with the very first one that we looked at let’s do data frame that’s why I kept it because I wanted to use it later now we can sort and order these values instead of it just being kind of a jumbled mess in here we can sort these columns however we would like ascending descending multiple columns single columns and let’s look at how to do that so we’ll say data frame and then we’ll do data frame look at rank again just like we were doing above and let’s do data frame where it’s less than 10 I should have just gone and copied this I apologize so now we have this data frame that is greater than 10 now we can do dot sort underscore values and this is the function that’s going to allow us to sort everything that we want to sort so we can do buy is equal to and we’ll just order it by the exact same thing that we were doing uh or calling it on we’ll do rank so now what this going to do it’s going to order our rank column and as you can see it did that 1 2 3 4 5 we can also do it with ascending or descending so if you want to you can look in here and see what you can do so we’ll do ascending we’ll say that’s equal to true and so that’s the automatic default so that didn’t change anything but if we say false it’s going to be descending from highest to lowest so now we have it in the opposite direction now we don’t have to just order or sort this on one single column we can do multiple columns and we can do that by making a list right here whoops make a list just like that and we’ll input different ones as well so now let’s input our country and when we run this it will give us rank of 9876 as well as the country of Russia Bangladesh Brazil now if you noticed the country really didn’t change because the rank stayed the exact same that’s because there’s an order of importance here and it starts with the very first one if we change this around and we look at this one and put a com right here now the country is going to to be descended and the rank would come second so it’s not going the rank isn’t going to really have any effect here so now we have the country United States Russia Pakistan and the rank really didn’t get ordered at all now if we want to see how that can actually work let’s do continent right here and actually put it right here and do country here so if we run this it’s first going to come and it’s going to organize or sort the continent then it’s going to come back and go to the country and then it’s going to sort the country so keep so keep your eye right here in this Asia area because we’re going to sort this differently than ascending so we have ascending false and that applies to both of these it’s false and false but we can specify which one we want to do we can do a false here and a true here so we’ll do false comma true and what this is going to do is it’s going to say false for the continent so the continent right here is going to stay the exact same and so that is a lot of how you can filter and order your data within pandas hello everybody today we’re going to be looking at indexing in pandas if you remember from previous videos the index is an object that stores the access labels for all pandas objects the index in a data frame is extremely useful because it’s customizable and you can also search and filter based off of that index in this video we’re going to talk all about indexing how you can change the index and customize that as well as how you can search and filter on that index and then we’re also going to be looking at something a little bit more advanced called multi indexing and you won’t always use it but it’s really good to know in case you come across a data frame that has that in it so let’s get started by importing pandas import pandas as PD now we’ll get our first data frame we’ll say DF is equal to pd. read CSV and I’ve already copied this but we’re going to do R and we’re going to put this file path so I have this world population CSV I will have that in the description just like I do in all of my other videos let’s run DF and let’s take a look at this data frame so we have a lot of information here we have rank country continent population as well as the default index from zero all the way up to 233 now if you haven’t watched any of my previous videos on pandas the index is pretty important and it’s basically just a number or a label for each row it doesn’t even necessarily have to be a unique number um you can create or add an index yourself if you want to and it doesn’t have to be unique but it it really should be unique uh especially if you want to use it appropriately for what we’re doing the country is actually going to be a pretty great index because the country you know is going to be all unique because we’re looking at every single row as a different um country as well as the population so let’s go ahead and create this country or add this country as our index now we can do this in a lot of different ways but the first way that you can do this if you already know what you are going to create that index on is we can just go right in here when we’re reading in this file and we’ll say comma index underscore oops I spelled that completely wrong index underscore column and we’ll say that is equal to and then we’re going to say quote country so we’re taking this country and we’re going to assign it as the index now let’s read this in and as you can see this is our index now it looks a little bit different we didn’t have this country header right here which is specifying that this is still the country but you can you can tell that this is the index based off the um bold letters as well as it being on the far left and all the regular columns for the data is over here while the country header is right here and it’s lower than all the others just a quick way that you can see that that is the index now before we move on I want to show you some other ways that you can do this as well but I’m going to show you how to reverse this index before we move on and we’ll say data frame so we had our data frame right here so we have data frame dot we’ll say reset unor index and then we’ll say in place is equal to True which means we don’t have to assign this to another variable and all that stuff it’ll just be true so now when we run that data frame again the index was reset to the default numbers so now let’s go down here and I’ll show you how to do this in a different way you can do DF do we’ll say setor index and then we’ll just say country so very similar to when we were reading in that file and we said set the index or that index column we said index column equals country if we do this and we run it in it works but if we say data frame right down here it’s not going to save that if we want to save it just like we did above we’re going to say in place is equal to true that is going to save it to where we don’t have to assign it another variable so now when we run this the data frame right here which is going to populate this the data frame is going to say in place is equal to true so that country will now be our index again let’s run this and there we go really quickly I wanted to give a huge shout out to the sponsor of this entire Panda series and that is udemy udemy has some of the best courses at the best prices and it is no exception when it comes to pandas courses if you want to master pandas this is the course that I would recommend it’s going to teach you just about everything you need to know about pandas so huge shout out to you me for sponsoring this Panda series and let’s get back to the video now what’s really great about this index is we’re able to search based off just this index and so we can filter on it and and basically look through our data with it and there are two different ways that you can do that at least this is a very common way that people who use pandas will do to kind of search through that index the first one is called lock and there’s lock and iock that stands for location or integer location let’s look at lock first let’s say DF do loock and then we’ll do a bracket now we’re able to specify the actual string the label so let’s go right up here and let’s say Albania so we’ll say Albania so again this is just looking at the location let’s run this now it’s going to bring up all the Albania data just like here where it’s kind of looks like a colum in a column and we can get this exact same data but using iock right here and when we ran lock we were searching based off Albania which is in the 0 one position so if we actually pull the one position for that integer the ilock we can look at the one position and this should give us the exact same data now let’s take a look at multi- indexing and we’ll come back to a little bit of this in a second so multi- indexing is creating multiple indexes we’re not just going to create the country as the index now we’re going to add an additional index on top of that so let’s pull up our data frame right now we have the country but let’s do dot reset index and we’ll say in place equals true oops oops let’s run it so now we have our data frame now let’s set our index but this time when we set our index we’re going to add the country as the index as well as the continent as an index so we’ll say data frame. setor index then we’ll do a parenthesis and instead of just doing country like we did before we’re going to create a list oops and we’ll do it like that and then we’ll say oops continent and separate by a comma so we have continent and country let’s just say in place is equal to true now when we run this we’re going to have two indexes let’s see what this looks like and let’s run this so now we have country as well as continent as our index now you may notice that these indexes are repeating themselves on this continent index we have Europe right here and Europe right here as well as Asia and Asia and it looks a little bit funky but we are able to sort these values and make they look a lot better so let’s go ahead and try this we’ll do DF do sortore index and when we run this it should sort our index alphabetically and we can also look in here and see what kind of things we can you know specify we can specify the axis but it’s automatically going to be looking at the zero this is zero and this is one so we have two axes within our data frame you choose the level whether it’s ascending or not ascending in place kind string sort remaining all of these different things the only one that I really you know think is worth looking at is the ascending we already know some of these other ones but if we look at ascending let’s run it now it’s sorted these and so now it’s kind of grouped together so we have Africa and all the African ones as well as South America and all the South American ones let’s really quickly say pd. setor option and we’ll say display. max. columns and just like this let’s run it and I need to specify whoops specify right here let’s see how many rows we have 235 so let’s do 235 let’s run this and now when we run this you can see that Africa is all grouped together and all the countries are in alphabetical order under it and then we go all the way down to Asia and again just all in alphabetical order if we wanted to we could say ascending equals true and then when we run this Oh meant to say false and then when we run this it’s the exact opposite so it starts with South America the last one and then goes in reverse alphabetical order we could also say false make it a list and do comma true and just like this and then it would sort this First Column as false and this next column as true so you can really customize it but you know for what we’re doing we don’t need any of that we just need to be able to see this right here so now when we try to search by our index like we did before we did data frame. Loke now when we did that and we said you know let’s say Angola when we specified Angola it’s not going to work properly because it’s searching in this first index for the first string that we have we can search Africa and let’s search for Africa and now we have all of the African countries and if we want to specify to Angola we can also go down another level oops by doing angle Angola and now we have what we were looking at before where we’re calling all the data within those but we couldn’t do it just based off Africa because we had an additional Index right here here so once we called both indexes now we get this view but let’s look at that I look really quick when we run this let’s just say one because right up here oh we have Angola zero and then one so you think it may pull up Angola let’s go ahead and run this and it’s still pulling up Albania let’s go right up here if you remember when we didn’t have the multiple indexes it was pulling up Albania the difference when you’re doing these multi- indexes is that the L is able to specify this whereas this one does not go based off that multi- indexing it’s going to go based off the initial index or the integer based index so that’s a lot about indexing in pandas we’ll cover even a few more things in future videos as we get more and more into pandas but this is a lot of what indexing looks like within pandas and again super important to learn how to do and know how to do because it’s a pretty important building block as we go through this Panda series hello everybody today we’re going to be taking look at the group by function and aggregating within pandas Group by is going to group together the values in a column and display them all on the same row and this allows you to perform aggregate functions on those groupings so let’s start reading in our data and take a look so we’re going to do import pandas as PD and then we’re going to say our data frame is equal equal to and we’ll say pd. read CSV we’ll do an open parenthesis R and our file path and we’re going to be looking at the flavors CSV right here so right here we have our flavor of ice cream we have our base flavor whether it was vanilla or chocolate whether I liked it or not the flavor rating texture rating and its overall or its total rating now these are all my own personal scores so you know I’ve spent years researching this so these are all very accurate but this should be a low stress environment to learn Group by and the aggregate functions so the first thing that we can do is look at our group by now you can’t Group by well you can you can Group by flavor but as you can see these are all unique values what we need is something that has duplicate values or or similar values on different rows that’ll group together so this base flavor is actually a perfect one to group it on and we’ll do that by saying DF do group by do an open parenthesis and we’ll just specify base flavor and this will then group together those values and I need to make sure I can spell properly this will group those flavors together so let’s run this and as you can see it actually is its own object so it has a group by data frame Group by object so now that we’ve grouped them let’s give it a variable so we’ll say group underscore byor frame let’s say that’s equal to Let’s copy this we’ll run it and now what we need to do is run our aggregations in order to get an output so we’re going to say mean and that’s all we’re going to put just for now just to get an output that we can take a look off and then we’ll build from there so let’s go ahead and run this and right here we have our base flavor which is now saying is the index of chocolate or vanilla and then it’s taking the mean or the average of all all the columns that have integers notice that it did not take the liked column and it did not take the flavor column because those are strings and they cannot aggregate those and we’ll take a look at that later but it took all the values that have integers and then it gave us the average of those ratings really quickly I wanted to give a huge shout out to the sponsor of this entire Panda series and that is udemy udemy has some of the best courses at the best prices and it is no exception when it comes to pandas courses if you want to master pandas this is the course that I would recommend it’s going to teach you just about every everything you need to know about pandas so huge shout out to UD me for sponsoring this Panda series and let’s get back to the video so right off the bat as averages with chocolate I have a much higher rating overall than the ones with vanilla bases now we can actually combine all of this together into one line and we can do something like this so we’ll say DF do groupby and we’ll say mean just like this and this will actually run it before we didn’t have any aggregating function on there so didn’t run but now that we combine it all into one it will run properly now there are a lot of different aggregate functions but I’m going to show you some of the most popular ones or the most common ones that you will see so let’s copy this right here so we can do dot count and when we run this we can look at the count and this will show us the actual count of the rows that were aggregated so for chocolate we had three so there going to be three all the way across and for vanilla we had six so we’re looking at a higher count of vanilla which if you’re comparing it to this mean up here that could be a big skew towards the chocolate because if you have one or two good chocolates it could really pull the numbers up whereas if you had two good vanillas but all the other ones were bad it pulls that average down so knowing the count of something is really good let’s take a look at the next one and we can do Min and Max and I’ll just run these really quickly we can do Min and when we run this the first thing that you should notice is that it now has a flavor and a liked column and that’s because Min and Max will actually look at the first letter in the string or the first set of letters if there are um you know chocolate something it’ll look at the first and then it’ll actually populate it so chocolate with the CH chocolate is the very first or the minimum value for that string and for a cake batter that is the minimum value in vanilla as well now with the liked it’s interesting because apparently I liked all the chocolate ones I’m going to go take a look so chocolate I liked chocolate I liked chocolate I like so there is no no option in this liked column so yes was the only option and now let’s look at Max whoops and it should do the exact opposite which is going to take the highest value even if it’s a string so Rocky Road the letter R comes later in the alphabet so that’s what it’s looking at and so does vanilla and then we have yes as well and then of course right here it’s taking the max value so before when we were looking at Min I just focused on those but it still does the exact same thing to these integer um columns as well so for the max value for vanilla it was mint chocolate chip that was our base so I had a rating of 10 for this vanilla row or grouping and then we can also look at the sum and there are all the sums for these and again it only does integer because we can’t add the strings here are the sum or the total values for all of them and for the total values since we had you know six rows that were grouping into this vanilla we now have a lot or much higher score for vanilla now that’s a really simple way to do your aggregations but there is actually an aggregation function and let’s take a look at this because this is um a little bit more complex although when I write it out or show you hopefully it makes a lot of sense we can do a so this is our aggregate function and what we need to pass into our aggregate function is actually a dictionary so let’s do an open parenthesis and we’re going to do a squiggly bracket and then we need to specify what we’re going to be aggregating on or what column so let’s do this flavor rating let’s copy this we’ll do flavor rating and I need to put that as a string and then we’ll do a colon and now we can specify what aggregate functions we want so we’ve done sum count mean Min and Max all of those and we can actually put all of those into here and perform all of those aggregations on just one column so let’s make a list and then let’s say mean Max count and uh what’s another one sum so let’s do all four of those only on this flavor rating column and when we run this we have our base flavor right here chocolate and vanilla but now we don’t have multiple columns we have one column with multiple Columns of our aggregations and it is possible to pass in multiple Colum like that so we’ll do texture rating and we’ll just come right here and do a comma then we’ll say uh uh texture rating and then a colon I don’t know why I spelled it out when I copied it but I did and then we’ll do the exact same ones and now when we run it we’re getting the exact same columns mean Max count and sum for flavor rating then mean Max count and sum for our texture rating now so far we’ve only grouped grouped on one column but we can actually group on multiple columns let’s go back up here to our data and I should have just copy this down here let’s go back down and just look at this so really we only grouped it on this base flavor but you can do multiple groupings or group by multiple columns so let’s do our base flavor which we did already as well as the liked column so we’re going to say DF do group by then we’ll do an open parentheses and then instead of just passing through one string we’re going to do a list and we’ll say base flavor oops comma and then we’ll do liked so now when it groups this it should put two groupings and let’s run this and just see oops I got to say let’s just do mean so now we have our chocolate and a vanilla and remember chocolate only had yes so that’s the only one that it’s going to group on but vanilla had a no and a yes so if we look at the vanilla we have our base flavor vanilla and then within liked we have no and a yes which can show us that within our vanilla when we group on these our NOS were really low but our yeses were really high we actually had a pretty similar rating or very close to the same rating as the ones we really liked in chocolate and just like we did above we can take this doag and I’m going to copy this and it’ll perform it on each of those rows let me close that and what did I do wrong oh I need the squiggly bracket and it’ll show us each of those so the mean Max count and sum for all of the chocolate and vanilla as well as the groupings of light yes and no now after we’ve looked at all that and that’s how I usually do it there is one uh shortcut function that can give you some of these things just really quickly and so let’s go back up here and take this it’s just called describe um and if you’ve ever done it it’s just going to give you some highlevel overview of some of those different aggregations so let’s run this and it’s going to give us our chocolate and vanilla and within each column it’s going to give us our count our mean our standard deviation I believe is what that is our minimum 25% 50 75 and 100 which is our Max then our count and our mean so a lot of those aggregate functions but the describe is you know a very generalized um function we can’t get as specific as we were with the previous ones that we were looking at but I just wanted to throw this out there in case this is something that you’d be interested in because it you know technically is showing a lot of those aggregate functions just you know all at one time hello everybody today we’re going to be talking about merging joining and concatenating data frames in pandas this whole video is basically around being able to combine two separate data frames together into one data frame these are really important to understand when we’re actually using the merge and the join right here we have what’s called an inner join and the Shaded part is what’s going to be returned it’s only the things that are in both the left and the right data frames then we have an outer join or a full outer join and this will take all the data from the left data frame and the right data frame and everything that is similar so basically it just takes everything we also have a left join which is going to take everything from the left and then if there’s anything that’s similar it’ll also include that and then the exact opposite of that is the right join which is going to give us everything from the right data frame and it’s going to give us everything that is similar but it’s not going to give us anything that is just unique to the left data frame so this is just for reference because in a little bit when we start merging these these become very important so I just wanted to kind of show you how that works visually so let’s get started by pulling in our files so first we’re going to say import and is aspd we’ll run this and then we’ll say data frame one and we’ll also have a data frame two and these are the different data frames the left and the right data frame that we’ll be using to join merge and concatenate so we’ll say data frame one is equal to pd. CSV read and we’ll do R and here is our file path so we have this lr. CSV that’s our Lord of the Rings CSV and let’s call that really quickly so we can see what’s in there and I’m having a dyslexic moment uh because it’s supposed to be read CSV uh I apologize for that but this is our data frame this is our data frame one we have three columns it’s their Fellowship ID 101 2 3 and four their first name froto Sam wiise gandal and Pippen and their skills hide and gardening spells and fireworks so this is our very first data frame that we’re going to be working with let’s go down a little bit let’s pull this down here and we’re just going to say data Frame 2 Data frame two and this is the Lord of the Rings 2 so let’s pull this one in now as you can see it’s very similar we have Fellowship ID 1 2 6 7 8 so we have three different IDs here we don’t have six seven and eight in this upper this First Data frame we also have the first name so froto and Sam or Sam wise are in the very first and the second data frame but now we have three new people barir Eland and legalis and now we have this age column which again is unique to just this second data frame first one that I want to look at is merge and I want to look at merge first because I think this one is the most important I use this one more than any of the ones that we’re going to talk about today the merge is just like the joins that we were just looking at the outer the inner the left and the right and there’s also one called cross and I’ll show you that one although if I’m being honest I don’t really use that one that much but it’s worth showing just in case you come into a scenario where you do want to do that so let’s go right down here and I want to be able to see these while we do it so we’re going to say data frame one and when we specify data frame frame one as the very first data frame when we say data frame. merge this is automatically going to be our left data frame then if we do our parenthesis right here and we say data Frame 2 this is our right data frame and let’s see what happens when we do this so what it’s going to do and this we didn’t specify this it’s just a default it’s going to do an inner join so it’s only going to give us an output where specific values or the keys are the same now you can’t see this but what is happening is is it’s taking this Fellowship ID and saying I have 101 here a 102 here this is the exact same as up here with this Fellowship ID and fellowship ID of 101 and 2 but when we look at 13 and 4 those aren’t in this right data frame and 678 is not in this left data frame so the only ones that match are this 101 and2 and that’s why they get pulled in down here but because we didn’t explicit itely say here’s what I want to join or merge between these two data frames it actually is looking at the fellowship ID and the first name so it’s taking in these unique values of froto and Sam wise which are the same in both which is why I pulled it over but really quickly let’s just check and make sure that we did it on the inner join because again we didn’t specify anything that was just the default so we’re going to say how is equal to and then we’ll say enter and if we run this it’s going to be the exact same because again the inner is the default but now just to show you how it’s kind of joining these two uh data frames together I’m going to say on is equal to and then I’m only going to put Fellowship ID so let’s run this now the first thing that you may have noticed is this first name undor X and this first name uncore Y what the merge does as kind of a default is when you are only joining on a fellowship ID we have this right data frame with fellow ship ID the left data frame with the fellowship ID if you’re just joining on these and you’re not joining on the first name and the first name then it’s going to separate those into an underscore X and an underscore Y and even though they have the exact same values since we are not merging on that column it automatically separates that into two separate columns so we can see the values within each of those columns if we went into this on and we make a list and let’s do it like that and we say comma and then we write first name oops first name and then we run this it’s going to look exactly like it did before again it automatically pulled in both of these columns when it was merging at the first time even though we didn’t write anything but if we actually write this it’s doing exactly what it was doing when we just had df2 we’re just now writing it out now there are other arguments that we can pass into this merge function let’s hit shift Tab and let’s scroll down here So within this merge function we have a lot of different arguments you can pass into it first we have this right which is the right data frame which is this data frame two then we have the how and the on which we’ve already shown how to do there’s a left on right on left Index right index not something you’ll probably use that much but you definitely can if you want to look into that and there’s all these doc strings which show you exactly how to use all of these so if you’re interested in looking at the left and the right and the left index it’s all in here but one that is really good is the sort and you can sort it saying either it’s false or true then we have these suffixes now if you remember when we took these out what it automatically did was it put in these underscore X andore Y you can customize that and you can put in whatever you’d like instead of the underscore X andore Y you can put in some custom um string for that we also have an indicator and a validates again all things that you can go in here and look at I’m just going to show you the stuff that I use the most so these things right here are things that I definitely use the most so now that we’ve looked at the inner join let’s copy this right down here and let’s look at the outer join and these get a little bit more tricky I think the inner join is probably the easiest one to understand let’s look at the outer this spelled o u t r i I don’t know why I always want to say o u t t r but let’s run this and see what we get so now this looks quite different the inner join only gave us the values that are the exact same this one is going to give us all of the values regardless of if they are the same so we have 1 2 3 4 six seven and eight so let’s scroll back up here so we have 1 2 3 4 1 2 and 6 7 and 8 so we don’t have a 105 and then if you notice in this data frame right here if the value doesn’t have so if we can’t join on the fellowship ID or the first name like legalis wasn’t one that we joined on or that has a similar value in the left data frame it just gives us an Nan which is not a number and it’s going to do that for any value where it couldn’t find that join or it couldn’t match uh something within that either ID or first name so in age we also have that for the ones that weren’t in the right data frame we only had 101 and 102 so we’ll have the age for both Frodo and Sam but for Gandalf and Pippen we don’t have their corresonding IDs and so it’s just going to be blank for Gandalf and Pippen and you can see that right here so again outer joins are kind of the opposite of inner joins they’re going to return everything from both if there is overlapping data it won’t be duplicated now let’s go on to the left join and I’m going to pull this down right here and now we’re just going to say how is equal to left and let’s run this so what this is going to do is it’s going to take everything from from the left table or the left data frame right here so everything from data frame one then if there is any overlap it’ll also pull the overlapped or the you know whatever we’re able to merge on from data frame two so let’s go back up to our data frame one and two so it’s going to pull everything from this left data frame because we’re specifying we’re doing a left join so everything from the left data frame will be in there we’re also going to try to bring in everything from the right but only if it matches or or is able to merge so just this information right here will come over we weren’t able to join on 1006 1007 or 1008 so really none of that information is going to come over so let’s go down and check on this so again we have 1 2 3 4 all of the data with this first name and skills everything is in here but then we are trying to bring over the age but we only have matches with 1,1 and 10002 so only these two values will come in let’s look at the right join CU it’s basically the exact opposite let’s look at the right and this is basically the exact opposite of the left in the fact that now we’re only looking at the right hand and then if there’s something that matches in data frame one then we will pull that in so this is basically just looking like data Frame 2 except we’re pulling in that skills column and since only 1 And1 and 102 are the same that’s why the skills values are here now those are the main types of merges that I will use when I’m using a data frame or when I’m trying to merge a data frame but there also is one called a cross or a cross join uh and let’s look at this one and this one is quite a bit different here we go let’s run this so this one is different in that it takes each value from the left data frame and Compares it to each value in the right data frame so for froto in this left data frame it looks at the froto in the right data frame Sam wise in the right data frame legalis elron and baromir all in the right data frame then it goes to the next value Sam wise does the exact same thing Roto Sam wise legalis Elon baromir and it does that for every single value so let’s go right back up here so it’s taking this this 101 it’s comparing it to 1 2 3 4 5 then it’s taking Sam Wise It’s comparing it to one two 3 4 five Gandalf 1 two 3 four five Pippen and then you kind of see that pattern and that’s what a cross join is um there are very few in my opinion reasons for a cross join although you’ll if you ever do like an interview where you’re being interviewed on python you will sometimes be asked on Cross joins but there aren’t a lot of instances in actual work where you really use or need a cross join now let’s take a look at joins and joins are pretty similar to the merge function and it can do a lot of the same thing except in my opinion the join function isn’t as easily understood as the merge function it’s a little bit more complicated um but let’s take a look and see how we can join together these data frames using the join function so let’s go right up here we’re going to say data frame one. join and then we’ll do data Frame 2 very similar to how we did it before and let’s try running this and it’s not going to work um when we did the merge function it had a lot of defaults for us let’s go down and see what this error is it says the columns overlap but no suffix was specified so it’s telling us that it’s trying to use the fellowship ID and the first name just like the join did except it’s not able to distinguish which is which and so we need to go in there and kind of help it out a little bit again a little bit more Hands-On than the merge let’s see what we can do to make this work let’s do comma and we’ll say on and let’s really quickly let’s open this up and kind of see what we have so this one has less options than the merge does we have other and that’s our other data frame we can do on and we’re going to specify you know what column do we want to join on and then we can look at how do we want it to be a left an inner and outer the same kind of types of joins as the merge then we have that left suffix right suffix and that’s right here is kind of part of the issue that we were just facing is that those columns are the same but if we say left suffix it’ll give us an underscore whatever we want to specify any string four columns that are both in the left and the right we can give it a unique name so it we’ll no longer have that issue and then we can also sort it like we did on the other one but anyways let’s go back to our on we’ll say on is equal to and then we’ll say Fellowship ID let’s try running this and we’re still getting an error it’s just not as simple as the merge so let’s keep going so now let’s specify the type so we’ll say how is equal to and we’ll do an outer and if we run this it still doesn’t work we’re still getting the exact same issue as the left suffix and the right suffix so now let’s finally resolve it I just wanted to show you how a little bit more frustrating it was but now let’s say uh L suffix is equal to and now it automatically when we did the merge did an underscore X but we can do let’s do underscore left and then we can do a comma we’ll do right suffix and we’ll say it’s equal to and we’ll do underscore right now when we run this it should work properly let’s run this so this is our output and obviously looks quite a bit different over here we have this Fellowship ID then we also have Fellowship ID left first name left Fellowship ID right and first name right so it just doesn’t look right now something I didn’t specify when I first started this because I kind of wanted to show you is that the join usually is better for when you’re working with indexes before when we were using the merge We Were Us using the column names and that worked really well and it was pretty easy to do but as you can see right here when we’re trying to use these column names it’s not working exceptionally well let’s go ahead and create our index and then I can show you how this actually works and how it works a little bit better when we’re working with just the index although you can get it to work just the same as the merge it’s just a lot more work so let’s go right down here and let’s go and say df4 so we’ll create a new data frame we’ll say df1 do set _ index and we’ll do an open parenthesis and we’ll say we want to do this index on the fellowship ID and then we’re going to do the join so now we’re going to say join so we’re setting an index so we’re setting that index on the fellowship ID now we’re going to join it on df2 do setor index and then we’re also going to do that on the fellowship ID and I’ll just copy this oh jeez I hate it when I do that okay now we also want to do and specify the left and the right index so I’ll just copy this as we do need to specify this now let’s try running the data frame four so really quickly just to recap we were setting the indexes we were doing the same thing above right we have this join we were joining data frame one with data Frame 2 now we’re joining data frame one with data frame two except in both instances we’re setting the index as Fellowship ID so we’re joining now on that index so now let’s run this and this should look a lot more similar to the merge than the join that we did above except now the fellowship ID right here is actually an index so it’s just a little bit different but we can still go in here and do how is equal to Outer oops let’s say outer so we can still specify our different types of joins or the different way that we can merge or join these data frames together we can still specify that again it’s just a little bit different and that’s why for most instances I’m using that merge function because it’s just a little bit more seamless little bit more intuitive the join function can still get the job done but as you can see it takes a little bit more work now let’s look at concatenate concatenating data frames can be really useful and the distinction between a merge and join versus the concatenate is that the concatenate is kind of like putting one data frame on top of the other rather than putting one data frame next to one another which is like the merge and the join so concatenating them is just a little bit different in how it’ll operate but let’s actually write this out and see how this looks let’s go up here and we’ll say pd. concat we’ll do an open parenthesis and then we’re going to concatenate data frame one comma data Frame 2 that’s all we have to write and let’s run this and so just like I said it literally took the First Data frame 1 2 3 4 and put it on top of the right data frame 1 2 6 7 8 so that is our left data frame this is our right data frame and they’re literally just sitting one on top of the other but just like when we merge either with a left or a right when you have these skills and there aren’t any values that populate for them it is going to say not a number and since we’re not actually joining we’re not joining on one and two even though this one and this one is the same rows it’s not populating that value because again we’re not joining these together we’re just concatenating and putting one on top of the other now if we go into this concat we say shift tab there are a lot of different things that we can do which if you remember the zero axis is the left-and index and the axis of one is the top index which is the columns so you can specify that and we can also do joins and this is the one that I’m going to take a look at but there are other ones that you can um look into as well but let’s look at join let’s do comma and we’ll say join is equal to and let’s do an inner join so let’s see what happens with this as you can see it is only taking the columns that are the same that’s what this inner is doing it’s joining these columns together and the ones that were different they didn’t take because again we weren’t able to combine them they aren’t similar between both data frames Let’s do an outer and now it’s going to take all of them and like I said that’s doing this on these colums right here but we can also do it on this axis as well so let’s go ahead and say a is equal to 1 and when we run this now it’s joining us on this Index right here of 0 1 2 3 4 so now these ones are being joined together and it’s putting it side by side much like a merge would so that’s how concatenate works and I’m going to show you one more thing and again it’s not up here in this you know title because it’s not one that I recommend but is one called append the append function is used to append rows from one data frame to the end of another data frame and then we can return that new data frame and so let’s do data frame 1. append do an open parenthesis and we’ll say data Frame 2 very similar to how we’ve been doing other things and let’s run this and as you can see this is almost exactly like how the concatenate did when we first did it but if we read kind of this warning it’s saying the frame. append method is deprecated and will be removed from pandas in the future version use pandas do canat instead so it’s literally warning us you know a pend is on its way out if you want to do exactly what you’re doing right here go and try concat or concatenate because that’ll do the exact same thing so I’m not really going to show you any other variations of a pend because there’s no reason it’s going to be on its way out in the next version so that is our video on merge join and concatenate and aend as well uh in pandas and I hope that that was helpful I hope that you learned something I mean this stuff is really important because often times you’re not just working with one CSV or one Json or one text file you’re working with multiple of them and you need to combine them all into one data frame and so this is a really really important concept and thing to understand hello everybody today we’re going to be building visualizations in pandas in this video we’ll look at how we can build visualizations like line plots Scatter Plots bar charts histograms and more I’ll also show you some of the ways that you can customize these visualizations to make them just a little bit better with that being said let’s go right over here start importing our libraries and we’ll start with importing pandas SPD and this one is really all you need to actually create the visualizations in pandas but we may get a little bit crazy uh and so we’re going to do a few different ones as well like import numpy as NP and then we’re going to do import matplot li. pyplot as PLT now I may or may not use this I just you know when I get into visualizations I may want to change some different things so we’re going to at least have them here in case we do want to use them let’s go ahead and run this so now let’s our data set that we’re going to be using so let’s say data frames equal to pd. read CSV and let’s get this in right here now we’re going to be doing these ice cream ratings let’s take a look at this really quickly now these values are completely randomly generated they are not real in any way um but that’s what we’re going to be using because I just wanted something kind of generic something that wouldn’t be too crazy confusing just something that we could use and you guys can understand that there’re just numerical values vales but let’s also set that index really quick so we’ll say data frame. setor index and then we’ll say date and then we’ll say that’s equal to the data frame and we have this date column right here as our index so we have uh January 1st second third fourth and then we have our ratings right here and again these are all just integers and they’re pretty easy or really easy to demonstrate how you can visualize these so that’s why we’re using it today so the way that we visualize something in pandas is use something called plot so let’s just take our data frame we’ll do data frame. plot and we’ll do our parentheses now let’s go in here really quickly let’s hit shift Tab and this is going to come up and this is pretty important because this kind of is going to tell us what we can do within this plot and unfortunately there isn’t like a quick overview we just have this dock string but we have our parameters right here these are what we can pass in to kind of customize our visualization so the data is going to be our data frame then we have our X and Y labels we can specify the kind and this one’s important because we can specify what kind of visualization do we want we can do a line plot horizontal a vertical bar plot histogram box plot and then a few others including area Pi density all these other things we can also specify if we want it to be a subplot and a lot of these things that I’m specifying you know I’m going to show you how to do you can use uh different indexes you can add titles add grids Legends Styles all these different things I mean you can go through here because there are a lot but you can specify and you know customize all of these things we won’t be going into all of them but I will show you some of the ones that I probably use the most and that I think are the most useful to know right away so let’s get out of here and we’re just going to do DF do plot and when we run this we’ll get this right here and that was super super easy created a line plot by literally doing just about nothing um but by by default it’s going to give us a line plot so if we come up here we say kind and let me get that out of the way is equal to line and we run this so by default without us actually having to input anything it’s giving us that line plot as a default so uh we can specify it’s a line plot as you can see we already have all of our data right here we didn’t have to specify anything it kind of automatically took it in it is visualizing all three of these columns and it has this little um Legend right here and we can specify where we want that uh there is an argument to be able to do that it also gave us these tick marks of 2 4 6 8 10 again it read in and it said it’s only going from 0.0 to 1.0 that is kind of the peak and so it kind of automatically gave us these ticks for us again that’s another thing that you can specify we can make it go up to 2 5 10 1,000 whatever you want it to be and then we’re doing this based off of this date value right here here really quickly I wanted to give a huge shout out to the sponsor of this entire Panda series and that is udemy udemy has some of the best courses at the best prices and it is no exception when it comes to pandas courses if you want to master pandas this is the course that I would recommend it’s going to teach you just about everything you need to know about pandas so huge shout out to you me for sponsoring this Panda series and let’s get back to the video if we wanted to break these out by the actual column we could go in here and say subplot is equal to true and it’s actually subplots whoops and now we can run that and then we can see each of those columns being broken out by themselves instead of them all being in one visualization it’s now uh three separate visualizations now let’s go right over here we’re going to get rid of the subplots I want to show you just some of the different arguments that you can use to make this look nice uh because I don’t want to do this on every single visualization I just want to show you what you can do so we have this one right here we can add a title notice there’s no title or anything really telling us what is so we can say comma idle and we’ll say ice cream ratings if we run this we now have this nice title right here now we can also customize the labels or the titles for the X and Y AIS it automatically took this date which is right here this is our date index it automatically took that for us but we can customize that if we’d like to all we have to do is comma and then we’ll say x label is equal to and so our X is the this date one right here and we can say daily rating and then we can do the Y label we’ll say y label is equal to and for this one we can say scores hope you cannot hear my dog in the background cuz they’re being insane uh but let’s go ahead and run this and now we have these daily ratings on the x- axis and on the Y AIS we have scores now let’s go right down here and start taking a look at our next kind of visualization which is going to be a bar plot so we’ll do DF do plot we’ll do kind is equal to and for this one we’re going to say bar now this is what your typical bar plot will look like and a lot of the arguments that we just did on the line plot you can also apply to this bar plot something that’s unique to the barplot is that you can also make it a stacked bar plot all we have to do is go in here we’ll say comma and we’ll say stacked is equal to true so now let going to make it a stacked bar chart instead of just you know your regular bar chart let’s go ahead and run this and as you can see this is now stacked on top of one another with each of these columns all representing the values that they have now we don’t always have to do every single column we can also specify the column that we want so let’s take the flavor rating for example we could do flavor oops flavor rating good night flavor rating and then it’s only going to take in that flavor rating column and if you notice we don’t have a legend that’s only when you have multiple values which we are only looking at this one column so all the values are right here now in this bar chart it automatically defaults to a vertical bar chart but you can change it to a horizontal bar chart let’s go ahead and take a look at how to do that bring back all of them we’ll do DF do plot Dot and then we’ll say barh and I don’t know if I can keep in that kind equals bar let me run this yeah I need to get rid of that because the bar. H is its own um this is its own function so now I’m going to run this it should just have a stacked bar chart except now it should be horizontal so now you can see this worked properly it’s basically the exact same thing as a vertical bar chart just now horizontal which may look better especially depending on if you have values like this or you know something else that just looks better being horizontal now the next one that we’re going to take a look at is the scatter plot so we’re going to say DF do plot. scatter and if we run this we’re going to get an error what we need in order to run this properly is we need to specify the X and the Y AIS in order for this scatter plot to work so let’s go here and we’ll say x is equal to and we can take any of our columns that we have up here so we’ll say x is equal to texture rating and then oops Y is equal to we’ll do overall rating now when we run this it should work properly let’s go ahead and take a look now if we go in here and we do shift tab we can also see some other things that we can specify so let’s go right down here so we have our X and we have our Y and those are the ones that we just did we can also pass through an S which is going to tell us or or change the size of the actual dots right here in our scatter plot then we can also do a c which is the color of each point let’s start with the S let’s say s is equal to and let’s just do 100 let’s see what that looks like so we have a much larger number let’s do 500 and see what that looks like so we can make these much larger on our visualization depending on what you’re looking for we can also look at the color let’s put comma C so for color we can say color is equal to and let’s do uh yellow let’s see if this works so now we’ve changed it to Yellow that looks absolutely terrible but it does work now let’s move on to the histogram histogram is always a good one it’s very similar to something like a bar chart but what’s great about a histogram is you can specify the bins um so let’s go ahead and say DF dolot doist then we’ll do an open parenthesis and let’s go ahead and hit shift tab in here take a look at this one as well so some of our parameters are the actual columns or the data frames that we want to pull in we can choose the bins and they have a default default of 10 in here and so let’s take a look at how this works so we’ll just run this as it is so this is by default what this histogram is going to look like let’s go ahead and specify our bins we’ll just say it was 10 by default let’s just do 20 see what that looks like so there are smaller columns right off the bat and remember histograms are really good for showing distribution of variables you know that’s really what a histogram is for but of course since these are completely random numbers this histogram isn’t going to make any sense at all but you can at least kind of see visually how it works and if I didn’t mention it before which I should have the bins represent how many kind of tick marks are down here so if we just do one it’s only going to be one very large uh you know histogram we could even go further down from 10 and do five so now there’s only one 2 3 four five so the distribution gets smaller and things get more compact as you spread it out again like we did 100 it’s going to spread it out a lot um and this is what it shows you know it’s showing the distribution of those bins across however many you want so the 10 by default you know it usually is pretty good for a lot of different things now let’s go down here and look at the box plot and the box plot is a pretty interesting one let’s go ahead and visualize it really quickly and then I’ll kind of explain how this one works let’s do DF dobox plot that’s r on this and really what we’re looking at is some different markers within our data this line right here is the minimum value within that column we also have the bottom of the box which is the 25th percentile of all the values within just this column this is 50% then we have 75% and then up here we have our maximum value so I can take a glance at this and see that we have a low minimum a high maximum and it definitely skews towards the lower range whereas if I look over here we have a lower minimum and a higher maximum and you can see that this medium point is at 6 versus 04 over here so this skews a lot higher now let’s go down here and take a look at an area plot we’ll do DF do plot. area and let’s just run this this is what we’re going to get by default now something I wanted to show you earlier I just haven’t gotten around to I want to show you something called Figure size or fig size um so for this it’s know it’s just looks small looks a little bit cramped let’s say we want increase the size of this and we’ll say fig size oops fig size is equal to and let’s just do a parentheses and say 10 comma 5 that should be pretty large this is going to make it a lot larger just something I wanted to throw in there I look at these area charts as pretty similar to like a line chart if we went and compared those be pretty similar um but they’re different visually and you know you absolutely can use these for different types of visualizations but I don’t use this one a lot if I’m being honest that’s why why it’s kind of towards the end of the video but you definitely can do it let’s go on to our very last one of the video that’s going to be the beautiful pie chart let’s say DF plot.py do an open parenthesis and let’s run it we’re going to get this error that’s because we need to specify what column we’re working with here so let’s just say the Y and that’s what we need me open this up for us right here we have our Y and this is our our label or our column that we’re going to plot that’s really all we need so we can just say Y is equal to flavor rating oops flavor rating let’s run this now we get this visualization right here let’s make this one a little bit bigger big size is equal to 10 comma 6 now it’s a little bit bigger it definitely depends so this Legend is going to autop populate you know you can make this as big as you want and obviously it’s going to look a little bit better if you do it larger and these colors autop populate now you can customize these colors although I found these ones to be just when you have a lot of them it’s harder to customize them as easily but you know definitely look into it these are things that everything in here is almost something that you can customize in some way although it does get a little bit tricky you definitely have to do some research and some Googling around just to kind of figure out how to do those things now one last thing that I wanted to show and something you know I could have probably done at the beginning um is you can actually change what visual this is and we can do that pretty easily within mpot lib there are different styles um and so let’s go right here let’s add a new row a new cell and we’ll say print and we’ll do PLT so that’s that map plot lib right here we’ll do PLT do style. available and what this is going to do whoops what this is going to do is show us all these different types of uh stylings that you can do to kind of change up this visualization then once we find the one that we like we’ll just do PLT do style. use and then in the parenthesis we’ll just specify which one we want now there’s all these Seaborn ones and Seaborn is a really great um really great Library let’s try Seaborn deep I haven’t tried this one at all let’s go ahead and try this and just changes some of the colors some of the visuals we can try something like like 538 let’s try this that looks quite a bit different and let’s try something like um classic I don’t know what this one looks like let’s just try it so you can try out all these different styles find one that you’d like find one that you think looks really nice and you can run with it through all your visualizations hello everybody today we’re going to be cleaning data using pandas now there are literally hundreds of ways that you can clean data within pandas but I’m going to show you some of the the ones that I use a lot and ones that I think are really good to know when you are cleaning your data sets so we’re going to start by saying import andas as PD and we’re going to run that and now we’re going to import our file so we’re going to say data frame is equal to PD so that’s pandas do read uncore and we actually have this in an Excel file so we’ll say read oops say read Excel do an open parenthesis and we’ll do R and then we’ll paste the path right here and now we’re just going to call that variable so we’ll call data frame and we’ll actually read it in and look at the data so let’s scroll down here and let’s take a look at this data frame or this Excel file that we’re reading in so right off the bat we have this customer ID that goes from 101 all the way down to20 we have this first name and everything looks pretty good here except in this last name column uh looks like we have some errors we have some forward slashes some dots some null values um so definitely going to have to clean that up because we don’t want that in the data we have a phone number and it looks like we have a lot of different formats um as well as Naas not a number um just lots of different stuff so we’re going to need to standardize that so clean it up and then standardize it to where it all looks the same um we also have address and it looks like on some of these we just have a street address but on some of the other ones we have like a street address and another location as well as a zip code in some of them so we’ll probably want to split those out we have a paying customer uh which is yes and Nos and some of those are not the same so I have to standardize that we have a do not contact kind of the same thing as the paying customer and we have this not useful column which we’ll probably just want to get rid of okay so the scenario is is that we got handed this list of names and we need to clean it up and hand it off to the people who are actually going to make these calls to this customer list so they want all the data in here standardized and cleaned so that the people who are making those calls can just make those calls as quickly as possible but they also don’t want columns and rows that aren’t useful to them so things like this not useful column we’re probably going to get rid of and then ones that say do not contact if it says yes we should not contact them we probably will want to get rid of those somehow so that’s a lot of what we’re going to be doing to clean this data set normally the very first thing that I do when I’m working with a data set most of the time except very rare cases when you’re actually supposed to have duplicates is I actually go and drop the duplicates from the data set completely all you have to do for that is say DF do dropcore duplicates so they make it super easy for you let’s just run it and up here is our original data set we have this 19 and 20 and those are obviously duplicates they have the exact same data it’s just a duplicate row that we need to get rid of if we look right down here we we no longer have that 20 we now just have one row of Anakin Skywalker and of course we want to save that so we’re just going to say DF is equal to and DF so now it’s going to save that to the data frame variable again and now when we run this our data frame Now does not have any duplicates that’s definitely one of the easier steps that we’re going to look at uh things are going to get quite a bit more complicated as we go but I’m starting out you know kind of simple so that we can kind of get a feel for it then we’ll start getting into the really tough stuff so the next thing that I want to do is remove any columns that we don’t need I don’t want to clean data that we’re not going to use so if we’re just looking through here you know they may need you know first name last name phone number for sure address might give them some information of where they’re calling to or time zone so we want that this not useful column looks like a pretty good candidate to delete and it’s very easy to do that we’re going to go right down here and we’re going to say DF do drop we’ll do an open parenthesis drop just means we are dropping that column and we can specify that by saying columns is equal to and then we’ll paste in that column that we want to delete so let’s run this and see what it looks like and it literally just drops that column exactly like we were talking about it no longer has that column again we want to save that we can always do in place equals true um if you follow this tutorial series you can always do in place equals true and that’ll save it as well but just for our workflow most of the time I’m going to assign it back to that variable um just for keeping it the same really quickly I wanted to give a huge shout out to the sponsor of this entire Panda series and that is udemy udemy has some of the best courses at the best prices and it is no exception when it comes to pandas courses if you want to master pandas this is the course that I would recommend it’s going to teach you just about everything you need to know about pandas so huge shout out to UD to me for sponsoring this Panda series and let’s get back to the video now let’s kind of go column by column and see what we need to fix and we’ll start on this left hand side this customer ID to me looks perfectly fine I’m not going to mess with it at all the first name at a glance also looks perfectly fine I don’t see anything wrong with it visually which is a good thing um although sometimes that can be deceiving and that can cause errors down the line but we’re not going to uh assume that there are errors in here now let’s look at this last name now the last name obviously I’m I’m seeing some obvious things things that we talked about when we were first looking at this data set we have this forward slash which we definitely need to get rid of we have null values so not a number right here we have some periods as well as an underscore right here so all those things I think we should clean up and get rid of it so that when the person is making these calls you know it’s all cleaned up for them so how are we going to do that we can actually do this in several different ways but let’s just copy this last name the first one I’m going to show you is strip and we’ll write it kind of like this we’ll say data frame and then we’ll specify the column that we’re working with because we don’t want to make these changes or strip all of these values from everywhere we only want to do it on just this column if we do this and we don’t specify the column name it will apply to everywhere so if we’re trying to do these yeah let’s say bum these underscores maybe that would mess with something else in another column and we don’t want that so we just want to specify just this last name so let’s go last name. string Dot strip now what strip does and let’s see if we can open this up really quickly no we can’t um but what strip does I was just I was hitting shift tab in here to see if it could bring up um you know some of the notes on it but what strip does is it takes either the left side or the right side well L strip takes from the left side R strip takes from the right side and strip takes from both but you can strip values off the left and the right hand side and we can specify those values now for what we’re doing in this column we can just use strip because as you can see this forward slash these dots as well as this um underscore are all on the far sides if there was a value Like swancore Son the strip wouldn’t work at all because it’s not on the outside of the value of the word so we can use strip I’ll also show you how to use replace and replace is another really good option for things like this but let’s start with strip and just see what it looks like and see if we can get what we need done done so let’s just run this for now see what happens so it looks like nothing has changed because again we’re not specifying any specific value just by default it’s only taking out white space so like spaces that shouldn’t be there that’s what it does by default now we can specify within this exactly what values we want to take out so let’s go ahead and do that let’s say left strip and let’s try to take out these dots real quick so we’re just going to do a parenthesis dot dot dot now let’s run this and see what it looks like for this one Potter it is now gone so those three dots were there before let’s just show it so they were there and then when I ran it like this now they’re gone that’s what the L strip does it takes it only off the left hand side now we can also do a forward slash so we’ll do something like this and it’ll get rid of the white but as you can see now we aren’t taking out these three dots so they’re still there now is it possible to do something like this where we put these values inside of a list um let’s try it so we’ll say just like this one two three let’s run it and no it doesn’t um this L strip actually sits within the the realm of regular expression so if you’ve ever worked with regular expression you know it gets very complicated very complex so you want to keep it kind of simple especially with these values where we’re just taking a few out so what we’re going to do is we’re going to do dot dot dot and we’re take it out one by one now in order to save this because we want to save this we want to take out that value we don’t just want to say data frame equals because that would be uh very bad what this would say is now this data frame is only equal to these values that we’re seeing right here we want to only apply it to this column so we’re going to go like this so now when we do it and then we call the entire data frame it’s only applying this to this one column the last name column so let’s run it and now when we go down to Potter right here it’s cleaned up so we’re going to do the same thing but for those other values and we’ll do it just like this we’ll do a forward slash and it’s a left strip and then we’ll do I’ll do the left strip on this underscore to just to show you that it won’t work and then we will go on from there so it’s not pulling it because we’re looking at the leftand side only we need to use R strip so now let’s use R strip and now that looks perfect as no underscore so that’s how you can use strip for either the left side the right side or just Strip by itself which covers both sides now I showed you all of that because I am going to show you a different way to do it um and I apologize because I somewhat lied to you earlier um let’s run this right here actually we’re just going to pull it in like this we’re going to remove the duplicates again bear with me we’re going to drop that column and then now we’re sitting with that data frame again with those exact same mistakes I just wanted to reset it for a second there is a way uh that you can do this and I just wanted to you know kind of show you how you can do it you can do this right here and we’ll say so we’re now again we’re just looking at this column just this column and we’re using strip and let’s get rid of R because we want to do apply it to everywhere you can input all of those values individually and it will clean it up so let’s say we want to get rid of numbers we’ll do 1 2 3 then we can do the dot so that’s going to be for our period or for our dot dot dot Potter we could also do the underscore and we can do the forward slash so we put it all in one string right here now let’s take a look at this we’ll get rid of this really quickly now let’s take a look and all of them were removed I showed you how to do it before because that’s at least how my mind would think about it I’d think oh I can put it in a list and run it through this L strip or this right strip and it would work um but that’s not how strip works you have to kind of combine it all into one value so uh yes I deceived you I apologize but now when we call data frame and we assign it to that column so the last name column or assigning what we just did to this last name column everything should look perfect and it does so our customer ID first name last name are all cleaned up now we’re going to come to a much more difficult one this is probably if I’m being honest the hardest one I said we were going to work up but this is probably the hardest one of the whole video working with phone numbers and look at all these different types of of formats I mean it is um it’s not going to be fun and imagine you know there’s 20,000 of these you can’t just go and manually clean those up you need something to kind of automate that so that is what we’re going to do so let’s go right down here copy the data frame and I’m going to pull it right here so now we need to clean up this phone number what we want is it all to look exactly the same unless it’s blank and we’ll keep it blank we don’t want to populate that data but we want all of them to look exactly like this one and what we’re going to do is right off the bat we’re going to take all of the non-numeric values and just completely get rid of them strip it down to just the numbers so this 1 23- 643 or forward slash will just be the numbers same with these bars and these slashes and everything all of these will just be numeric then we’ll go back and reformat it how we want to format it which will look exactly like this one um but we just want to do it for the entire column so let’s go right up here and we’re going to try replace for the first time so let’s do phone number just oops that’s not what I wanted so we’re going to do a bracket say phone number do string. replace just like we did before now we’re going to use some regular expression in here and I’ll kind of do a really high overview although I’m not going to dive super deep into the regular expression then we’re going to do a parenthesis and within there we’re going to do a bracket um I can’t remember what this is called is it called a carrot I think it’s called a carrot uh B I’m just going to call it that it may not be correct but I think it’s a an upper Arrow so it’s an upper Arrow a a d oops A- Z A- Z and then 0-9 now at a super high level what that character that first thing is doing it’s saying we’re going to return any character except and then we specify anything A to Z A to Z upper or lowercase and then actually I think this should be like this A to Z uh and then 0 to 9 so any value like a BC One Two Three those are not going to be matched it’s going to match all of them except these values and then we’re going to replace them by saying comma and we’re going to replace them with nothing so this is just an empty string so literally we’re taking everything that is not an A A B C A 1 two 3 so a letter or a number we’re replacing all of that and then we’re replacing it with nothing so let’s run this and see what it looks like and it looks like that worked properly now we do have this na because we had an n- a for I don’t remember maybe that was Creed Bratton um but it worked for basically everything else we’re going to go through the entire process and then at the end we’ll remove any values we want them to just be completely null we we don’t want them to even see n an and wonder what that is we just want it to be blank and we’ll do that at the very end so now that we know that that worked let’s assign it we’ll do DF phone number is equal to and then we’ll say data frame and this looks a lot more standardized than it did before already but now what we want to do is try to format this um and I’ve done this many many times I always use a Lambda you can definitely use a for loop I just I don’t do it that way myself so I’m going to show you how to do it using a Lambda let’s get rid of this and we’re going to say thef phone number we’ve already done that I’m just going to get rid of it now we’re going to say DF phone number then we’re going to say do apply we’ll do an open parentheses and then this is where we’re going to build out our Lambda so we’ll say Lambda X colon now this is where we’re going to kind of format it so what I want to do is I want to take the first three strings 1 2 3 then I want to add a slash and then the next three strings add a slash or a dash uh and then that be the value that’s returned so it’s not super difficult we’re just going to do X then a bracket let me get rid of that an X and then a bracket and then we want the 0 to three so it goes 01 2 so 0 1 2 it doesn’t include the three it goes up to three so 0 1 2 that’s our third first three values then we’ll do plus and do a quote and do a dash so this is our first kind of sequence and I’m just going to copy this we’ll do plus and instead of three or we are going to start at three because now it’s inclusive so we’re going to go from three and we’re going to go all the way up to six so it should be three four five our next three values then we have a dash and we’ll copy this and we’ll say plus and now we go from six all the way to 10 now let’s try running this and as you can see we get an error now I already know what the error is float object is not subscriptable which means we’re trying to um basically look at it like a string right now it’s not a string it’s actually a number so let me get rid of this for just a second I’ll going show you what it’s talking about so right now we have values that are floats and values that are strings or not even a number so we have values that are strings or not a number so if we want to actually look through it like kind of like indexing if we want to do that they all have to be strings so we need to change this entire column into Strings before we can apply this um formatting now when I was creating this if I’m being honest my first thought when I was doing this was to do it like this string DF phone number um let’s just run that this is what the values look like um and I don’t remember why or why it was doing this I can’t I can’t remember but I looked into it quite a bit and I was like oh I need to apply this string converting it to a string on each value not the entire row or not the entire column so how we can do that is actually fairly easy because we’ve already done a lot of the heavy lifting we’re just going to copy this and we’re going to say x so string of X and again Lambda is like a little anonimous function so you could do this by saying for um X in this uh column we could do a for Loop and then say for every X it equals the string of X and then it changes it to a string but a Lambda just does it a lot quicker um so we’re going to say so let’s do that really quickly and all of our values look exactly the same and that’s how we want it so we’re just going to copy this apply it good and now we’re going to take this and we’re going to run this again just ignore all my commented out stuff pretend I don’t have that um so now when we run this it should work there we go now if we look at these numbers 1 2 3- 545 D 5421 and it does that for every every single one where there’s values even when there’s n n or na it’s still adding those values but we expected that so let’s apply it says equal to and then we’ll look at the data frame and this looks almost exactly what we’re hoping for we just need to get rid of these so this n- Dash and this na Dash we need to get rid of those and that is super easy to do um we’re just going to say so now that we’ve done it and we I me it out we’ll say DF and let’s copy this ignore the messiness I do apologize for that it’s very messy um but if you’re following along with me you get what we’re doing so DF phone number so only on the phone number say string. replace parenthesis now we can specify this value so we want to take this exact value and replace it with nothing and let’s just see if that does work it does now we have these Nas and so let’s actually I’ll paste that right down here we’re going to do this is equal to and then we’re just going to take this entire string put it right here and put this value as our what we’re looking for and then replacing and then when we call that data frame it should work properly and it is perfectly cleaned so so we have every single value all the exact same they don’t have different characters or different um you know formatting and we got rid of all the ones that we don’t have or don’t need um all the ones that were just random values so this column is now completely cleaned up again definitely one of the more difficult ones um one that I’ve done a thousand times I’ve had to work with a lot of phone numbers and stuff like that this one does get very tricky especially if you have like a plus one which is like an area code um that can get tricky as well but this is on a kind of a high level this is how you can do that and it’s pretty neat how you can actually you know clean up and standardize those phone numbers so let’s go right down here uh let’s run it the next thing that we’re going to look at is this address now let’s just pretend that the people who are on the call center want all these separated into three different columns they can read it easier see what the ZIP code is where they live uh you know whatever they want it for let’s just say we want to do that and this is you know again for this use case it may not make sense but you have to do this I do this all the time um you need to split those columns now luckily all of these things are separated by a comma so we can specify that we’re going to split on this column and then we’ll be able to create three separate columns based off of this one column which is exactly what we want then we can name it as well and we can do that very easily by using this split so we’re going to say DF and we want to specify oh jeez not again so we want to specify that we’re looking at the address then we’re going to say string. split we’ll do an open parenthesis now the very first value that we need to specify is what we’re splitting on so we want to split on the comma so we want to specify that and then we need to specify how many values from left to right it should look for now we’ll just start with one and then we’ll go from there let’s just see what this looks like so it doesn’t really look like it did anything let’s do two well let’s go back to one and then let’s say expand equals true when we expand it it’s actually going to uh separated I believe okay so we’re expanding now we’re only doing this with one comma so we’re only looking at the very first comma and splitting it but in some of these well just in one there is an additional comma so we should do it up to two let’s do this okay so now we have three columns if we just save it like this it’s going to give us these 0 one2 these basically these indexed values for these columns and we don’t want that we want to specify what these actually are and we can do that by saying DF and let me just do is equal to we’ll do bracket and then within there we’re going to specify our list so we have three of them that we have so I’m going to do um the first one this is the street address so we’ll say street address the next one is and it’s sh is not a state uh but these all are state so I’m just going to say State and then for the very last one that looks like a zip code so we’ll say zip and we’ll do code in fact I also want to do streetcore address um so what this is now going to do is these three columns are going to be applied to these three names and they’ll basically be appended it’s doesn’t replace the address we’re not saying DF address equals the DF address we’re not replacing it we’re now creating different columns so let’s run it and then let’s also call it so they’re right over here on this right hand side I couldn’t see them at first but it did exactly what we needed it to do so now if we wanted to at the very end if we want to we’re not going to we could just delete this address and keep the street address the state and the zip code another really common thing that you can do this happens often again with like first name last name well you’ll have Alex freeberg but it’s Alex comma freeberg or Alex space freeberg and you can separate those out into different columns now the next one that we want to look at is this paying customer and the paying customer and do not contact are very similar um in the fact that it’s yes no NY yes no NY um and so let’s go right on down here and we’re going to say DF Dot and we we want to just replace these values as all yeses or all NOS but just with the same formatting um just to keep it consistent so let’s make anything that’s an N into a no anything that’s a a y into a yes I like it spelled out so let’s change anything that’s a yes into a y and anything that’s uh a a no into an N that’s usually how I do it just saves on data because it’s less strings although it’s be often very minimal um but let’s specify the in customer we see say DF bracket Pay customer then we’ll do string. replace so now we’re just going to look for those specific values so if it’s a y oops a capital Y then we’ll say yes now let’s run it and now we have no more y we now just have yeses although now these are yes yeses okay we don’t want to do that let’s do if we’re looking because it’s taking it’s literally looking up here and saying okay there’s here’s a y um let’s change the let’s change that Y into a y so now it’s doing ye uh we don’t want that so let’s look for the yes and change it into a y now when we run this that looks a lot better um so we’ll do D of paying customers equal to and then we’ll copy this we’ll do the exact same thing no and N then let’s call it and now that entire column looks really good except for that value right there but I’m going to leave that because I’m just going to apply it to the entire thing all at once to get rid of those at the end instead of just going column by column and then it’s literally going to be the exact same thing so I’m not even going to scroll down whoops I’m just going to put it right up here because this is the exact same thing I’m going save us all some time and when we run this this looks exactly like what we’re looking for again some not a number of values but we can get rid of that in just a second by doing our place over the entire data frame and that is basically the end of cleaning up individual columns now let’s go right down here we’re going to say DF do string. replace and then we’ll first do these values oops so we’ll do oops let me do that there we go and replace that with nothing let’s just see what it looks like oops data frame object has no value string well that’s because we were looking at columns before yeah I think I just need to get rid of this string we’re not looking it we’re just doing it across the entire data frame now let’s try that okay that worked appropriately and we’ll just say data frame is equal to and then we’ll copy this and we’ll do the NN as well and we’ll [Music] do and now when we do this it is not going to replace these because these aren’t actually a value because we’re looking for that string we actually need to use and I I completely forgot this I’m not going to lie to you um let’s get rid of this uh to get rid of those values because it’s literally not a number there it is technically empty um I forgot we can do um or we could not even specify it we’ll do DF do fillna so we’re going to fill these values if there’s nothing in them we’re going to fill it and we’re going to say blank and when we run that every value that doesn’t have something in it is going to show up blank even over here where we only had a few all of them throughout the data frame if it doesn’t have a value it is now blank so let’s apply that and and we’ll run this and now all of our cleaning we’re actually cleaning up the individual columns is completely done we’ve removed columns we’ve split columns we’ve formatted and cleaned up phone numbers we’ve also taken values off of first name or or this last name column and then we formatted in just kind of standardized paying customer and do not contact now they also asked us to only give them a list of phone number numbers that they can call so if we take a look some of these do not contacts are why which means we cannot contact them and then there are some that don’t even have phone numbers so we don’t want to give the people the call center numbers that or or people who don’t have numbers so we want to remove those now there’s a few different ways that we can do this but let’s start with and we’ll just go by do this do not contact it seems like the most obvious one now if it’s blank we want to give them a call we only want to not call them if they’ve specifically said we cannot call them so if it’s y we’re not going to call them so what we need to do it’s not anything like this we probably need to Loop through this column and then look at each row that has a value of this and drop that entire row uh and we probably will’ll need to do that based off this index instead of doing it based off just this column uh that may not make sense but let’s actually let’s actually start writing it so we’ll do 4X in and we need to look at our index so we’re just going to do let’s do in DF do index and we’ll do a colon enter and then we want to look at these indexes how do we look at these indexes we use lock that’s going to be DF do Lo and then we need to look at the value which is this x right here so each time it looks at the index it’s looking at the value but we want to look at the value of this column do not contact I don’t know if I copied this before let me copy it we only want to look at the value in this one column if we didn’t it would look at um a different value so we don’t want that so we’re looking at just that value if it’s equal to Y so if this value is equal to Y then we want to drop it so we actually need to say if so if this value X in this column is equal to Y then we want to do DF do drop and then we’ll say x and we I think we have to say in place equals true here otherwise it won’t take a fact um otherwise have to say like DF is equal to DF I don’t I don’t want to start messing with that let’s just do in place equals true um and let’s see if that works I I can’t remember if this is going to work or not invalid syntax okay neon and now let’s try to run this okay okay yeah if we look at our index we can already tell that there are ones missing the one the one is missing the three is missing um let’s see and the 18 is missing so we already got rid of those values and you can you can see that there’s no y’s in here anymore which is really good we can if we want to and we probably should we should probably populate that um really quickly um let me just go up here really quick I’ll copy this we probably should populate that and I didn’t plan on doing this so um if it’s blank oops it’s blank give it an n and we want to attribute it to do not contact do not contact whoops let’s see if that works and we probably need to do dot string let’s just see if it works so if it’s blank dude okay I don’t know why it’s giving us a triple n maybe there’s maybe I need to strip this or something uh okay never mind let’s not do that but now we basically need to do the exact same thing for this phone number um because if it’s blank we don’t want them calling it um so we can copy this entire thing go right down here and but now we’re looking at phone number so now we’re looking just at the values within phone number and we only want to look at if it’s blank so if it literally has no value we want to get rid of it let’s run this and see if it works again it should good and now our list is getting much smaller so you can see in our index a lot of um those rows were removed and and okay good actually this worked itself out because these all have ends um so right now we’re sitting really good everything looks really um standardized cleaned everything looks great I might drop this address if you want to you can drop this address but besides that this is all looking really good this pain customer doesn’t uh the yes and knows aren’t really anything um now we could and we probably should before we hand this off to the client or the customer call let’s we probably should reset this index because they might be confused as why there’s numbers missing or you know they might use this index um to show how many people they’ve called or I don’t know something like that so let’s go right down here we’re going to say DF Dot and then we’ll do reset index and let’s just see what this looks like um it does work but as you can tell it didn’t uh get rid of that index completely it actually took the index and saved that original one we do not need to save that whoops let’s put it right in here now we’re just going to do drop equals true and when we do that it just completely resets it drops the original index and gives us a new index and that is what we want let’s do DF equals and this is our final product now one thing that I you definitely could have done here um and I made this a little probably more complicated than it needed to be um that was just how my brain was working at the time when I’m you know typing this out we could could have done DF do drop an a um which is literally going to look at these null values um before we couldn’t do that with this one because these aren’t we’re not looking at na we’re looking at y’s so we couldn’t do that but because we’re looking at null values we could have also done drop na um and done subset is equal to and then done it just on this phone number and then done like this and done in place equals true so we could have also done this and then said DF equals um I can’t I mean I can run it it’s just not going to do anything I can run it on the different column but that’ll me mess everything up but this is another way you can do it and I’ll just save it in case you want to um I’ll say another way to drop null values there you go and that’ll just be a note for us in the future um but this is our final product it looks a lot different than when we first started I mean we had mistakes here completely different formatting in the phone number different address everything that we just talked about um and this looks just a lot lot better and you can tell why it’s really important to do this process because again we’re working on a very small data set I I purposely you know created this data set with these mistakes because you know when you’re looking at data that has tens of thousands 100 thousands a million rows these are all things that are going to be applied to much larger scale and you won’t be able to as easily see them um you’ll have to do some exploratory data analysist to find these mistakes and then you’re going to need to clean the data or doing it at the same time when you’re exploring the data uh so you’ll clean it up as you go but these are a lot of the ways that I clean data a lot of the things that you can do to make your data just a lot more standardized a lot more um visually better and then it really helps later on with visualizations and your you know actual data analysis so hello everybody today we’re going to be looking at exploratory data analysis using pandas exploratory data analysis or Eda for short is basically just the first look at your data during this process we’ll look at identifying patterns within the data understanding the relationships between the features and looking at outliers that may exist within your data set during this process you are looking for patterns and all these things but you’re also looking for um mistakes and missing values that you need to clean up during your cleaning process in the future now there are hundreds of ways to perform Eda on your data set but we can’t possibly look at every single thing so I’m just going to show you what I think are some of the most popular and the best things that you can do when you’re first looking at a data set the first thing that we’re going to do are import our libraries so we’ll do import andas as PD we’re also going to import Seaborn and matplot lib now during this exploratory data analysis process I often like to visualize things as I go because sometimes you just can’t fully comprehend it unless you just visualize it and it gives you a a larger broader glimpse of everything so we’re going to import and let’s do caborn oops as SNS and then we’ll import Matt plot li. pyplot as PLT let’s run this this should work okay perfect now we need to bring in our data set so we’ve worked with that world population data set that is the exact one that we’re going to use now so we’ll say dataframe equals pd. read CSV do R and we’ll paste in our CSV and this is what it should look like although your path may be different be sure to make sure that you have the correct file path then we’ll read it in now this data set should look extremely familiar if you’ve done some of my previous pandas tutorial but I did make some alterations to this one took out a little bit of data put in a little bit of data here and there um to change things up because if it was just exactly how I pulled it which I got this data set from kaggle if it was exactly how we pulled it like we’ve looked at in the previous videos it’s too simple you know we wouldn’t actually be able to do some of the things that I would like to show you so be sure to actually download this exact data set for this video because it is a little bit different but what we’re going to do now is just just try to get some highlevel information from this now if yours looks just a little bit different like your values are in scientific notation uh I have applied this so many times I think it’s um you know still applied to this you can do something and we’ll write it right down here we’re going to do pd. setor option and we’ll do an open parenthesis and we’ll say display. flator format and so we’re going to change that float format by just saying Lambda X colon and then we’re going to change basically how many um decimal points we’re looking at so let’s just do here so we do a quote sign 2f so we’re formatting it whoops 2f so we’re going to format it and we’ll do percent X this is going to format it appropriately I’m I can run it um and actually it will change it CU this is at0 one I believe last time I did it so let’s run this and then let’s run this again n it’ll change it to0 2 so that’s two I like it at 0.1 we don’t really need it any well let’s keep it at0 2 why not we’re going to keep it at0 two that’s how you change that and I like looking at it like this a lot better than scientific notation so just something to point out um let’s go down here and let’s just pull up data frame so we have this data one of the first things that I like to do when I get a data set is to just look at the info so we’re going to do do info and this gives gives us just some really high level information this is how many columns we have here are the column names here are how many uh values we have and if you notice this is where it kind of gets so we have 234 in each of these so in each of these columns we have 234 until we get to this 2022 population once we get there we start losing some values and then at the world population percentage we have all of our values all 234 of them the count tells us that it’s nonnull so it does have values in it and then we also have the data types and these come in handy later um and these are really great to know and we’ll be able to kind of use those in a few different ways later on in this tutorial really quickly I wanted to give a huge shout out to the sponsor of this entire Panda series and that is udemy udemy has some of the best courses at the best prices and it is no exception when it comes to pandas courses if you want to master pandas this is the course that I would recommend it’s going to teach you just about everything you need to know about pandas so huge shout out to UD me for sponsoring this Panda series and let’s get back to the video the next thing that I really like to do and this one is DF do describe this allows you to get really a high level overview of all of your columns very quickly you can get the count the mean the standard deviation the minimum value and the maximum value as well as your 25 50 and 75 percentiles of your values so just at a super quick glance there is a row somewhere in here and there this country their population is 510 for 2022 and in fact if you go back to 1970 it was higher was at 752 that’s just interesting then if we look at the um max population one has 1.42 billion I believe that’s China and then over here in 1970 we have 822 million again I still believe that’s China but this gives you just a really nice high level of all of these values all these different calculations that you can run on it and we can run all these individually on even specific columns but you know this just a nice high level overview one thing that we just talked about was the null values that we’re seeing in here um I’d like to see how many values we’re actually missing because that is a problem um we don’t want to have too many missing values that could really obscure or change the data set entirely and so we don’t want that so we’ll say DF do is null and then we’ll do a parenthesis we’ll say do sum and when we do this whoops dot sum there we go when we do this it’s going to give us all the columns and how many values we’re actually missing now we have 234 rows of data so we have 41477 55424 um so we have we definitely have data missing what we choose to do with it in the data cleaning process maybe we want to populate it with a median value Maybe we just want to delete those countries entirely if the data is missing um you know I don’t think you’re going to do that but these are things that you need to think about when you’re actually finding these missing values this is what the Eda process is all about we want to find different um either outliers missing values things that are wrong with the data or we can find insights into it while we’re doing this as well so this is definitely something that I would consider um when I’m actually going through that data cleaning process really important information to know now let’s go right down here go to our next cell say DF do unique and this is going to show us how many unique values and it’s actually n unique uh this is going to show us how many unique values are actually in each of these uh columns and this one makes the most sense um for continent because I think there’s only seven continents right um but we have six right here and for all of these each of these ranks countries capitals should all be unique that makes perfect sense as well as these you know these populations are such specific numbers in such large numbers I would be shocked if any of these were similar and then for these world population percentages it’s much lower and again that makes a lot of sense because when we’re looking at and we’ll pull it up right here when we’re looking at these world population percentages um a lot of them are really low 0.00 0.01 like this one um 0 .2 there are a lot of really low values for those small countries and so those are all um you know one unique value now let’s say we just have this data right here and we want to take a look at some of the largest countries and we can easily do that we could even we could say Max and take a look at the largest country but I want to be a little bit more strategic I want to be able to look at some of the top range of countries and we can do that based off this 2022 population so we’ll say DF do sort underscore values this is how we sort and um not filter but um order our data so we’ll do sort values and then we’ll do buy is equal and then we’ll specify that we want uh this 2022 population and then we’re going to say comma and we’ll say actually let’s just run this as is um but we’ll do head because we just want to look at the top values so now we’re just looking at the very top values so what we’re looking at is actually these 2022 population um that’s what we’re filtering on or sorting on basically and we’re looking at the very bottom values because it’s sorting ascending so from lowest to highest so this Vatican City in Europe is um you know 510 that’s the value that we were looking at earlier now we can do comma ascending equal to false because it was by default true we can do false whoops we can do false and then it’ll give us the very largest ones so if we just take a look at the top five largest by population we’re looking at China India United States Indonesia and Pakistan and we can even specify that we want the top 10 in this head we can bring in the top 10 and we also have Nigeria Brazil Bangladesh Russia and Mexico and you can do this for literally any of these columns whether you want to look at continent capital country um you can sort on these and look at them and you can even look at you know things like growth rate world percentage this one seems really interesting let’s just look at this one really quick before we move on to the next thing um if we look at this world percentage just China alone I believe yep just China alone is 17.88% of the world so 17.88% again just getting in here looking around that’s all we’re really doing now I want to look at something and I have always liked doing this which is looking at correlations um so correlation between usually only numeric values we can do that by saying DF docr and a parenthesis and we’ll run this and what this is is it is comparing every column to every other column and looking at how closely correlated they are so this 2022 population if we look across the board it’s very highly I mean this is a a one: one this is highly correlated to each other and that almost for all of these populations they’re very very closely tied to each other which makes perfect sense because for most countries they’re going to be steadily increasing and so they’re probably almost exactly correlated but we can look at these populations and if you look at the area it’s only somewhat correlated and that’s because in some countries you know they have a very high population but a small area or vice versa small area in a very high population so there isn’t a one toone correlation there but it’s hard to really just glance at this um and understand everything that’s there we could just visualize it and it would be a lot easier so let’s go ahead and do that let’s go down here we’re just going to visualize this using a heat map basically so we’re going to say SNS do heatmap and an open parentheses and the data that we’re going to be looking at is DF do core correlation and then we also want to say inote equals true I’ll kind of show you what that looks like in just a little bit um but let’s do PLT doow and this will be our first look and I need to say show not shot um we can get a little glimpse of what it looks like but this looks um absolutely terrible let’s change the figure size really quickly so I want to make this much larger than it already is we’ll do PLT Dot RC pams RC pams oops right there do an open parenthesis and then right here we’re going to do in quotes do figure. fig size this actually needs to be in brackets I believe just like this not parentheses we’ll say fig size is equal to and now we can specify the value that we want let’s do 10 comma 7 and see if this looks any better no no that’s doesn’t look good do 20 okay that looks a lot better and um you know this is just a quick way because it gives you basically a colorcoded system highly correlated is this tan all the way down to basically no correlation or negative correlation even which is black so when we’re looking at these 2022 populations and these are populations right down here on this axis we can see that all of these are extremely highly correlated very very quick whereas the rank really has nothing to do it’s it’s negatively correlated doesn’t really have anything to do with it then for the population and the world population percentage it again is quite correlated except for the area density and growth rate so I find that really interesting that you know the density the growth rate in the area aren’t really all that Associated or correlated with the population numbers that is I kind of of would have assumed that on some level they went hand inand the area does um would you know again make sense you know larger area larger population that kind of thing but even density um I guess I guess density and growth rate um growth rate I can see because that’s a percentile thing that could be definitely not correlated but I thought the density would be more correlated than it is all that to say is this is one way that you can kind of look at your data see how correlated it is to one another that can definitely um help you know what to analyze and look at later when you’re actually doing your data analysis let’s go right down here um something that I do almost all the time when I’m doing any type of uh exploratory data analysis like this I’m going to group together columns start looking at the data a little bit closer um so let’s go ahead and group on the continent so let’s look at it right here let’s group on this continent because sometimes when you’re doing this Eda you already know kind of what the end goal of this data set is you know kind of what you’re looking for what you’re going to visualize at the end that you really comes in handy when doing this but sometimes you don’t sometimes just going in blind and so far we’ve really just been going in blind we’re just throwing things at the wind kind of seeing some overviews um looking at correlation that’s all we’ve done now I kind of want to get more specific I want to have like a use case something I’m kind of looking for not doing full data analysis not diving Into the Depths but something we can kind of aim for so the use case or the question for us is are are there certain continents that have grown faster than others and in which ways so we want to focus on these continents we know that that’s the most important column for this use case this very fake use case um so we can group on this continent and we can look at these populations right here because we can’t really see growth you can see a growth rate but the density per uh kilometer we don’t have multiple values for that it’s just a static one single value same for growth rate same for world population percentage but we have this over a long span many many years um you know 50 years of data here so this we can see which countries have really done well or which continents have really done well so without you know talking about it even more let’s do DF Group by and then we’ll say continent oops let me just copy this I’m I’m not good at spelling I’m going to say DF Group by and then we’ll do mean and we can just do it just like this and now we have Africa Asia Europe North America Oceana and South America okay so if I’m being completely honest I knew most of these all right I’m no geography extra expert but I I knew most of these I don’t know what this ocean is um this that I don’t I genuinely don’t know what that is um so let’s just search for that value and see we’ll come back up here in just a second but I want to I want to kind of understand um what this is so we’re going to DF um and we’ll say content let me sound that out for you guys um then we’ll do do string. contains oops contains good night and then I want to look for Oceana uh and let’s let’s run this oh I need to do it like this now let’s run this so now we’re looking at our data frame we’re seeing what the values have this continent as Oceana um okay so these look like Islands I’m guessing so we have Fiji Guam um New Zealand Papa New Guinea yeah these look like all I’m I’m guessing based off the continent Oceana um Oceania o ocean Oceania guys this is tough for me okay I’m doing my best I you know this is part of the Eda process I don’t know what that means I don’t know what Oceana ocean ocean Oceania geez I’m just going to call it Oceana that’s so wrong but I’m just gonna it’s so easy for me to say you know I I now am seeing this and it looks like Islands um which would make sense because for their average they have the highest average rank um and I’m guessing that’s because they’re just mostly small continents so let’s let’s order this really quickly we’re going to do dot sortore values do an open parenthesis and I want to sort on the population we’re just doing the average population um we’ll do BU um equal so on the average population and we’ll do ascending equals false so when we’re looking at this average or the mean population Asia has the highest population on average then we have South America Africa Europe North America and then Oceana at the very bottom which makes perfect sense again small Islands um world population percentage so each of the countries each of those countries in Asia makes up about 1% on average really interesting um to know and just kind of look at this and the density in Asia is far higher than d almost double every single other continent um really really interesting actually now that I’m looking at this but you know that’s something that I would actually look into and I would be like what is this Oceana or oenia what does that mean and you know let me look into that let me explore that more because I want to know this data set I’m trying to really understand this data set well but what I want to do now is I want to visualize this um because I just feel like looking at it I don’t it’s hard to visualize and again the use case that we’re saying is is which continent has grown the fastest like it could be percentage wise it could be um you know as just a whole on average let’s take a look so we’re going to take this and let’s copy it like this let’s bring this right down here so let’s look at this so if I try to visualize this and let’s do that let’s do df2 is equal to because I’m I already know it’s not going to look good just based off how the data’s sitting um we can do df2 oops what am I doing I don’t need to do that but I will okay df2 and we’ll do df2 do lot and we’ll run it just like this um as you can see Asia South America Africa Europe North America Oceana we can kind of understand what’s happening but these are the actual um values that are being visualized not the continents which is what I wanted um in order to switch it and it’s actually pretty easy and this is something that um you know is good to know we can actually transpose it to where these these continents become the columns and the columns become the index and all we have to do is say df2 do transpose and we’ll do this parentheses right here and let’s just look at it and then we’ll save it so now all these columns are right here and all of the indexes are the columns so we’ll say df3 is equal to and I’m just doing that so I don’t you know write over the DF or my earlier data frames so now we have this data frame three so now let’s do data frame 3. plot and it should look quite a bit different uh whoops I didn’t run this let’s run this and run this and as you can see this does not look right at all and the reason is because we’re not only looking at uh the correct columns we have this density in here we population percentage rank we don’t need any of those the only ones that we want to keep are these ones right here this population now we can do that and we can just go right up here this is where we created that data frame two that we transposed we can go right up here and we can specify within this we actually only want specific values now we can go through and handr write all of these and by all means go for it but I am going to go down here I’m going to say DF do columns and I’m going to run this it’s going to give us this list of all of our columns and I’m just going to you can just copy this and you can put it right in here I need a list with I think it needs to be like this if I’m let me try running this okay so this worked properly you can do it just like this or a little shortcut if you want to do it like that if you want to do a shortcut like um I I would hope you would you would just do DF do columns just like how we looked at down here except since this is our an index we can search through it so we can just say 0 1 two okay so we can do five up to 13 so I think it’s seven and we’ll just let’s see if this works uh it may not I may actually need to go like this let’s see there we go so you can just use you know the indexing to save you some visual space gives you the exact same output so now we have this this is our df2 now let’s go down and transpose it so now we just have these populations and we have our continents right here and then now we’re going to plot it and this looks good although it’s backward um okay it’s backward so what I actually want to do is not this uh that is a quick way to do it although not the best way to do it um so I’m actually going to copy all of these and although I said it would save us time it did not at all so I’m going to put a bracket right here I’m going to paste this in here and I’m literally going to change these up I might speed this up or I might just have you sit through this because you know this is an interesting part of the process and I want you know you to get the full experience you know what now that I’m talking about it that is what we’re going to do do you guys can hang out with me this is a good time we have 2010 2015 2020 and 2022 now let’s run it what did I do oh too many brackets there we go so now it’s ordered appropriately we have 1970 all the way up to 2022 this is how we want it let’s transpose it appropriately let’s run it and now we basically have the inverted uh image of this now just at a glance and we haven’t done anything to this except for literally what we are looking at at a glance we can see that from 1970 China you know Asia and China are already in the lead by quite a bit and it continues to drastically go up especially in the 2000s like right here it explodes like just straight up then kind of starts going up and just leveling off every other continent especially oce ocean is just really low it it never has done a bunch let’s see look at green green has gone up um from you know Point let’s say 0.1 up to about 0.2 so they’ve almost doubled um in the last 50 years and again you can just get an overview a highlevel overview of each of these you know continents over the span of this time so this is kind of one way that we can you know look at that use case we’re not going to harp on that too long I just want to give you an example like you know when you’re looking at this sometimes you’ll have something in mind of what you’re looking for and you go exploring and just kind of find what’s out there and find what you see um the next thing I want to look at is a box plot now I personally I love box plots you know they’re really good for finding outliers and there’s a lot of outliers I already know this because the average the 25th 50 percentile are very low and then there’s some really just big outliers but for your data set it may not be that way and those outliers may be something that you really need to look into and box plots have been something that I’ve used a lot where I found those outliers that way and started to dig into the data to find those outliers and you know came across some stuff that I’m like oh I have to clean this up I have to go back to the source really um really really powerful and useful to be able to find these so all you have to do is DF dobox plot and let’s take a look at it and this already looks good as is maybe I’ll make it a little a little bit wider um let’s do fig size oops sorry fig size is equal to let’s try 20 by 10 um okay that didn’t help at all I apologize I thought I would but let’s keep going what this is showing us is that these little boxes down here which are actually usually much larger because you have a more equal distribution of of um numbers or values in the small value this is where our averages lie this number right here is the upper range and then all these values all these Open Circles those actually stand for outliers so we’re looking at the 2022 population there’s a lot of outliers now for our data set knowing our data set is really important outliers are to be expected especially when most countries or continents are small so we’re looking at you know all of these little dots are outlier countries um or outlier values which each value corresponds to a country so if this was a different data set I would be you know searching on these and trying to find these so that I can see what’s wrong with them if anything or if they are real um numbers like if this was Revenue everyone’s revenue is way down here and then there’s one company that’s making like 10 trillion dollar that’d be an outlier up here and it would definitely be something that you want to look into for our data set knowing that you know we’re looking at population this is more than acceptable you know oddly enough but that’s what box plots are really good for showing you some of those core tiles the upper and the lower um as well as denoting these points that fall outside of those normal ranges for you to look into so really really useful so now let’s go down here pull up our data frame again and we’ve kind of just zoomed into the whole Eda process there was one last thing that I wanted to show you and this is the very last thing that we’re going to look at we’re ending on really a low point if I’m being honest because the last kind of stuff was more much more exciting but there is something DF DOD types oops let’s do DF DOD types and we’ll run this now just like info it gave us these values but we’re actually able to search on these values now so these um object float and integer we can search on those which is really great because we can do include equal and we can use something like number and none of these are numbers right or none of them EXP say number but when we run it I’m getting an error series object not oh that’s because I’m doing um D types is for a series we need to do select underscore D types now let’s run this now it’s only returning um The Columns in this data frame where the data types are included in this number so you won’t see any you know country or any of those text or the strings if we want to do that we go in here and say object and run that and this is another really quick way where we can just filter those columns to look for specific whether it’s numeric um we could even do float in here and so now it’s not including that rank which was an integer so we can specify the type of data type and it’ll filter all of the columns based off of that which you know when you’re doing stuff like this you it is good to know what kind of data types you’re working with and look at just those types of data types because there might might be some type of analysis you want to perform on just that whether it’s numeric or just the string or integer columns within your data set so again ending on a low note I apologize um you know everything else that we looked at all those other things that we looked at are all things that I typically do in some way or another when I’m looking at a data set exploratory data analysis is really just the first look you’re looking at it you’re going to be cleaning it up doing the data cleaning process and then you’re going to be doing your actual data analysis actually finding those Trends and patterns and then visualizing it um in some way to find some kind of meaning or Insight or value from that data and again there’s a thousand different ways you can go about this it it does typically um you know depend on the data set but these are a lot of the ways that you’ll clean a lot of different data sets and so you know that’s why I went into the things that we looked at in this video so I hope that you guys liked it I hope that you enjoyed something in this tutorial if you like this video be sure to like And subscribe as well as check out all my other videos on pandas and Python and I will see you in the next video [Music]

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • PyTorch Deep Learning & Machine Learning

    PyTorch Deep Learning & Machine Learning

    This PDF excerpt details a PyTorch deep learning course. The course teaches PyTorch fundamentals, including tensor manipulation and neural network architecture. It covers various machine learning concepts, such as linear and non-linear regression, classification (binary and multi-class), and computer vision. Practical coding examples using Google Colab are provided throughout, demonstrating model building, training, testing, saving, and loading. The course also addresses common errors and troubleshooting techniques, emphasizing practical application and experimentation.

    PyTorch Deep Learning Study Guide

    Quiz

    1. What is the difference between a scalar and a vector? A scalar is a single number, while a vector has magnitude and direction and is represented by multiple numbers in a single dimension.
    2. How can you determine the number of dimensions of a tensor? You can determine the number of dimensions of a tensor by counting the number of pairs of square brackets, or by calling the endim function on a tensor.
    3. What is the purpose of the .shape attribute of a tensor? The .shape attribute of a tensor returns a tuple that represents the size of each dimension of the tensor. It indicates the number of elements in each dimension, providing information about the tensor’s structure.
    4. What does the dtype of a tensor represent? The dtype of a tensor represents the data type of the elements within the tensor, such as float32, float16, or int32. It specifies how the numbers are stored in memory, impacting precision and memory usage.
    5. What is the difference between reshape and view when manipulating tensors? Both reshape and view change the shape of a tensor. Reshape copies data and allocates new memory, while view creates a new view of the existing tensor data, meaning that changes in the view will impact the original data.
    6. Explain what tensor aggregation is and provide an example. Tensor aggregation involves reducing the number of elements in a tensor by applying an operation like min, max, or mean. For example, finding the minimum value in a tensor reduces all of the elements to a single number.
    7. What does the stack function do to tensors and how is it different from unsqueeze? The stack function concatenates a sequence of tensors along a new dimension, increasing the dimensions of the tensor by one. The unsqueeze adds a single dimension to a target tensor at a specified dimension.
    8. What does the term “device agnostic code” mean, and why is it important in PyTorch? Device-agnostic code in PyTorch means writing code that can run on either a CPU or GPU without modification. This is important for portability and leveraging the power of GPUs when available.
    9. In PyTorch, what is a “parameter”, how is it created, and what special property does it have? A “parameter” is a special type of tensor created using nn.parameter that is a module attribute. When assigned as a module attribute, parameters are automatically added to a module’s parameter list, enabling gradient tracking during training.
    10. Explain the primary difference between the training loop and the testing/evaluation loop in a neural network. The training loop involves the forward pass, loss calculation, backpropagation and updating the model’s parameters through optimization, whereas the testing/evaluation loop involves only the forward pass and loss and/or accuracy calculation without gradient calculation and parameter updates.

    Essay Questions

    1. Discuss the importance of tensor operations in deep learning. Provide specific examples of how reshaping, indexing, and aggregation are utilized.
    2. Explain the significance of data types in PyTorch tensors, and elaborate on the potential issues that can arise from data type mismatches during tensor operations.
    3. Compare and contrast the use of reshape, view, stack, squeeze, and unsqueeze when dealing with tensors. In what scenarios might one operation be preferable over another?
    4. Describe the key steps involved in the training loop of a neural network. Explain the role of the loss function, optimizer, and backpropagation in the learning process.
    5. Explain the purpose of the torch.utils.data.DataLoader and the advantages it provides. Discuss how it can improve the efficiency and ease of use of data during neural network training.

    Glossary

    Scalar: A single numerical value. It has no direction or multiple dimensions.

    Vector: A mathematical object that has both magnitude and direction, often represented as an ordered list of numbers, i.e. in one dimension.

    Matrix: A rectangular array of numbers arranged in rows and columns, i.e. in two dimensions.

    Tensor: A generalization of scalars, vectors, and matrices. It can have any number of dimensions.

    Dimension (dim): Refers to the number of indices needed to address individual elements in a tensor, which is also the number of bracket pairs.

    Shape: A tuple that describes the size of each dimension of a tensor.

    Dtype: The data type of the elements in a tensor, such as float32, int64, etc.

    Indexing: Selecting specific elements or sub-tensors from a tensor using their positions in the dimensions.

    Reshape: Changing the shape of a tensor while preserving the number of elements.

    View: Creating a new view of a tensor’s data without copying. Changing the view will change the original data, and vice versa.

    Aggregation: Reducing the number of elements in a tensor by applying an operation (e.g., min, max, mean).

    Stack: Combining multiple tensors along a new dimension.

    Squeeze: Removing dimensions of size 1 from a tensor.

    Unsqueeze: Adding a new dimension of size 1 to a tensor.

    Device: The hardware on which computations are performed (e.g., CPU, GPU).

    Device Agnostic Code: Code that can run on different devices (CPU or GPU) without modification.

    Parameter (nn.Parameter): A special type of tensor that can be tracked during training, is a module attribute and is automatically added to a module’s parameter list.

    Epoch: A complete pass through the entire training dataset.

    Training Loop: The process of iterating through the training data, calculating loss, and updating model parameters.

    Testing/Evaluation Loop: The process of evaluating model performance on a separate test dataset.

    DataLoader: A utility in PyTorch that creates an iterable over a dataset, managing batching and shuffling of the data.

    Flatten: A layer that flattens a multi-dimensional tensor into a single dimension.

    PyTorch Deep Learning Fundamentals

    Okay, here’s a detailed briefing document summarizing the key themes and ideas from the provided source, with relevant quotes included:

    Briefing Document: PyTorch Deep Learning Fundamentals

    Introduction:

    This document summarizes the core concepts and practical implementations of PyTorch for deep learning, as detailed in the provided course excerpts. The focus is on tensors, their properties, manipulations, and usage within the context of neural network building and training.

    I. Tensors: The Building Blocks

    • Definition: Tensors are the fundamental data structure in PyTorch, used to encode data as numbers. Traditional terms like scalars, vectors, and matrices are all represented as tensors in PyTorch.
    • “basically anytime you encode data into numbers, it’s of a tensor data type.”
    • Scalars: A single number.
    • “A single number, number of dimensions, zero.”
    • Vectors: Have magnitude and direction and typically have more than one number.
    • “a vector typically has more than one number”
    • “a number with direction, number of dimensions, one”
    • Matrices: Two-dimensional tensors.
    • “a matrix, a tensor.”
    • Dimensions (ndim): Represented by the number of square bracket pairings in the tensor’s definition.
    • “dimension is like number of square brackets…number of pairs of closing square brackets.”
    • Shape: Defines the size of each dimension in a tensor.
    • For example, a vector [1, 2] has a shape of (2,) or (2,1). A matrix [[1, 2], [3, 4]] has a shape of (2, 2).
    • “the shape of the vector is two. So we have two by one elements.”
    • Data Type (dtype): Tensors have a data type (e.g., float32, float16, int32, long). The default dtype in PyTorch is float32.
    • “the default data type in pytorch, even if it’s specified as none is going to come out as float 32.”
    • It’s important to ensure tensors have compatible data types when performing operations to avoid errors.
    • Device: Tensors can reside on different devices, such as the CPU or GPU (CUDA). Device-agnostic code is recommended to handle this.

    II. Tensor Creation and Manipulation

    • Creation:torch.tensor(): Creates tensors from lists or NumPy arrays.
    • torch.zeros(): Creates a tensor filled with zeros.
    • torch.ones(): Creates a tensor filled with ones.
    • torch.arange(): Creates a 1D tensor with a range of values.
    • torch.rand(): Creates a tensor with random values.
    • torch.randn(): Creates a tensor with random values from normal distribution.
    • torch.zeros_like()/torch.ones_like()/torch.rand_like(): Creates tensors with the same shape as another tensor.
    • Indexing: Tensors can be accessed via numerical indices, allowing one to extract elements or subsets.
    • “This is where the square brackets, the pairings come into play.”
    • Reshaping:reshape(): Changes the shape of a tensor, provided the total number of elements remains the same.
    • view(): Creates a view of the tensor, sharing the same memory, but does not change the shape of the original tensor. Modifying a view changes the original tensor.
    • Stacking: torch.stack() concatenates tensors along a new dimension. torch.vstack() and torch.hstack() are similar along specific axes.
    • Squeezing and Unsqueezing: squeeze() removes dimensions of size 1, and unsqueeze() adds dimensions of size 1.
    • Element-wise operations: standard operations like +, -, *, / are applied element-wise.
    • If reassigning the tensor variable (e.g., tensor = tensor * 10), the original tensor will be changed.
    • Matrix Multiplication: Use @ operator (or .matmul() function). Inner dimensions must match for valid matrix multiplication.
    • “inner dimensions must match.”
    • Transpose: tensor.T will tranpose a tensor (swap rows/columns)
    • Aggregation: Functions like torch.min(), torch.max(), torch.mean(), and their respective index finders like torch.argmin()/torch.argmax() reduce the tensor to scalar values.
    • “So you’re turning it from nine elements to one element, hence aggregation.”
    • Attributes: tensors have attributes like dtype, shape (or size), and can be retrieved with tensor.dtype or tensor.shape (or tensor.size())

    III. Neural Networks with PyTorch

    • torch.nn Module: The module provides building blocks for creating neural networks.
    • “nn is the building block layer for neural networks.”
    • nn.Module: The base class for all neural network modules. Custom models should inherit from this class.
    • Linear Layers (nn.Linear): Represents a linear transformation (y = Wx + b).
    • Activation Functions: Non-linear functions such as ReLU (Rectified Linear Unit) and Sigmoid, enable neural networks to learn complex patterns.
    • “one divided by one plus torch exponential of negative x.”
    • Parameter (nn.Parameter): A special type of tensor that is added to a module’s parameter list, allowing automatic gradient tracking
    • “Parameters are torch tensor subclasses…automatically added to the list of its parameters.”
    • It’s critical to set requires_grad=True for parameters that need to be optimized during training.
    • Sequential Container (nn.Sequential): A convenient way to create models by stacking layers in a sequence.
    • Forward Pass: The computation of the model’s output given the input data. This is implemented in the forward() method of a class inheriting from nn.Module.
    • “Do the forward pass.”
    • Loss Functions: Measure the difference between the predicted and actual values.
    • “Calculate the loss.”
    • Optimizers: Algorithms that update the model’s parameters based on the loss function during training (e.g., torch.optim.SGD).
    • “optimise a step, step, step.”
    • Use optimizer.zero_grad() to reset the gradients before each training step.
    • Training Loop: The iterative process of:
    1. Forward pass
    2. Calculate Loss
    3. Optimizer zero grad
    4. Loss backwards
    5. Optimizer Step
    • Evaluation Mode: Set the model to model.eval() before doing inference (testing/evaluation), and it sets requires_grad=False

    IV. Data Handling

    • torch.utils.data.Dataset: A class for representing datasets, and custom datasets can be built using this.
    • torch.utils.data.DataLoader: An iterable to batch data for use during training.
    • “This creates a Python iterable over a data set.”
    • Transforms: Functions that modify data (e.g., images) before they are used in training. They can be composed together.
    • “This little transforms module, the torch vision library will change that back to 64 64.”
    • Device Agnostic Data: Send data to the appropriate device (CPU/GPU) using .to(device)
    • NumPy Interoperability: PyTorch can handle NumPy arrays with torch.from_numpy(), but the data type needs to be changed to torch.float32 from float64

    V. Visualization

    • Matplotlib: Library is used for visualizing plots and images.
    • “Our data explorers motto is visualize, visualize, visualize.”
    • plt.imshow(): Displays images.
    • plt.plot(): Displays data in a line plot.

    VI. Key Practices

    • Visualize, Visualize, Visualize: Emphasized for data exploration.
    • Device-Agnostic Code: Aim to write code that can run on both CPU and GPU.
    • Typo Avoidance: Be careful to avoid typos as they can cause errors.

    VII. Specific Examples/Concepts Highlighted:

    • Image data: tensors are often (height, width, color_channels) or (batch_size, color_channels, height, width)
    • Linear regression: the formula y=weight * x + bias
    • Non linear transformations: using activation functions to introduce non-linearity
    • Multi-class data sets: Using make_blobs function to generate multiple data classes.
    • Convolutional layers (nn.Conv2d): For processing images, which require specific parameters like in-channels, out-channels, kernel size, stride, and padding.
    • Flatten layer (nn.Flatten): Used to flatten the input into a vector before a linear layer.
    • Data Loaders: Batches of data in an iterable for training or evaluation loops.

    Conclusion:

    This document provides a foundation for understanding the essential elements of PyTorch for deep learning. It highlights the importance of tensors, their manipulation, and their role in building and training neural networks. Key concepts such as the training loop, device-agnostic coding, and the value of visualization are also emphasized.

    This briefing should serve as a useful reference for anyone learning PyTorch and deep learning fundamentals from these course materials.

    PyTorch Fundamentals: Tensors and Neural Networks

    1. What is a tensor in PyTorch and how does it relate to scalars, vectors, and matrices?

    In PyTorch, a tensor is the fundamental data structure used to represent data. Think of it as a generalization of scalars, vectors, and matrices. A scalar is a single number (0 dimensions), a vector has magnitude and direction, and is represented by one dimension, while a matrix has two dimensions. Tensors can have any number of dimensions and can store numerical data of various types. In essence, when you encode any kind of data into numbers within PyTorch, it becomes a tensor. PyTorch uses the term tensor to refer to any of these data types.

    2. How are the dimensions and shape of a tensor determined?

    The dimension of a tensor can be determined by the number of square bracket pairs used to define it. For example, [1, 2, 3] is a vector with one dimension (one pair of square brackets), and [[1, 2], [3, 4]] is a matrix with two dimensions (two pairs). The shape of a tensor refers to the size of each dimension. For instance, [1, 2, 3] has a shape of (3), meaning 3 elements in the first dimension, while [[1, 2], [3, 4]] has a shape of (2, 2), meaning 2 rows and 2 columns. Note: The shape is determined by the number of elements in each dimension.

    3. How do you create tensors with specific values in PyTorch?

    PyTorch provides various functions to create tensors:

    • torch.tensor([value1, value2, …]) directly creates a tensor from a Python list. You can control the data type (dtype) of the tensor during its creation by passing the dtype argument.
    • torch.zeros(size) creates a tensor filled with zeros of the specified size.
    • torch.ones(size) creates a tensor filled with ones of the specified size.
    • torch.rand(size) creates a tensor filled with random values from a uniform distribution (between 0 and 1) of the specified size.
    • torch.arange(start, end, step) creates a 1D tensor containing values from start to end (exclusive), incrementing by step.
    • torch.zeros_like(other_tensor) and torch.ones_like(other_tensor) create tensors with the same shape and dtype as the other_tensor, filled with zeros or ones respectively.

    4. What is the importance of data types (dtypes) in tensors, and how can they be changed?

    Data types determine how data is stored in memory, which has implications for precision and memory usage. The default data type in PyTorch is torch.float32. To change a tensor’s data type, you can use the .type() method, e.g. tensor.type(torch.float16) will convert a tensor to 16 bit float. While PyTorch can often automatically handle operations between different data types, using the correct data type can prevent unexpected errors or behaviors. It’s good to be explicit.

    5. What are tensor attributes such as shape, size, and Dtype and how do they relate to tensor manipulation?

    These are attributes that can be used to understand, manipulate, and diagnose issues with tensors.

    • Shape: An attribute that represents the dimensions of the tensor. For example, a matrix might have a shape of (3, 4), indicating it has 3 rows and 4 columns. You can access this information by using .shape
    • Size: Acts like .shape but is a method i.e. .size(). It will return the dimensions of the tensor.
    • Dtype: Stands for data type. This defines the way the data is stored and impacts precision and memory use. You can access this by using .dtype.

    These attributes can be used to diagnose issues, for example you might want to ensure all tensors have compatible data types and dimensions for multiplication.

    6. How do operations like reshape, view, stack, unsqueeze, and squeeze modify the shape of tensors?

    • reshape(new_shape): Changes the shape of a tensor to a new shape, as long as the total number of elements remains the same, a tensor with 9 elements can be reshaped into (3, 3) or (9, 1) for example.
    • view(new_shape): Similar to reshape, but it can only be used to change the dimensions of a contiguous tensor (a tensor that has elements in continuous memory) and will also share the same memory as the original tensor meaning changes will impact each other.
    • stack(tensors, dim): Concatenates multiple tensors along a new dimension (specified by dim) and increases the overall dimensionality by 1.
    • unsqueeze(dim): Inserts a new dimension of size one at a specified position, increasing the overall dimensionality by 1.
    • squeeze(): Removes all dimensions with size one in a tensor, reducing overall dimensionality of a tensor.

    7. What are the key components of a basic neural network training loop?

    The key components include:

    • Forward Pass: The input data goes through the model, producing the output.
    • Calculate Loss: The error is calculated by comparing the output to the true labels.
    • Zero Gradients: Previous gradients are cleared before starting a new iteration to prevent accumulating them across iterations.
    • Backward Pass: The error is backpropagated through the network to calculate gradients.
    • Optimize Step: The model’s parameters are updated based on the gradients using an optimizer.
    • Testing / Validation Step: The model’s performance is evaluated against a test or validation dataset.

    8. What is the purpose of torch.nn.Module and torch.nn.Parameter in PyTorch?

    • torch.nn.Module is a base class for creating neural network models. Modules provide a way to organize and group layers and functions, such as linear layers, activation functions, and other model components. It keeps track of learnable parameters.
    • torch.nn.Parameter is a special subclass of torch.Tensor that is used to represent the learnable parameters of a model. When parameters are assigned as module attributes, PyTorch automatically registers them for gradient tracking and optimization. It tracks gradient when ‘requires_grad’ is set to true. Setting requires_grad=True on parameters tells PyTorch to calculate and store gradients for them during backpropagation.

    PyTorch: A Deep Learning Framework

    PyTorch is a machine learning framework written in Python that is used for deep learning and other machine learning tasks [1]. The framework is popular for research and allows users to write fast deep learning code that can be accelerated by GPUs [2, 3].

    Key aspects of PyTorch include:

    • Tensors: PyTorch uses tensors as a fundamental building block for numerical data representation. These can be of various types, and neural networks perform mathematical operations on them [4, 5].
    • Neural Networks: PyTorch is often used for building neural networks, including fully connected and convolutional neural networks [6]. These networks are constructed using layers from the torch.nn module [7].
    • GPU Acceleration: PyTorch can leverage GPUs via CUDA to accelerate machine learning code. GPUs are fast at numerical calculations, which are very important in deep learning [8-10].
    • Flexibility: The framework allows for customization, and users can combine layers in different ways to build various kinds of neural networks [6, 11].
    • Popularity: PyTorch is a popular research machine learning framework, with 58% of papers with code implemented using PyTorch [2, 12, 13]. It is used by major organizations such as Tesla, OpenAI, Facebook, and Microsoft [14-16].

    The typical workflow when using PyTorch for deep learning includes:

    • Data Preparation: The first step is getting the data ready, which can involve numerical encoding, turning the data into tensors, and loading the data [17-19].
    • Model Building: PyTorch models are built using the nn.Module class as a base and defining the forward computation [20-23]. This includes choosing appropriate layers and defining their interconnections [11].
    • Model Fitting: The model is fitted to the data using an optimization loop and a loss function [19]. This involves calculating gradients using back propagation and updating model parameters using gradient descent [24-27].
    • Model Evaluation: Model performance is evaluated by measuring how well the model performs on unseen data, using metrics such as accuracy and loss [28].
    • Saving and Loading: Trained models can be saved and reloaded using the torch.save, torch.load, and torch.nn.Module.load_state_dict functions [29, 30].

    Some additional notes on PyTorch include:

    • Reproducibility: Randomness is important in neural networks; it’s necessary to set random seeds to ensure reproducibility of experiments [31, 32].
    • Device Agnostic Code: It’s useful to write device agnostic code, which means code that can run on either a CPU or a GPU [33, 34].
    • Integration: PyTorch integrates well with other libraries, such as NumPy, which is useful for pre-processing and other numerical tasks [35, 36].
    • Documentation: The PyTorch website and documentation serve as the primary resource for learning about the framework [2, 37, 38].
    • Community Support: Online forums and communities provide places to ask questions and share code [38-40].

    Overall, PyTorch is a very popular and powerful tool for deep learning and machine learning [2, 12, 13]. It provides tools to enable users to build, train, and deploy neural networks with ease [3, 16, 41].

    Understanding Machine Learning Models

    Machine learning models learn patterns from data, which is converted into numerical representations, and then use these patterns to make predictions or classifications [1-4]. The models are built using code and math [1].

    Here are some key aspects of machine learning models based on the sources:

    • Data Transformation: Machine learning models require data to be converted into numbers, a process sometimes called numerical encoding [1-4]. This can include images, text, tables of numbers, audio files, or any other type of data [1].
    • Pattern Recognition: After data is converted to numbers, machine learning models use algorithms to find patterns in that data [1, 3-5]. These patterns can be complex and are often not interpretable by humans [6, 7]. The models can learn patterns through code, using algorithms to find the relationships in the numerical data [5].
    • Traditional Programming vs. Machine Learning: In traditional programming, rules are hand-written to manipulate input data and produce desired outputs [8]. In contrast, machine learning algorithms learn these rules from data [9, 10].
    • Supervised Learning: Many machine learning algorithms use supervised learning. This involves providing input data along with corresponding output data (features and labels), and then the algorithm learns the relationships between the inputs and outputs [9].
    • Parameters: Machine learning models learn parameters that represent the patterns in the data [6, 11]. Parameters are values that the model sets itself [12]. These are often numerical and can be large, sometimes numbering in the millions or even trillions [6].
    • Explainability: The patterns learned by a deep learning model are often uninterpretable by a human [6]. Sometimes, these patterns are lists of numbers in the millions, which is difficult for a person to understand [6, 7].
    • Model Evaluation: The performance of a machine learning model can be evaluated by making predictions and comparing those predictions to known labels or targets [13-15]. The goal of training a model is to move from some unknown parameters to a better, known representation of the data [16]. The loss function is used to measure how wrong a model’s predictions are compared to the ideal predictions [17].
    • Model Types: Machine learning models include:
    • Linear Regression: Models which use a linear formula to draw patterns in data [18]. These models use parameters such as weights and biases to perform forward computation [18].
    • Neural Networks: Neural networks are the foundation of deep learning [19]. These are typically used for unstructured data such as images [19, 20]. They use a combination of linear and non-linear functions to draw patterns in data [21-23].
    • Convolutional Neural Networks (CNNs): These are a type of neural network often used for computer vision tasks [19, 24]. They process images through a series of layers, identifying spatial features in the data [25].
    • Gradient Boosted Machines: Algorithms such as XGBoost are often used for structured data [26].
    • Use Cases: Machine learning can be applied to virtually any problem where data can be converted into numbers and patterns can be found [3, 4]. However, simple rule-based systems are preferred if they can solve a problem, and machine learning should not be used simply because it can [5, 27]. Machine learning is useful for complex problems with long lists of rules [28, 29].
    • Model Training: The training process is iterative and involves multiple steps, and it can also be seen as an experimental process [30, 31]. In each step, the machine learning model is used to make predictions and its parameters are adjusted to minimize error [13, 32].

    In summary, machine learning models are algorithms that can learn patterns from data by converting the data into numbers, using various algorithms, and adjusting parameters to improve performance. Models are typically evaluated against known data with a loss function, and there are many types of models and use cases depending on the type of problem [6, 9-11, 13, 32].

    Understanding Neural Networks

    Neural networks are a type of machine learning model inspired by the structure of the human brain [1]. They are comprised of interconnected nodes, or neurons, organized in layers, and they are used to identify patterns in data [1-3].

    Here are some key concepts for understanding neural networks:

    • Structure:
    • Layers: Neural networks are made of layers, including an input layer, one or more hidden layers, and an output layer [1, 2]. The ‘deep’ in deep learning comes from having multiple hidden layers [1, 4].
    • Nodes/Neurons: Each layer is composed of nodes or neurons [4, 5]. Each node performs a mathematical operation on the input it receives.
    • Connections: Nodes in adjacent layers are connected, and these connections have associated weights that are adjusted during the learning process [6].
    • Architecture: The arrangement of layers and connections determines the neural network’s architecture [7].
    • Function:
    • Forward Pass: In a forward pass, input data is passed through the network, layer by layer [8]. Each layer performs mathematical operations on the input, using linear and non-linear functions [5, 9].
    • Mathematical Operations: Each layer is typically a combination of linear (straight line) and nonlinear (non-straight line) functions [9].
    • Nonlinearity: Nonlinear functions, such as ReLU or sigmoid, are critical for enabling the network to learn complex patterns [9-11].
    • Representation Learning: The network learns a representation of the input data by manipulating patterns and features through its layers [6, 12]. This representation is also called a weight matrix or weight tensor [13].
    • Output: The output of the network is a representation of the learned patterns, which can be converted into a human-understandable format [12-14].
    • Learning Process:
    • Random Initialization: Neural networks start with random numbers as parameters, and they adjust those numbers to better represent the data [15, 16].
    • Loss Function: A loss function is used to measure how wrong the model’s predictions are compared to ideal predictions [17-19].
    • Backpropagation: Backpropagation is an algorithm that calculates the gradients of the loss with respect to the model’s parameters [20].
    • Gradient Descent: Gradient descent is an optimization algorithm used to update model parameters to minimize the loss function [20, 21].
    • Types of Neural Networks:
    • Fully Connected Neural Networks: These networks have connections between all nodes in adjacent layers [1, 22].
    • Convolutional Neural Networks (CNNs): CNNs are particularly useful for processing images and other visual data, and they use convolutional layers to identify spatial features [1, 23, 24].
    • Recurrent Neural Networks (RNNs): These are often used for sequence data [1, 25].
    • Transformers: Transformers have become popular in recent years and are used in natural language processing and other applications [1, 25, 26].
    • Customization: Neural networks are highly customizable, and they can be designed in many different ways [4, 25, 27]. The specific architecture and layers used are often tailored to the specific problem at hand [22, 24, 26-28].

    Neural networks are a core component of deep learning, and they can be applied to a wide range of problems including image recognition, natural language processing, and many others [22, 23, 25, 26]. The key to using neural networks effectively is to convert data into a numerical representation, design a network that can learn patterns from the data, and use optimization techniques to train the model.

    Machine Learning Model Training

    The model training process in machine learning involves using algorithms to adjust a model’s parameters so it can learn patterns from data and make accurate predictions [1, 2]. Here’s an overview of the key steps in training a model, according to the sources:

    • Initialization: The process begins with a model that has randomly assigned parameters, such as weights and biases [1, 3]. These parameters are what the model adjusts during training [4, 5].
    • Data Input: The training process requires input data to be passed through the model [1]. The data is typically split into a training set for learning and a test set for evaluation [6].
    • Forward Pass: Input data is passed through the model, layer by layer [7]. Each layer performs mathematical operations on the input, which may include both linear and nonlinear functions [8]. This forward computation produces a prediction, called the model’s output or sometimes logits [9, 10].
    • Loss Calculation: A loss function is used to measure how wrong the model’s predictions are compared to the ideal outputs [4, 11]. The loss function provides a numerical value that represents the error or deviation of the model’s predictions from the actual values [12]. The goal of the training process is to minimize this loss [12, 13].
    • Backpropagation: After the loss is calculated, the backpropagation algorithm computes the gradients of the loss with respect to the model’s parameters [2, 14, 15]. Gradients indicate the direction and magnitude of the change needed to reduce the loss [1].
    • Optimization: An optimizer uses the calculated gradients to update the model’s parameters [4, 11, 16]. Gradient descent is a commonly used optimization algorithm that adjusts the parameters to minimize the loss [1, 2, 15]. The learning rate is a hyperparameter that determines the size of the adjustments [5, 17].
    • Training Loop: The process of forward pass, loss calculation, backpropagation, and optimization is repeated iteratively through a training loop [11, 17, 18]. The training loop is where the model learns patterns on the training data [19]. Each iteration of the loop is called an epoch [20].
    • Evaluation: After training, the model’s performance is evaluated on a separate test data set [19]. This evaluation helps to measure how well the model has learned and whether it can generalize to unseen data [21].

    In PyTorch, the training loop typically involves these steps:

    1. Setting the model to training mode using model.train() [22, 23]. This tells the model to track gradients so that they can be used to update the model’s parameters [23].
    2. Performing a forward pass by passing the data through the model.
    3. Calculating the loss by comparing the model’s prediction with the actual data labels.
    4. Setting gradients to zero using optimizer.zero_grad() [24].
    5. Performing backpropagation using loss.backward() [15, 24].
    6. Updating the model’s parameters using optimizer.step() [24].

    During training, models can have two modes: train and evaluation.

    • The train mode tracks gradients and other settings to learn from the data [22, 23].
    • The evaluation mode turns off settings not needed for evaluation such as dropout, and it turns off gradient tracking to make the code run faster [25, 26].

    Other key points about the model training process are:

    • Hyperparameters: The training process involves the use of hyperparameters, which are values set by the user, like the learning rate or the number of epochs [5, 23].
    • Experimentation: Model training is often an experimental process, with various parameters and settings being tried to find the best performing model [27, 28].
    • Data: The quality and quantity of the training data has a big effect on the model’s performance [29, 30].
    • Reproducibility: Randomness is an important part of training; to reproduce results, it is necessary to set random seeds [31, 32].
    • Visualization: Visualizing model training through metrics such as accuracy and loss curves is important in understanding whether the model is learning effectively [33-35].
    • Inference: When making predictions after training, the term inference is also used [36]. Inference uses a model to make predictions using unseen data [26, 36].

    In summary, the model training process in machine learning involves iteratively adjusting a model’s parameters to minimize error by using the techniques of gradient descent and backpropagation [1, 2, 14, 15].

    PyTorch Model Deployment

    The sources discuss model deployment in the context of saving and loading models, which is a key part of making a model usable in an application or other context. Here’s a breakdown of model deployment methods based on the sources:

    • Saving Models:State Dictionary: The recommended way to save a PyTorch model is to save its state dictionary [1, 2]. The state dictionary contains the model’s learned parameters, such as weights and biases [3, 4]. This is more flexible than saving the entire model [2].
    • File Extension: PyTorch models are commonly saved with a .pth or .pt file extension [5].
    • Saving Process: The saving process involves creating a directory path, defining a model name, and then using torch.save() to save the state dictionary to the specified file path [6, 7].
    • Flexibility: Saving the state dictionary provides flexibility in how the model is loaded and used [8].
    • Loading Models:Loading State Dictionary: To load a saved model, you must create a new instance of the model class and then load the saved state dictionary into that instance [4]. This is done using the load_state_dict() method, along with torch.load(), which reads the file containing the saved state dictionary [9, 10].
    • New Instance: When loading a model, it’s important to remember that you must create a new instance of the model class, and then load the saved parameters into that instance using the load_state_dict method [4, 9, 11].
    • Loading Process: The loading process involves creating a new instance of the model and then calling load_state_dict on the model with the file path to the saved model [12].
    • Inference Mode:Evaluation Mode: Before loading a model for use, the model is typically set to evaluation mode by calling model.eval() [13, 14]. This turns off settings not needed for evaluation, such as dropout layers [15-17].
    • Gradient Tracking: It is also common to use inference mode via the context manager torch.inference_mode to turn off gradient tracking, which speeds up the process of making predictions [18-21]. This is used when you are not training the model, but rather using it to make predictions [19].
    • Deployment Context:Reusability: The sources mention that a saved model can be reused in the same notebook or sent to a friend to try out, or used in a week’s time [22].
    • Cloud Deployment: Models can be deployed in applications or in the cloud [23].
    • Model Transfer:Transfer Learning: The source mentions that parameters from one model could be used in another model; this process is called transfer learning [24].
    • Other Considerations:Device Agnostic Code: It is recommended to write code that is device agnostic, so it can run on either a CPU or a GPU [25-27].
    • Reproducibility: Random seeds should be set for reproducibility [28, 29].
    • Model Equivalence: After loading a model, it is important to test that the loaded model is equivalent to the original model by comparing predictions [14, 30-32].

    In summary, model deployment involves saving the trained model’s parameters using its state dictionary, loading these parameters into a new model instance, and using the model in evaluation mode with inference turned on, to make predictions. The sources emphasize the importance of saving models for later use, sharing them, and deploying them in applications or cloud environments.

    PyTorch for Deep Learning & Machine Learning – Full Course

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Learn Python in Under 3 Hours Variables, For Loops, Web Scraping Full Project

    Learn Python in Under 3 Hours Variables, For Loops, Web Scraping Full Project

    The provided text consists of a series of coding tutorials and projects focused on Python. The initial tutorials cover fundamental Python concepts, including Jupyter Notebooks, variables, data types, operators, and conditional statements. Later tutorials explore looping constructs, functions, data type conversions, and practical projects like building a BMI calculator. The final segment introduces web scraping using Beautiful Soup and Requests, culminating in a project to extract and structure data from a Wikipedia table into a Pandas DataFrame and CSV.

    Python Fundamentals: A Study Guide

    Quiz

    1. What is Anaconda, and why is it useful for Python development?
    • Anaconda is an open-source distribution of Python and R, containing tools like Jupyter Notebooks. It simplifies package management and environment setup for Python projects.
    1. Explain the purpose of a Jupyter Notebook cell, and how to execute code within it.
    • A Jupyter Notebook cell is a block where code or markdown text can be written and executed. Code is executed by pressing Shift+Enter, which runs the cell and moves to the next one.
    1. Describe the difference between code cells and markdown cells in a Jupyter Notebook.
    • Code cells contain Python code that can be executed, while markdown cells contain formatted text for notes and explanations. Markdown cells use a simple markup language for formatting.
    1. What is a variable in Python, and how do you assign a value to it?
    • A variable is a named storage location that holds a value. Values are assigned using the assignment operator (=), such as x = 10.
    1. Explain why variable names are case-sensitive, and provide an example.
    • Python treats uppercase and lowercase letters differently in variable names. For example, myVar and myvar are distinct variables.
    1. List three best practices for naming variables in Python.
    • Use descriptive names, follow snake_case (words separated by underscores), and avoid starting names with numbers.
    1. What are the three main numeric data types in Python?
    • The three main numeric data types are integers (whole numbers), floats (decimal numbers), and complex numbers (numbers with a real and imaginary part).
    1. Explain the difference between a list and a tuple in Python.
    • A list is mutable (changeable), while a tuple is immutable (cannot be changed after creation). Lists use square brackets, while tuples use parentheses.
    1. Describe the purpose of comparison operators in Python, and give three examples.
    • Comparison operators compare two values and return a Boolean result (True or False). Examples: == (equal to), != (not equal to), > (greater than).
    1. Explain the purpose of the if, elif, and else statements in Python.
    • if executes a block of code if a condition is true. elif checks additional conditions if the previous if or elif conditions are false. else executes a block of code if none of the preceding conditions are true.

    Quiz Answer Key

    1. Anaconda is an open-source distribution of Python and R, containing tools like Jupyter Notebooks. It simplifies package management and environment setup for Python projects.
    2. A Jupyter Notebook cell is a block where code or markdown text can be written and executed. Code is executed by pressing Shift+Enter, which runs the cell and moves to the next one.
    3. Code cells contain Python code that can be executed, while markdown cells contain formatted text for notes and explanations. Markdown cells use a simple markup language for formatting.
    4. A variable is a named storage location that holds a value. Values are assigned using the assignment operator (=), such as x = 10.
    5. Python treats uppercase and lowercase letters differently in variable names. For example, myVar and myvar are distinct variables.
    6. Use descriptive names, follow snake_case (words separated by underscores), and avoid starting names with numbers.
    7. The three main numeric data types are integers (whole numbers), floats (decimal numbers), and complex numbers (numbers with a real and imaginary part).
    8. A list is mutable (changeable), while a tuple is immutable (cannot be changed after creation). Lists use square brackets, while tuples use parentheses.
    9. Comparison operators compare two values and return a Boolean result (True or False). Examples: == (equal to), != (not equal to), > (greater than).
    10. if executes a block of code if a condition is true. elif checks additional conditions if the previous if or elif conditions are false. else executes a block of code if none of the preceding conditions are true.

    Essay Questions

    1. Discuss the differences between for loops and while loops in Python. Provide examples of situations where each type of loop would be most appropriate.
    2. Explain the concept of web scraping using Python. What libraries are commonly used for web scraping, and what are some ethical considerations involved in web scraping?
    3. Describe the process of defining and calling functions in Python. Explain the purpose of function arguments and return values, and provide examples of how to use them effectively.
    4. Explain the different data types in Python and provide examples of using them in variable assignments, and data manipulation.
    5. Explain the difference between an arbitrary argument, an arbitrary keyword argument, and an ordinary argument, and what are the use cases for each one.

    Glossary of Key Terms

    • Anaconda: An open-source distribution of Python and R used for data science and machine learning, simplifying package management.
    • Jupyter Notebook: An interactive web-based environment for creating and sharing documents containing live code, equations, visualizations, and explanatory text.
    • Cell (Jupyter): A block in a Jupyter Notebook where code or markdown can be entered and executed.
    • Markdown: A lightweight markup language used for formatting text in markdown cells.
    • Variable: A named storage location that holds a value in a program.
    • Data Type: The classification of a value, determining the operations that can be performed on it (e.g., integer, string, list).
    • Integer: A whole number (positive, negative, or zero).
    • Float: A number with a decimal point.
    • String: A sequence of characters.
    • List: An ordered, mutable collection of items.
    • Tuple: An ordered, immutable collection of items.
    • Set: An unordered collection of unique items.
    • Dictionary: A collection of key-value pairs.
    • Comparison Operator: Symbols used to compare two values (e.g., ==, !=, >, <).
    • Logical Operator: Symbols used to combine or modify Boolean expressions (e.g., and, or, not).
    • if Statement: A conditional statement that executes a block of code if a condition is true.
    • elif Statement: A conditional statement that checks an additional condition if the preceding if condition is false.
    • else Statement: A conditional statement that executes a block of code if none of the preceding if or elif conditions are true.
    • for Loop: A control flow statement that iterates over a sequence (e.g., list, tuple, string).
    • while Loop: A control flow statement that repeatedly executes a block of code as long as a condition is true.
    • Function: A reusable block of code that performs a specific task.
    • Argument: A value passed to a function when it is called.
    • Return Value: The value that a function sends back to the caller after it has finished executing.
    • Web Scraping: Extracting data from websites using automated software.
    • Beautiful Soup: A Python library for parsing HTML and XML documents, making it easier to extract data from web pages.
    • Request: The act of asking a URL for its information.
    • HTTP request: A request using the standard “Hypertext Transfer Protocol,” which is the foundation for data communication on the World Wide Web.
    • CSV file: A Comma Separated Value file, which allows data to be saved in a table-structured format.
    • Pandas data frame: A two-dimensional, size-mutable, potentially heterogeneous tabular data structure with labeled axes.
    • List comprehension: An elegant syntax for creating lists based on existing iterables. It provides a concise way to generate lists using a single line of code, making it efficient and readable.

    Python Programming and Web Scraping Tutorial

    Okay, I have reviewed the provided text and here’s a briefing document summarizing its main themes and important ideas:

    Briefing Document: Python Basics and Web Scraping Tutorial

    Overall Theme:

    This document contains the script for a video tutorial aimed at teaching beginners the fundamentals of Python programming, including setting up the environment, covering core concepts, and introducing web scraping with Beautiful Soup. The tutorial is structured as a hands-on lesson, walking the viewer through installing Anaconda, using Jupyter Notebooks, understanding variables, data types, operators, control flow (if/else, for loops, while loops), functions, data type conversions, and finally applying these skills to a web scraping project.

    Key Ideas and Facts:

    • Setting up the Python Environment:
    • The tutorial recommends installing Anaconda, describing it as “an open source distribution of python and our products. So within Anaconda is our jupyter notebooks as well as a lot of other things but we’re going to be using it for our Jupiter notebooks.”
    • It walks through the Anaconda installation process, emphasizing the importance of selecting the correct installer for the operating system (Windows, Mac, or Linux) and system architecture (32-bit or 64-bit).
    • Introduction to Jupyter Notebooks:
    • Jupyter Notebooks are the primary environment for writing and executing Python code in the tutorial. “Right here is where we’re going to be spending 99% of our time in future videos this is where we’re going to write all of our code.”
    • Notebooks are comprised of “cells” where code or markdown can be written.
    • Markdown is introduced as a way to add comments and organization to the notebook: “markdown is its own kind of you could say language but um it’s just a different way of writing especially within a notebook.”
    • Basic notebook operations are explained, including saving, renaming, inserting/deleting cells, copying/pasting cells, moving cells, running code, interrupting the kernel, and restarting the kernel.
    • Python Variables:
    • A variable is defined as “basically just a container for storing data values.”
    • Variables are dynamically typed in Python, meaning the data type is automatically assigned based on the value assigned to the variable.
    • Variables can be overwritten with new values.
    • Multiple variables can be assigned values simultaneously (e.g., x, y, z = 1, 2, 3).
    • Multiple variables can be assigned the same value (e.g., x = y = z = “hello”).
    • Lists, dictionaries, tuples, and sets can all be assigned to variables.
    • The tutorial covers naming conventions such as camel case, Pascal case, and snake case, recommending snake case for readability: “when I’m naming variables I usually write it in snake case because I just find it a lot easier to read because each word is broken up by this underscore”.
    • It also covers invalid naming practices and what symbols can be used within variable names.
    • Strings can be concatenated using the + operator, but you can’t directly concatenate strings and numbers within a variable assignment (you can in a print statement using commas).
    • Python Data Types:
    • The tutorial covers the main data types in Python.
    • Numeric: Integers, floats, and complex numbers.
    • Boolean: True or False values.
    • Sequence Types: Strings, lists, and tuples.
    • Set: Unordered collections of unique elements.
    • Dictionary: Key-value pairs.
    • Strings can be defined with single quotes, double quotes, or triple quotes (for multi-line strings). Strings are arrays of bytes representing Unicode characters.
    • Indexing in strings starts at zero and can use negative indices to access characters from the end of the string. Slicing also works.
    • Lists are mutable, meaning their elements can be changed after creation using their indexes. Lists are index just like a string is. “One of the best things about lists is you can have any data type within them.”
    • Tuples are immutable, and lists and tuples are very similar with that being one main exception. “typically people will use tupal for when data is never going to change”.
    • Sets only contain unique values and are unordered.
    • Dictionaries store key-value pairs, and values are accessed by their associated keys. Dictionaries are changeable. “within a data type we have something called a key value pair… we have a key that indicates what that value is attributed to”.
    • Operators:
    • Comparison Operators: Used to compare values (e.g., ==, !=, >, <, >=, <=).
    • Logical Operators: Used to combine or modify boolean expressions (and, or, not).
    • Membership Operators: Used to check if a value exists within a sequence (in, not in).
    • Control Flow:
    • If/Elif/Else Statements: Used to execute different blocks of code based on conditions. The tutorial mentions “You can have as many ill if statements as you want but you can only have one if statement and one else statement”. Nested if statements are also covered.
    • For Loops: Used to iterate over a sequence, the diagram in the text walks through this, ending in “exit the loop and the for loop would be over”.
    • While Loops: Used to repeatedly execute a block of code as long as a condition is true. Break statements, continue statements, and using else statements to create a “counter” are also covered.
    • Functions:
    • Functions are defined using the def keyword.
    • Arguments can be passed to functions.
    • The tutorial describes many types of arguments including custom arguments, multiple arguments, arbitrary arguments, and keyword arguments. Arbitrary arguments use *args, and arbitrary keyword arguments use **kwargs.
    • Data Type Conversion:
    • Functions like int(), str(), list(), tuple(), and set() are used to convert between data types. This is important because the tutorial also says “it cannot add both an integer and a string.” Converting a list to a set automatically removes duplicate elements.
    • BMI Calculator Project:
    • The tutorial walks through building a BMI calculator.
    • The program takes user input for weight (in pounds) and height (in inches).
    • The BMI is calculated using the formula: weight * 703 / (height * height).
    • The program then uses if/elif/else statements to categorize the BMI into categories like underweight, normal weight, overweight, obese, severely obese, and morbidly obese.
    • The program uses input() for user input, which is then converted to an integer.
    • Web Scraping Project:
    • Introduction to Web Scraping: Web scraping is the process of extracting data from websites.
    • Libraries Used:requests: Used to send HTTP requests to retrieve the HTML content of a webpage.
    • Beautiful Soup: Used to parse the HTML content and make it easier to navigate and extract data. “Beautiful Soup takes this messy HTML or XML and makes it into beautiful soup”.
    • pandas: Used for data manipulation and analysis, specifically creating a DataFrame to store the scraped data. “We can use Pandas and manipulate this”.
    1. Steps in Web Scraping:Send a Request: Use the requests library to get the HTML content of the target webpage.
    2. Parse the HTML: Use Beautiful Soup to parse the HTML content into a navigable data structure.
    3. Locate Elements: Use Beautiful Soup’s methods (e.g., find(), find_all()) to locate the specific HTML elements containing the data you want to extract.
    4. Extract Data: Extract the text or attributes from the located HTML elements.
    5. Store Data: Store the extracted data in a structured format, such as a pandas DataFrame or a CSV file.
    • Key Beautiful Soup Methods:find(): Finds the first element that matches the specified criteria.
    • find_all(): Finds all elements that match the specified criteria.
    • HTML Element Attributes: The tutorial mentions the importance of HTML element attributes (e.g., class, href, id) for targeting specific elements with Beautiful Soup.
    • Targeting Elements with Classes: The .find() and .find_all() methods can be used to select elements based on their CSS classes.
    • Navigating HTML Structure: The tutorial demonstrated how to navigate the HTML structure to locate specific data elements, particularly focusing on table, tr (table row), and td (table data) tags.
    • Data Cleaning: The tutorial showed how to clean up the extracted data by stripping whitespace from the beginning and end of the strings.
    • Creating Pandas DataFrame: The scraped data is organized and stored into a pandas DataFrame.
    • Exporting Data to CSV: The tutorial shows how to export the data in a data frame to a CSV file.

    Quotes:

    • “Right here is where we’re going to be spending 99% of our time in future videos this is where we’re going to write all of our code.”
    • “a variable is basically just a container for storing data values.”
    • “when I’m naming variables I usually write it in snake case because I just find it a lot easier to read because each word is broken up by this underscore”
    • “typically people will use tupal for when data is never going to change”
    • “Beautiful Soup takes this messy HTML or XML and makes it into beautiful soup”
    • “we can use Pandas and manipulate this”
    • “It cannot add both an integer and a string”

    Overall Assessment:

    The provided text outlines a comprehensive introductory Python tutorial suitable for individuals with little to no prior programming experience. It covers a wide range of essential concepts and techniques, culminating in practical projects that demonstrate how these skills can be applied. The step-by-step approach and clear explanations, supplemented by hands-on examples, should make it accessible and engaging for beginners. However, some familiarity with HTML is assumed for the web scraping portion.

    Python Programming: Basics and Fundamentals

    Python Basics & Setup

    1. What is Anaconda and why is it recommended for Python beginners?

    Anaconda is an open-source distribution of Python and R, containing tools like Jupyter Notebooks. It simplifies setting up a Python environment, especially for beginners, by providing pre-installed packages and tools, avoiding individual installations and configurations that can be complex.

    2. What is a Jupyter Notebook and how do you use it to write and run Python code?

    A Jupyter Notebook is an interactive environment where you can write and execute Python code, as well as include formatted text (Markdown), images, and other content. You create cells within the notebook, type code, and then run each cell individually by pressing Shift+Enter.

    3. What are variables in Python and why are they useful?

    Variables are containers for storing data values. They are useful because they allow you to assign a name to a value (like a number, string, or list) and then refer to that value throughout your code by using the variable name, without having to rewrite the value itself.

    4. How does Python automatically determine the data type of a variable, and what are some common data types?

    Python uses dynamic typing, meaning it automatically infers the data type of a variable based on the value assigned to it. Common data types include integers (whole numbers), floats (decimal numbers), strings (text), Booleans (True/False), lists, dictionaries, tuples, and sets.

    Python Fundamentals & Usage

    5. What are the key differences between lists, tuples, and sets in Python?

    • Lists: Ordered, mutable (changeable) collections of items. They allow duplicate values.
    • Tuples: Ordered, immutable (unchangeable) collections of items. They also allow duplicate values.
    • Sets: Unordered collections of unique items. Sets do not allow duplicate values.

    6. What are comparison, logical, and membership operators in Python, and how are they used?

    • Comparison Operators: Used to compare values (e.g., == (equal), != (not equal), > (greater than), < (less than)). They return Boolean values (True or False).
    • Logical Operators: Used to combine or modify Boolean expressions (e.g., and, or, not).
    • Membership Operators: Used to test if a value is present in a sequence (e.g., in, not in).

    7. Explain the purpose of if, elif, and else statements in Python, and how they control the flow of execution.

    if, elif (else if), and else statements are used to create conditional blocks of code. The if statement checks a condition, and if it’s true, the code block under the if statement is executed. elif allows you to check additional conditions if the previous if or elif conditions were false. The else statement provides a default code block to execute if none of the if or elif conditions are true.

    8. How do for and while loops work in Python, and what are the differences between them?

    • for Loops: Used to iterate over a sequence (like a list, tuple, or string) and execute a block of code for each item in the sequence.
    • while Loops: Used to repeatedly execute a block of code as long as a specified condition is true. The loop continues until the condition becomes false.

    The main difference is that for loops are typically used when you know in advance how many times you want to iterate, while while loops are used when you want to repeat a block of code until a specific condition is no longer met.

    Creating Jupyter Notebooks with Anaconda

    To create a notebook in Anaconda using jupyter notebooks, these steps can be followed:

    1. Download Anaconda, which is an open source distribution of Python and R products, from the Anaconda website. Make sure to select the correct installer for your operating system (Windows, Mac, or Linux). For Windows users, it’s important to check the system settings to determine if it’s a 32-bit or 64-bit system.
    2. Install Anaconda by clicking ‘next’ on the installer window. Review the license agreement and click ‘I agree’. Choose the installation type, either for the current user only or for all users on the computer. Select the file path for the installation, ensuring there is enough disk space (approximately 3.5 GB).
    3. In the advanced options, it is not recommended to add Anaconda to the path environment variable unless you are experienced with Python. It is safe to register Anaconda as the default Python version. Allow the installation process to complete.
    4. After the installation is complete, search for and open Anaconda Navigator.
    5. In Anaconda Navigator, launch jupyter Notebook. This will open a new tab in the default web browser. If this is the first time opening jupyter Notebook, the file directory may be blank.
    6. In the jupyter Notebook interface, go to the ‘new’ drop down and select ‘Python 3 (ipykernel)’ to create a new notebook with a Python 3 kernel.
    7. A new jupyter Notebook will open where code can be written. This is where code will be written in future tutorials.
    8. In the notebook, there are cells where code can be typed. To run the code in a cell, press Shift + Enter.
    9. Besides writing code, markdown can be used to add comments and organize the notebook. To use markdown, type a hashtag/pound sign (#) followed by the text.

    After creating a jupyter Notebook, the title can be changed by clicking on the name at the top of the page. It is also possible to insert cells, delete cells, copy and paste cells and move cells up or down.

    Python Code: Concepts and Web Scraping

    Python code involves several key concepts, including variables, data types, operators, control flow (if statements, loops), functions, and web scraping.

    Variables:

    • Are containers for storing data values, such as numbers or strings.
    • A value can be assigned to a variable using the equal sign (=), for example, x = 22 assigns the value 22 to the variable x.
    • The print() function displays the value of a variable. For example, print(x) would output 22 if x has been assigned the value of 22.
    • Python automatically assigns a data type to a variable based on the assigned value.
    • Variables can be overwritten with new values.
    • Variables are case-sensitive.
    • Multiple values can be assigned to multiple variables. For example, x, y, z = “chocolate”, “vanilla”, “rocky road” assigns “chocolate” to x, “vanilla” to y, and “rocky road” to z.
    • Multiple variables can be assigned to one value. For example, x = y = z = “root beer float” assigns “root beer float” to all three variables.
    • Variables can be used in arithmetic operations. For example, y = 3 + 2 assigns the value 5 to the variable y.
    • Variables can be combined within a print statement using the + operator for strings or commas to combine different data types.

    Data Types:

    • Are classifications of the data that you are storing.
    • Numeric data types include integers, floats, and complex numbers.
    • Integers are whole numbers, either positive or negative.
    • Floats are decimal numbers.
    • Complex numbers are numbers with a real and imaginary part, where j represents the imaginary unit.
    • Booleans have two built-in values: True or False.
    • Sequence types include strings, lists, and tuples.
    • Strings are arrays of bytes representing Unicode characters and can be enclosed in single quotes, double quotes, or triple quotes. Triple quotes are used for multi-line strings. Strings can be indexed to access specific characters.
    • Lists store multiple values and are changeable (mutable). Lists are defined using square brackets []. Lists can contain different data types. Items can be added to the end of a list using .append(). Items in a list can be changed by referring to the index number. Lists can be nested.
    • Tuples are similar to lists but are immutable, meaning they cannot be modified after creation. Tuples are defined using parentheses ().
    • Sets are unordered collections of unique elements. Sets do not allow duplicate elements. Sets are defined using curly brackets {}.
    • Dictionaries store key-value pairs. Dictionaries are defined using curly brackets {}, with each key-value pair separated by a colon :. Dictionary values are accessed using the key. Dictionary items can be updated, and key-value pairs can be deleted.

    Operators:

    • Comparison operators compare two values.
    • == (equal to)
    • != (not equal to)
    • > (greater than)
    • < (less than)
    • >= (greater than or equal to)
    • <= (less than or equal to)
    • Logical operators combine conditional statements.
    • and (returns True if both statements are true)
    • or (returns True if one of the statements is true)
    • not (reverses the result, returns False if the result is true)
    • Membership operators test if a sequence is present in an object.
    • in (returns True if a sequence is present in the object)
    • not in (returns True if a sequence is not present in the object)

    Control Flow:

    • If statements execute a block of code if a condition is true.
    • if condition: (body of code)
    • else: (body of code) – executes if the initial if condition is false
    • elif condition: (body of code) – checks an additional condition if the initial if condition is false
    • Nested if statements can be used for more complex logic.
    • For loops iterate over a sequence (list, tuple, string, etc.).
    • for variable in sequence: (body of code)
    • Nested for loops can be used to iterate over multiple sequences.
    • While loops execute a block of code as long as a condition is true.
    • while condition: (body of code)
    • break statement: stops the loop even if the while condition is true
    • continue statement: rejects all the remaining statements in the current iteration of the loop
    • else statement: runs a block of code when the condition is no longer true

    Functions:

    • Are blocks of code that run when called.
    • Defined using the def keyword.
    • Arguments can be passed to functions.
    • Arbitrary arguments allow an unspecified number of arguments to be passed.
    • Keyword arguments allow arguments to be passed with a key-value assignment.
    • Arbitrary keyword arguments allow an unspecified number of keyword arguments to be passed.

    Web Scraping:

    • Involves extracting data from websites using libraries like Beautiful Soup and requests.
    • The requests library is used to send HTTP requests to a website.
    • Beautiful Soup is used to parse HTML content.
    • find() and find_all() methods are used to locate specific HTML elements.

    Python Variable Assignment: A Comprehensive Guide

    Variable assignment in Python involves using variables as containers for storing data values. You can assign a value to a variable using the equal sign (=). For example, x = 22 assigns the value 22 to the variable x. You can display the value of a variable using the print() function, such as print(x).

    Key aspects of variable assignment:

    • Data Type Assignment: Python automatically assigns a data type to a variable based on the assigned value. For example, assigning 22 to x makes it an integer.
    • Overwriting: Variables can be overwritten with new values.
    • y = “mint chocolate chip”
    • print(y) # Output: mint chocolate chip
    • y = “chocolate”
    • print(y) # Output: chocolate
    • Case Sensitivity: Variables are case-sensitive. Y and y are treated as different variables.
    • Y = “mint chocolate chip”
    • y = “chocolate”
    • print(Y) # Output: mint chocolate chip
    • print(y) # Output: chocolate
    • Multiple Assignments: Multiple values can be assigned to multiple variables. For example:
    • x, y, z = “chocolate”, “vanilla”, “rocky road”
    • print(x) # Output: chocolate
    • print(y) # Output: vanilla
    • print(z) # Output: rocky road
    • One Value to Multiple Variables: Multiple variables can be assigned the same value. For example:
    • x = y = z = “root beer float”
    • print(x) # Output: root beer float
    • print(y) # Output: root beer float
    • print(z) # Output: root beer float
    • Combining Variables in Print: Variables can be combined within a print statement using the + operator for strings or commas to combine different data types. However, it is important to note that you can only concatenate a string with another string, not with an integer, unless you are separating the values by a comma in the print statement.
    • x = “ice cream”
    • y = “is”
    • z = “my favorite”
    • print(x + ” ” + y + ” ” + z) # Output: ice cream is my favorite
    • x = 1
    • y = 2
    • z = 3
    • print(x, y, z) # Output: 1 2 3

    It is allowable to assign lists, dictionaries, tuples, and sets to variables as well.

    Python Data Types: Numeric, Boolean, Sequence, Set, and Dictionary

    Data types are classifications of the data that is stored; they inform what operations can be performed on the data. The main data types within Python include numeric, sequence type, set, Boolean, and dictionary.

    Numeric data types include integers, float, and complex numbers.

    • An integer is a whole number, whether positive or negative.
    • A float is a decimal number.
    • A complex number is used for imaginary numbers, with j as the imaginary number.

    Boolean data types only have two built-in values: either true or false.

    Sequence type data types include strings, lists, and tuples.

    • Strings are arrays of bytes representing Unicode characters. Strings can be in single quotes, double quotes, or triple quotes. Triple quotes are called multi-line. Strings can be indexed, with the index starting at zero.
    • Lists store multiple values and are changeable. A list is indexed just like a string. A bracket means that it will be a list. Lists can have any data type within them. The comma in a list denotes that the values are separate. Lists can be nested.
    • Tuples are quite similar to lists but the biggest difference is that a tuple is immutable, meaning that it cannot be modified or changed after it is created. Typically, tuples are used when data is never going to change.

    A set is similar to a list and a tuple, but does not have any duplicate elements. The values within a set cannot be accessed using an index, because it does not have one.

    A dictionary is different than the other data types because it has a key value pair.

    Web Scraping with Beautiful Soup and Requests

    Web scraping involves extracting data from websites using libraries like Beautiful Soup and requests.

    Key points regarding web scraping:

    • Libraries:
    • Requests: Used to send HTTP requests to a website to retrieve its HTML content. The requests.get() function sends a GET request to the specified URL and returns a response object. A response of 200 indicates a successful request.
    • Beautiful Soup: Used to parse HTML content, making it easy to navigate and search for specific elements.
    • Setting Up:
    • Import the necessary libraries:
    • from bs4 import Beautiful Soup
    • import requests
    • Specify the URL of the website to scrape:
    • URL = ‘https://example.com&#8217;
    • Send a GET request to the URL and retrieve the page content:
    • page = requests.get(URL)
    • Create a Beautiful Soup object to parse the HTML content:
    • soup = Beautiful Soup(page.text, ‘html.parser’)
    • HTML Structure:
    • HTML (Hypertext Markup Language) is used to describe the structure of web pages.
    • HTML consists of elements defined by tags (e.g., <html>, <head>, <body>, <p>, <a>).
    • Tags can have attributes, such as class, id, and href.
    • Inspecting web pages using browser developer tools helps identify the relevant HTML elements for scraping.
    • Finding Elements:
    • find(): Locates the first occurrence of a specific HTML element.
    • find_all(): Locates all occurrences of a specific HTML element and returns them as a list.
    • Elements can be filtered by tag name, class, id, or other attributes.
    • soup.find_all(‘div’, class_=’container’)
    • Extracting Data:
    • .text: Extracts the text content from an HTML element.
    • .strip(): Removes leading and trailing whitespace from a string.
    • Workflow:
    1. Import libraries: Import Beautiful Soup and requests.
    2. Get the HTML: Use requests to fetch the HTML content from the URL.
    3. Parse the HTML: Create a Beautiful Soup object to parse the HTML.
    4. Find elements: Use find() or find_all() to locate the desired elements.
    5. Extract data: Use .text to extract the text content from the elements.
    6. Organize data: Store the extracted data in a structured format, such as a list or a Pandas DataFrame.
    • Pandas DataFrames and Exporting to CSV:
    • The extracted data can be organized into a Pandas DataFrame for further analysis and manipulation.
    • The DataFrame can be exported to a CSV file using df.to_csv(). To prevent the index from being included in the CSV, use index=False.
    Learn Python in Under 3 Hours | Variables, For Loops, Web Scraping + Full Project

    The Original Text

    what’s going on everybody welcome back to another video today we’re going to be learning the basics of python in under 3 [Music] hours python is a fantastic skill to know how to do but I remember when I was first learning python it was a little bit intimidating it a little bit more difficult than I was used to when I had just known Excel and SQL and python seemed really really difficult but I’ve been using python for over 7even years now is a fantastic skill to know how to use so in this really long lesson we’re going to be walking through every you need to know in order to get started in Python I’ll be walking you through how to set up your environment to make sure that you can actually run your code and then we’ll be walking through all of the basics all the variables and for loops and while loops and even web scraping and we’ll even have a full project in this as well so we have a ton of things to cover and I hope it is really helpful without further Ado let’s jump onto my screen and get started all right so let’s get started by downloading anaconda anaconda is an open source distribution of python and our products So within Anaconda is our jupyter notebooks as well as a lot of other things but we’re going to be using it for our Jupiter notebooks so let’s go right down here and if I hit download it’s going to download for me because I’m on Windows but if you want additional installers if you’re running on Mac or Linux then you can get those all right here now if you are running on Windows just make sure to check your system to see if it’s a 32-bit or a 64 you can go into your about and your system settings to find that information I’m going to click on this 64-bit it’s going to pop up on my screen right here and I’m going to click save now it’s going to start downloading it it says it could take a little while but honestly it’s going to take probably about two to three minutes and then we’ll get going now that it’s done I’m just going to click on it and it’s going to pull up this window right here we are just going to click next because we want to install it this is our license agreement you can read through this if you would like I will not I’m just going to click I agree now we can select our installation type and you can either select it for just me or if you have multiple admin or users on one laptop you can do that as as well for me it’s just me so I’m going to use this one as it recommends now it’s going to show you where it’s installing it on your computer this is the actual file path it’s going to take about 3.5 gigs of space I have plenty of space but make sure you have enough space and then once you do you can come right over here to next and now we can do some Advanced options we can add Anaconda 3 to my path environment variable and when you’re using python you typically have a default path with whatever python IG or notebook that you’re using I use a lot of Visual Studio code so if I do this I’m worried it might mess something up so I am not going to do this it also says it doesn’t recommend it again messing with these paths is kind of something that you might want to do once you know more about python so I don’t really recommend you having this checked we can also register in AA 3 as my default python 3.9 you can do this one and I’m going to keep it this way just so I have the exact same settings as you do so let’s go ahead and click install install and now it is going to actually install this on your computer now once that’s complete we can hit next and now we’re going to hit next again and finally we’re going to hit finish but if you want to you can have this tutorial and this getting started with anonda I don’t want either of them because I don’t need them but if you would like to have those keep those checked and you can get those let’s click finish now let’s go down and we’re going to search for Anaconda and it’ll say Anaconda navigate and we’re going to click on that and it should open up for us so this is what you should be seeing on your screen this is the Anaconda Navigator and this is where that distribution of python and R is going to be so we have a lot of different options in here and some of them may look familiar we have things like Visual Studio code spider our studio and then right up here we have our Jupiter notebooks and this is what we’re going to be using throughout our tutorials so let’s go ahead and click on launch and this is what should kind of pop up on your screen now I’ve been using this a lot um so I have a ton of notebooks and files in here but if you are just now seeing this it might be completely blank or just have some you know default folders in here but this is where we’re going to open up a new jupyter notebook where we can write code and all the things that we’re going to be learning in future tutorials and you can use this area to save things and create folders and organize everything if you already have some notebooks from previous projects or something you can upload them here but what we’re going to do is go right to this new we’re going to click on the drop down and we’re going to open up a Python 3 kernel and so we’re going to open this up right here now right here is where we’re going to be spending 99% of our time in future videos this is where we’re going to write all of our code so right here is a cell and this is where we can type things so I can say print I can do the famous hello world and then I’ll run that by clicking shift enter and this is where all of our code is going to go these are called cells so each one of these are a cell and we have a ton of stuff up here and I’m going to get to that in just a second one thing I want to show you is that you don’t only have to write code here you can also do something called markdown and so markdown is its own kind of you could say language but um it’s just a different way of writing especially within a notebook so all we’re going to do is do this little hashtag and actually I think it’s a pound sign but I’m going to call it hashtag we’re going to do that and we’re going to say first notebook and then if I run that we have our first notebook and we can make little comments and little notes like that that don’t actually run any code they just kind of organize things for us and I’m going to do that in a lot of our future videos so just wanted to show you how to do that now let’s look right up here a lot of these things are pretty important uh one of the first things that’s really important is actually saving this so let’s say we wanted to change the title to I’m going to do a AA because I want it to be at the beginning um so I can show you this I’m do AAA new notebook and I’m going to rename it and then I’m going to save that so if I go right back over here you can see AAA new notebook that green means that it’s currently running and when I say running I mean right up here and if we wanted to we go ahead and shut that down which means it wouldn’t run the code anymore and then we’d have to run up a new cluster uh so let’s go ahead and do that I didn’t plan on doing that but let’s do it so we have no notebooks running and right here it says we have a dead kernel so this was our Python 3 kernel and now since I stopped it it’s no longer processing anything so let’s go ahead and say try restarting now and it says kernel is ready so it’s back up and running and we’re good to go the next thing is this button right here now this is an insert cell below so if I have a lot of code I know I’m going to be writing I can click a lot of that and I often do that because I just don’t like having to do that all the time so I make a bunch of cells just so I can use them you can also delete cells so say we have some code here we’ll say here and we have code here and then we have this empty cell right here we can just get rid of that by doing this cut selected cells we can also copy selected cells so if I hit copy selected cells then I can go right here and say paste selected cells and as you can see it pasted that exact same cell you can also move this up and down so I can actually take this one and say I wanted it in this location I can take this cell and move it up or I can move it down and that’s just an easy way to kind of organize it in instead of having to like copy this and moving it right down here and pasting it you can just take this cell and move it up which is really nice now earlier when I ran this code right here I hit shift enter you can also run and it’ll run the cell below so you can hit run and it works properly if you’re running a script and it’s taking forever and it’s not working properly at least it’s you don’t think it’s working properly you can stop that by doing this interrupt the kernel right here and anything you’re trying to do within this kernel if it’s just not working properly it’ll stop it you can restart it then you can try fixing your code you can also hit this button if you want to restart your kernel and this button if you want to restart the kernel and then rerun the entire notebook as we talked about just a second ago we have our code and our markdown code we’re not going to talk about either of these because we’re not going to use that throughout the entire series the next thing I want to show you is right up here if you open this file we can create a new notebook we can open an existing notebook we can copy it save it rename it all that good stuff we can also edit it so a lot of these things that we were talking about you can cut the cells and copy the cells using these shortcuts if you would like to we also go to view and you can toggle a lot of these things if you would like to which just means it’ll show it or not show it depending on what you want so if we toggle this toolbar it’ll take away the toolbar for us or if we go back and we toggle the toolbar we can bring it back we can also insert a few different things like inserting a cell above or a cell below so instead of saying This plus button you can just say A or B adding above or below we also have the cell in which we can run our cells or run all of them or all above or all below and then we have our kernels right here which we were talking about earlier where we can interrupt it and restart those there are widgets we’re not going to be looking at any widgets in this series but if it’s something you’re interested in you can definitely do that then we have help so if you are looking for some help on any of these things especially some of these references which are really nice you can use those and you can also edit your own keyboard shortcuts and now that we walked through all of that you now have anacon and jupyter notebooks installed on your computer in future videos this is where we’re going to be writing all of our python code so be sure to check those out so we can learn python together hello everybody today we’re going to be learning about variables in Python a variable is basically just a container for storing data values so you’ll take a value like a number or a string you can assign it to a variable and then the variable will carry and contain whatever you put into it so for example let’s go right over here we’re going to say x and this is going to be our variable we’re going to say is equal to now we can assign the value to it so let’s say I want to put 22 x is now equal to 22 so we won’t have to write out the number 22 in later scripts that we write we can just say x because X is equal to 22 it now contains that number so now we can hit enter and say print we do an open parentheses and we’ll say x now I’m going to hit shift enter and now it prints out that 22 because we are printing x and x is equal to 22 this is our value and this is our variable one really great thing about variables is that it assigns its own data type it’s going to automatically do this so we didn’t have to go and tell X that it’s an integer it just automatically knew that 22 is a number so we can check that by saying type and then open parenthesis and writing X and we’ll do shift enter again and this says that X is an integer type now we only assigned a integer to X let’s try assigning a string value or some text to a variable so we’ll say Y is equal to uh let’s say mint chocolate chip I’m feeling some ice cream today so we’ll say mint chocolate chip now if we print that again we’ll do print open parentheses Y and do shift enter it’ll print mint chocolate chip and if we look at the type we can see that the type is a string this time and not an integer now again we did not tell it that X was an integer and Y was a string it just automatically knew this let’s go up here really quickly we’re going to add several rows in here because we’re about to write a lot of different variables and really learn in- depth how to use variables the next thing to know about variables is that you can overwrite previous variables right now we have mint chocolate chip and that is assigned to the variable y so if I go down here I say print y I hit shift enter it’s going to print out mint chocolate chip but if I go right above it I say Y is equal to and let’s say chocolate if I print that out it’s now going to say chocolate whereas up here I’m reassigning it to Y it’s still going to say mint chocolate chip so if I come right down here and I copy this and I’m going to paste this right here initially it is going to assign y to Chocolate but then right here it will automat Ally overwrite y as mint chocolate chip and when we hit shift enter it’s going to show mint chocolate chip variables are also case sensitive so if I come up here and I say a capital Y this is a lowercase Y and this is a capital Y it is going to print out the correct one instead of mint chocolate chip and then if I go down here to the print and I type the capital Y it will give us the mint chocolate chip up till now we’ve only assigned one value to one variable but but we can actually assign multiple values to multiple variables so let’s do X comma y comma Z is equal to and now we can assign multiple values to all of those so we can say chocolate and then we’ll do a comma oops a comma then we can say vanilla and then we’ll do another comma and we’ll say rocky road now now this is going to assign chocolate to X vanilla to Y and Rocky Road to Z so what we can do is we’ll say print and we’ll go print print print and we’ll say X Y and Z so it prints out chocolate vanilla and rocky road and these are our three different values we can also assign multiple variables to one value and we can do this by saying X is equal to Y is equal to Z is equal to and we can put whatever we would like let’s do root beer float then we’ll come back up here we’ll copy this and let’s print off our X our Y and Z and they are all the exact same now so far we’ve really only looked at integers and strings but you can assign things like lists dictionaries tupal and sets all to variables as well so let’s go right down here so let’s create our very first list I’m going to say ice _ cream is equal to and that is our variable right there the ice uncore cream is our variable so now we’re going to do an Open Bracket like this and we’re going to come up here and copy all of these values and we’re going to stick it within our list so now within ice cream we have three string values chocolate vanilla and rocky road all within this list so what we can do is we can say x comma y comma Z is equal to to ice cream so now these three values chocolate vanilla and rocky road will be assigned to these three variables X Y and Z and we can copy this print up here and we’ll hit shift enter and now the X Y and Z all were assigned these values of chocolate vanilla and rocky road now something that we just did which is really important or something that you really need to consider is how you name your variables so right here we have ice cream now this to me is exactly how I usually write my variables but there are many different ways that you can write your variables so let’s take a look at that really quickly and let’s add just a few more because I have a feeling we’re going to go a little bit longer than what we have so there are a few best practices for naming variables first I’m going to show you kind of what a lot of people will do I’ll show you some good practices and I’m going to show you some bad practices as well that you should avoid doing the first thing that we’re going to look at is something called camel case and let’s say we want to name it test variable case oops case now if we have a test variable case the camel case is going to look like this we’ll have lowercase test and then we’ll have uppercase variable and uppercase case is equal to this is what this variable is going to look like and we can assign it a nilla swirl and this is what your camel case will look like it’s going to be lowercase and then all the rest of those uh compound words or however you want to say that these letters are going to be capitalized to kind of separate where the words end and begin let’s go right down here we’re going to copy this the next one is called Pascal case so Pascal case is going to look just a little bit different instead of the lower case at test it’s going to be a capital T in test so test variable case again this is a very similar way of writing it very similar to camel case but just a capital at the beginning now let’s look at the last one and this one is my personal favorite this one is going to be the snake case now this one is quite a bit different in the fact that you don’t use any capital letters and you separate everything using underscore so we’re going to write testore variable uncore case now typically let me have them all in there typically these are the best practices these are what you typically want to do but probably the best one to use is this snake case right here what a lot of people say is that it improves readability if you take a look at either the camel case or the Pascal case which you will see people do it’s not as easy to distinguish exactly what it says and the name of a variable is important because you can gain information from it if people name them appropriately so when I’m naming variables I usually write it in snake case because I just find it a lot easier to read because each word is broken up by this underscore so now let’s look at some good variable names these are all ones that you can use or could use so let’s do something like test VAR so test VAR is completely appropriate we can also do something like testore VAR oops underscore we could do underscore testore VAR you’ll see that often as well well people will start it with an underscore you can do test VAR capital T oops capital T capital V in test VAR or you could even do something like test VAR two now adding a number to your variable is not inherently a Bad Thing usually it’s semif frowned upon but there are definitely some use cases where you can use it but one thing that you cannot do is do something like putting the two at the front if you put the two at the front it no longer works it won’t run properly at all so we’re going to take that out so we can’t do that so I’m going to use this as an example of what you should not do you also can’t use a dash so something like test- var2 that doesn’t work either and you also can’t use something like a space or a comma or really any kind of symbol like a period or a backslash or equal sign none of those things will work work within your variable now another thing that you can do within your variable is use the plus sign so let’s assign this we’ll say x is equal to and we’ll do a string we’ll say ice cream is my favorite and then we’ll do a plus sign and we’ll say period now what this will do is it will literally add these two strings together so let’s do print and we’ll do X so now it says ice cream is my favorite one thing that we cannot do in a variable is we cannot add a string and a number or an integer so we can’t do ice cream as my favorite two if we try to do that it will give us this error right here so in this error it’s saying you can only concatenate a string not an integer to a string so only a string plus a string for this example you can also do and we’ll say x is equal to or we’ll say y we’ll say Y is equal to 3 + 2 and it should output 5 because you can also do an integer and an integer now so far we’ve only been outputting one variable in the print statement but you can actually add multiple variables within a print statement so let’s go right down here we’re going to say let’s give it some more right there so we’ll say x is equal to ice cream and we’ll say Y is equal to is and then the last one Z is equal to my favorite and we’ll do a period at the end now we can go to the bottom and we can say print x + y + C and when we enter that and when we run and when we run that we get ice cream is my favorite now we can actually add a space before is a space before my and when we hit shift enter it says ice cream is my favorite you can also do this exact same thing with numbers as well so we’ll say x = to 1 2 and what Z is equal to 3 so this should equal six now one thing that we tried to do was assign to one variable a string plus an integer and that did not work but what you can do is you can take something like this and you can say ice cream and we’ll get rid of this one and we’ll get rid of the Z Now say Plus is actually not going to work let’s try running this so again we can’t concatenate these but what we can do in the print statement is we can separate it by a comma so when we add this comma it should work properly let’s hit enter and it says ice cream 2 again this makes no sense but you are able to combine a string and an integer separating by a comma now this is the meat and potatoes of variables there are some other things as well but some of those things are a little bit more advanced and not something I wanted to cover in this tutorial although we may be looking at some of those things in future tutorials but this is definitely the basics what you really really need to know about variables hello everybody today we’re going to be talking about data types in Python data types are the classification of the data that you are storing these classifications tell you what operations can be performed on your data we’re going to be looking at the main data types within python including numeric sequence type set Boolean and dictionary so let’s get started actually writing some of this out and first let’s look at numeric there are three different types of numeric data types we have integers float and complex numbers let’s take a look at integers an integer is basically just a whole number whether it’s positive or negative so an integer could be a 12 and we can check that by saying type we’ll do an open parenthesis and a Clos parenthesis and if we say the type of 12 it’s going to give us an integer or if we say a -2 that is also an integer we can also perform basic calculations like -2 + 100 and that’ll tell us it is also an integer so whether it’s just a static value or you’re performing an operation on it it’s still going to be that data type if those numbers are whole numbers whether negative or positive now let’s take this exact one and let’s say 12 and we’ll do plus 10.25 when we run this it’s no longer going to be a whole number it’ll now be a float so let’s check this now this is a float type because is no longer a whole number it’s now a decimal number and the last data type within the numeric data type is called complex let’s copy this right down here now personally this is not one that I’ve used almost ever but it is one just worth noting so you can do 12 plus and let’s say 3 J and if we do this it’s going to give us a complex the complex data type is used for imaginary numbers for me it’s not often used but if you do use it J is used as that imaginary number if you use something like C or any other number it’s going to give you an error J is the only one that will work with it now let’s take a look at Boolean values so we’ll say Boolean the Boolean data type only has two built-in values either true or false so let’s go right down here and say type true and when we run this it’ll say bu which stands for Boolean we can do the exact same thing with false that is also Boolean and this can be used with something like a comparison operator so let’s say 1 is greater than 5 and let’s check this this is giving us a Boolean because it’s telling us whether one is greater than five let’s bring that right down here this will give us a false so it’s telling us that one is not greater than five and just as we got a false we can say 1 is equal to 1 and this should give us a true so now let’s take a look at our sequence type data types and that includes strings lists and tupal we let’s start off by looking at string strings in Python strings are arrays of byes representing Unicode characters when you’re using strings you put them either in a single quote a double quote or a triple quote I call them apostrophes it’s just what I was raised to call them but most people who use Python call them quotes So Right Here we have a single quote and that works well we can do a double quote and that works also and as you can see they are the exact same output and then we have a triple quote just like this and this is called a multi-line so we can write on multiple lines here so let’s write a nice little poem so we’ll say the ice cream vanquished my longing for sweets upon this diet I look away it no longer exists on this day and then if we run that it’s going to look a little bit weird it’s basically giving us the raw text which is completely fine but let’s let’s call this a multi-line and we’re going to call this a variable multi-line and we’re going to come down here and say print and before I run this I have to make sure that this is Ran So now let’s print out our multi-line and now we have our nice little poem right down here now something to know about these single and double quotes is how they’re actually used so if we use a single quote and we say I’ve always wanted to eat a gallon of ice cream and then we do an apostrophe at the end obviously something went wrong here what went wrong is when you use a single quote and then within your text within your sentence you have another apostrophe it’s going to give you an error so what we want to do is whenever we have a quote within it we need to use a double quote these double quotes will negate any single quotes that you have within your statement they won’t however negate another double quote so you need to make sure you aren’t using double quotes within your sentence if you want to do something like that you need to use the triple quotes like we did above so we can do double double and then let’s paste this within it and anything you do Within These triple quotes will be completely fine as long as you don’t do triple quotes within your triple quotes we’ll say this is wrong so even though it’s between these two triple quotes it doesn’t work exactly again you just have to understand how that works you have to use the proper apostrophes or quotes within your string and just to check this we can always say here’s our multi-line we can always say type of multi-line and that is still a string one really important thing to know about strings is that they can be indexed indexing means that you can search within it and that index starts at zero so let’s go ahead and create a variable and we’ll just say a is equal to and let’s let’s do the all poopular hello world let’s run this and now when we print the string we can say a and we’re going to do a bracket and now we can search throughout our string using the index so all you have to do is do a colon we going say five what this is going to do is is going to say zero position zero all the way up to five which should give us the whole hello I believe let’s run this and it’s giving us the first five positions of this string we can also get rid of the colon and just say something like five and then when we run this it’s actually going to give us position five so this is 0 1 2 3 4 and then five is the space let’s do six so we can see the actual letter and that is our w we can also use a negative when we’re indexing through our string so we could say -3 and it’ll give us the L because it’s -1 2 and three we can also specify a range if we don’t want to use the default of Z so before we did 0 to 5 and it started at zero because that was our default but we could also do 2 to 5 let’s run this and now we go position 0 1 and then we start at 2 L L O now we can also multiply strings and we have this a hello world so we can do a time three and if we run this it’ll give us hello world three times and we can also do A+ a and that is hello world hello world now let’s go down here and take a look at lists lists are really fantastic because they store multiple values the string was stored as one value multiple characters but a list can store multiple separate values so let’s create our very first list we’ll say list really quickly and then we’ll put a bracket and a bracket means this is going to be a list there are other ones like a squiggly bracket and a parentheses these denote that they are different types of data types the bracket is what makes a list a list so to keep it super simple we’ll say 1 2 3 and we’ll run this and now we have a list that has three separate values in it the comma in our list denotes that they are separate values and a list is indexed just like a string is indexed so position zero is this one position one is the two and position two is the three now when we made this list we didn’t have to use any quotes because these are numbers but if we wanted to create a list and we wanted to add string values we have to do it with our quotes so we’ll say quote cookie dough then we’ll do a comma to separate the value and then we’ll say strawberry and then we’ll do one more and this will just be chocolate and when we run this we have all three of these values stored in our list now one of the best things about list is you can have any data type within them they don’t just have to be numbers or strings you can basically put anything you want in there so let’s create a new list and let’s say vanilla and then we’ll do three and then we’ll add a list within a list and we’ll say Scoops comma spoon and then we’ll get out of that list and then we’ll add another value of true for Boolean and now we can hit shift enter and we just created a list with several different data types within one list now let’s take this one list right here with all of our different ice cream flavors we’ll say icore cream is equal to this list now one thing that’s really great about lists is that they are changeable that means we can change the data in here we can also add and remove items from the list after we’ve already created it so let’s go and take ice cream and we’ll say ice cream. append and this is going to append it to the very end of the list we do an open parenthesis let’s say salted caramel now when we run this and we call it just like this it’s going to take this list add salted caramel to the end and we’ll print it off and as you can see it was added to the list and just like I said before let me go down here we can also change things from this list so let’s say ice cream and then we need to look at the indexed position so we’re going to say zero and that’s going to be this cookie dough right here we can say that is equal to so we can now change that value so let’s call that butter peon and now when we call it we can now see that the cookie dough was changed to butter peon another thing that you saw just a little bit ago is something called a list within a list basically a nested list so we had Scoops spoon true let’s give this and we’ll say nested uncore list is equal to now when we run this we now have this nested list so if we look at the index and we say 0 we’ll get vanilla if we say two we’ll get scoops and spoons now since we have a list within a list we can also look at the index of that nested list so let’s now say one and that should give us just spoon and you can go on and on and on with this you can do lists within lists within lists and all of them will have indexing that you can call now let’s go down here and start taking a look at tupal so a list and a tupal are actually quite similar but the biggest difference between a list in a tupal is that a tupal is something called immutable it means it cannot be modified or changed after it’s created let’s go right up here we’re going to say Tuple and let’s write our very first tupal so we’ll say Tuple undor Scoops is equal to and then we’ll do an open parenthesis now these open parentheses you’ve seen if you do like a print statement but that’s different because that’s executing a function this is actually creating a tupal which is going to store data for us so we’ll say one 2 three two and one let’s go ahead and create that tupal and we can just check the data type really quickly and it’s a tupal and just like we saw before a tupal is also indexed so if we go at the very first position which is a one we will get the output of a one but we can’t do something like aend and then add a value like three if we do that it’s going to say tupal object has no attribute aend it’s just because you cannot change or add anything to a tupal just like we were talking about before typically people will use tupal for when data is never going to change an example for this might be something like a city name a country a location something that won’t change they definitely have their use cases but I don’t think they’re as popular as just using a list so now let’s scroll down and start taking a look at sets but really quickly let me add a few more cells for us and let’s say sets now a set is somewhat similar to a list and a tupal but they are little bit different in the fact that they don’t have any duplicate elements another big difference is that the values within a set cannot be accessed using an index because it doesn’t have an index because it’s actually unordered we can still Loop through the items in a set with something like a for Loop but we can’t access it using the bracket and then accessing its index point so let’s go ahead and create our very first first set so we’re going to say daily pints then we’re going to say equal to and to create a set we’re going to use these squiggly brackets I don’t know if there’s an actual name for those if I’m being honest I call them squiggly brackets and that’s what we’re going to go with we’re going to put in a one a two and a three so let’s go ahead and run this and let’s look at the type and as you can see it is a set now when we print this out it’s going to show us one a two and a three and those are all the values Within set but if we copy this and we’ll say daily pant log this is going to be every single day maybe I had different values now when we run this and we do the exact same thing now when we print this it’s going to have just the unique values within that set now a use case for set and this is something that I’ve done in the past is comparing two separate sets maybe you have a list or a tupal and you convert that into a set and that will narrow it down down to its unique values then you can compare the unique values of one set to the unique values in another set and then we can see what’s the same and what’s different so let’s go down here and let’s say wife’s uncore daily and we’ll just copy this right here we’ll say is equal to let’s do our squiggly lines let’s do one two let’s do just random numbers so now this is my daily log and this is my wife’s daily log and now we can compare these values so let’s go right down here let’s say print we’ll do my daily logs and then we’ll do this bar right here and this is going to show us the combined unique values it’s basically like putting them all in one set and then trimming it down to just the unique values so we’ll take wife’s daily pintes log and when we run this we actually need to run this first when we run this we should see all the unique values between these two sets and so as you can see 0 1 2 3 4 5 6 7 24 31 so these are all the unique values between these two sets we can also do another one and instead of this bar we’re going to do this symbol right here which I believe is called an Amper sand don’t quote me on that but when we run this it’s going to show what matches that means which ones show up in both sets so the only ones that show up in both sets are 1 2 3 and five we can also do the opposite of that by doing a minus sign and this is going to show us what doesn’t match and so we have 4 6 and 31 now where is our 24 that was in our wife’s daily pints log it’s in this one but we’re subtracting the values on this one so let’s reverse this and we’ll say daily pints log and let’s run it now those are our other values so we’re taking the values of this and then we’re subtracting all the ones that are the same and getting the remaining values and then for our last one we can get rid of this and we’ll do this symbol right here and this is going to show if a value is either in one or the other but not in both so let’s run this so these values are completely unique only to each of those sets now the very last one that we’re going to look at in this video is dictionaries so let’s go right down here let’s add a few cells and let’s say dictionaries now I saved dictionary for last because this one is probably the most different out of all the previous data types that we’ve looked at within a data type we have something called a key value pair that means when we use a dictionary it’s not like a list where you just have a value comma value comma value we have a key that indicates what that value is attributed to so let’s write out a dictionary to see how this looks so we’re going to say dictionary cream and just like a set we use a squiggly line but the thing that differentiates it is that in a dictionary we’ll have that key value pair whereas in a set each value is just separated by a comma so let’s write name and this is our key and then we do a colon and this is then where we input our value so we’re going to say Alex freeberg and then we separate that key value Pair by a comma and now we can do another key value pair so we’ll say weekly intake and and a colon and we’ll say five pints of ice cream do a comma and then we’ll do favorite ice creams and now what we’re going to do is we’re going to put in here a list so within this dictionary we can also add a list we’ll do MCC from mint chocolate chip and then we’ll add chocolate another one of my favorites so now we have our very first dictionary let’s copy this and run it and let’s just look at the type and as as you can see it says that this is a dictionary let’s also print it out now if we want to we can take our dictionary cream and say dot values with an open parenthesis and when we execute this we’ll see all of the values within this dictionary so here’s our values of Alex freeberg five mint chocolate chip and chocolate we can also say keys and when we run this all of the keys the name weekly intake and favorite ice creams and we can also say items so this key value pair is one item and this key value pair is another item now one difference between something like a list and a dictionary is how you call the index but you can’t call it by doing something like this where you just do a bracket oops and say zero so this would in theory take this very first one right our very first key value pair that’s going to give us an error how you call a dictionary is actually by the key so it doesn’t technically have an index but you can specify what you want to call and take it out so we’re going to say name and this is going to call that key right here and when we run this we’ll get the value which is Alex freeberg one other thing that you can do is you can also update information in a dictionary which we can’t with some other data types so for this for the name it was Alex freeberg now let’s say Steen freeberg and when we update that I’m also going to print the dictionary get rid of this so it’s going to update Christine freeberg in that value of the name so let’s go ahead and run this and now it changed the name from Alex freeberg to Christine freeberg we can also update all of these values at one time so let’s copy this and I’m going to put it right down here I’m going to say dictionary.c cream. update then we’re going to put a bracket or not a rocket but a parenthesis around these so now what we’re going to do is update this entire thing let me take this say print this dictionary now we can update this to anything we want so instead of here I can say I’ll say weight and because of all that ice cream I now weigh 300 lb so let’s run this and as you can see it did not delete our key value pair right here instead it just added to it when you’re using the update we can’t actually delete that’s the delete statement and I’ll show you that in just a second but all we did was added this new value it also is going to check and see if you changed anything with your key value pair so we can go in here and change this value and we’ll say 10 so now when we run this the value of this key value pair was changed but let’s say we do want to delete it we’ll say deel that stands for delete part of this dictionary cream and now let’s specify the key which will also delete the value with it but let’s specify the key that we want to get rid of and let’s say wait and then let’s print that again and as you can see the weight was deleted from that dictionary so hello everybody today we’re going to be taking a look at comparison logical and membership operators in Python operators are used to perform operations on variables and values for example you’re often going to want to compare two separate values to see if they are the same or if they’re different within Python and that’s where the comparison operator comes in right here you can see our operators you can also see what they do so this equal sign equal sign stands for equal we have the does not equal the greater than less than greater than or equal to and less than or equal to and honestly I use these almost every single time I use Python so these are very important to know and know how to use so let’s get rid of that really quickly and actually start writing it out and see how these comparison operators work in Python the very first one that we’re going to look at is equal to now you can’t just say 10 is equal to 10 let’s try running that really quickly by clicking shift enter it’s going to say cannot assign to literal that’s because this is like assigning a variable we’re trying to say 10 is equal to 10 and then we can call that 10 later but that’s not how this actually works what we’re trying to do is to determine whether 10 is equal to 10 so we’re going to say equal sign equal sign and then if we run that by clicking shift enter again it’s going to say true now if we put something else like 50 in there and we try to run this it’s going to say false so really what you’re going to get when you use these comparison operators is either a true or a false if we take this right down here we can also say does not equal and we’re going to use an exclamation point equal sign and that says 10 is not equal to 50 and that should be true you can also compare strings and variables so let’s go right down here and we’re going to say vanilla is not equal to chocolate and when we run this it’ll say false now if it was the same just just like when we did our numbers it should say true and we can also compare variables so we’ll say x is equal to vanilla and Y is equal to chocolate and then when we come down here we can say x is equal to Y and it’ll give us a false and we say X is not equal to Y and it’ll give us a true the next one that we’re going to take a look at is the less than so let’s copy this one right up here let’s scroll down and let’s say 10 is less than 50 now this will come out as true now let’s say we put a 10 in here before 10 was of course less than 50 but is 10 less than 10 no that’s false because they are the same so if we want an output that is true all we would have to add is an equal sign right here and this would say 10 is less than or it is equal to 10 and now it’s true of course we can say the exact same thing by saying greater than so 10 is equal or greater than 10 that’ll be true because 10 is equal to 10 we can also say 50 is greater or equal to 10 because 50 is obviously greater than 10 now let’s look at logical operators that are often combined with comparison operators so our operators are and or and not so if you have an and that returns true if both statements are true if it’s or only one of the statements has to be true and the not basically reverses the result so if it was going to return true it would return turn false I don’t use this not one a lot but I will show you how it works so let’s actually test that out so before we were saying 10 is greater than 50 and of course this returned false so now let’s add a parentheses around this 10 is greater than 50 and we’re going to say and we’ll do an open parenthesis 50 is greater than 10 now this statement right here is true 50 is greater than 10 so we have a true statement and a false statement but this and is going to look at both of them it’s going to say they both need to be true in order to return a true so let’s try running this and we still have a false if we want it to return true we’re going to have to change this to make it a true statement so 70 is greater than 50 and 50 is greater than 10 when we run this it should return true now let’s look at the or so let’s copy this and we’ll say 10 is greater than 50 or 50 is greater than 10 now this is a false statement and this is a true statement so if even one of them is a true statement the output should be true and again we can do this even with strings so we can do vanilla and chocolate there we go and vanilla is actually greater than chocolate because V is a higher number in the alphabetical order so V is like 20 something whereas chocolate is three right so it actually looks at the spelling for this so if we say or here it will come out true and if we say and here it should also be true because V is greater than C and 50 is greater than 10 so this should also be true now let’s copy this right here and we’re going to say not so what we had before is 50 is greater than 10 that returned true but now all we’re doing is putting not in front of it so instead of returning true it’s going to return false so now let’s take a look at membership operators and we use this to check if something whether it’s a value or a string or something like that is within another value or string or sequence our operators are in and not in so it’s pretty simple if it’s in it’s going to return true if the sequence with a specified value is present in the object just like we were talking about and for not in it’s basically the exact same thing if it’s not in that object so let’s start out by taking a look at a string we’re going to say icore cream is equal to I love chocolate ice cream and then we’re going to say love in icore cream and that will will turn true so all we’re doing is searching if the word love or that string is in this larger string we could also just do that by literally copying this and putting this where this is so we can check is this string part of this string and it’ll say true we can also make a list so we’ll say Scoops is equal to and then we’ll do a bracket and we’ll say 1 2 3 4 5 and then we’ll say two in Scoops so all we’re doing is searching to see if two is within this list and that should return true now if we put a six here and we said not in it will also return true because six is not in scoops and that is true and just like we did we could also say wanted underscore Scoops and we’ll say eight so I wanted eight Scoops so we can say wanted Scoops in Scoops and this should return true because there’s not an eight within the Scoops that we wanted and if we said in and we said we wanted eight is that within our list that we created and that’s going to return a false hello everybody today we’re going to be taking a look at the if statement within python now it’s actually the if lfl statement but that’s a mouthful so I’m just going to call it the if L statement now we have this flowchart and I apologize for being blurry but this is the absolute best one that I could find right up top we have our if condition now if this if condition is true we’re going to run a body of code but if that condition is false we’re going to go over here and go to the LF condition the LF condition or statement is basically saying if the first if statement doesn’t work let’s try this if statement if this LF statement is true it goes to this body of code if it’s false it’ll come over here to the else and the else is basically if all these things don’t work then run this body of code now you can have as many ill if statements as you want but you can only have one if statement and one else statement so let’s write out some code and see how this actually looks let’s first start off by writing if that is our if statement and now we have to write our condition which is about to be either met or not met so we’ll say if 25 is greater than 10 which is true we’ll say colon and then we’re going to hit enter and it’s going to automatically indent that line of code for us and this is our body of code so if 25 is greater than 10 our body of code will execute so for us we’re just going to write print and we’ll say it worked now if we run this it’s going to check is 25 greater than 10 if that is true print this so let’s hit shift enter and it worked now let’s take this exact code we’ll paste it right down here and we’ll say is less than and right now this if statement is not true so it’s not actually going to work as you can see there’s no output there’s nothing that happened really but it did check to see if 25 was less than 10 but it just wasn’t true now we can use our else statement so we’re going to come right down here and we’re going to say else and we’ll do a colon and we’ll hit enter again automatically indenting and we’re going to say print and we’re going to say it did not work dot dot dot so what it’s going to do is it’s going to come up here and check is 25 less than 10 no it’s not so this body of code is not going to be executed it’s going to go right down to this else statement now this else statement is going to be printed there’s no condition on this so the if statement has a condition 25 is less than 10 this has no condition so if this doesn’t work if this is false it’s going to come down here and it will run this body of code let’s run this by clicking shift enter and as you can see our output is it did not work now let’s go back up here and put greater than because this is now true it’s going to say if 25 is greater than 10 print it worked and then it’s going to stop it’s not going to go to this L statement at all so let’s run this and our output is it worked so what if we have a lot of different conditions that we want to try let’s come right down here this is where the LF comes in so really quickly let’s change this to a not true a false statement we’re going to go down and say LF and we’re going to say if it is and let’s say 30 we’ll say LF worked so now it’s going to check is 25 less than 10 no it’s not let’s look at the next condition is 25 less than 30 and if it is we’ll print L if worked so let’s try running this and L if worked now we can do as as many of these LF statements as we want we can do let’s just try a few of them right here so we’ll say if 25 is less than 20 is less than 21 and let’s do 40 and let’s do 50 so we’ll say LF lf2 lf3 and lf4 now if you look at this the first one that is actually going to work is this 25 to 40 right here once this one is checked and it comes out as true none of the other LF or L statements will work so let’s try this one it should be lf3 and this one ran properly now within our condition so far we’ve only used a comparison operator we can also use a logical operator like and or or so we can say if 25 is less than 10 which it’s not let’s say or actually and we’ll say or 1 is less than three which is true if we run this now it will actually work so we can use several different types of operators within our if statement to see if a condition is true or not or several conditions are true there’s also a way to write an if else statement in one line if you want to do that so we can write print we’ll say it worked and then we’ll come over here and say if 10 is greater than 30 and then we’ll write else print and we’ll say it did not work just like we had before except now it’s all occurring on one line so let’s just try this and see if it works so it’s saying print it worked if 10 is greater than 30 which it wasn’t so it went to the L statement and then it printed out our body right here although we didn’t have any indentation or multiple lines it was all done in one line now there’s one other thing that we haven’t looked at yet uh and I’m going to show it to you really quickly and that’s a nested if statement so when we run this it’s going to say it worked it works because it says 25 is less than 10 or 1 is less L than three since this is true it’s going to print out it worked but we can also do a nested if statement so we can do multiple if statements as well so we’re going to hit enter and we’ll say if and we’ll do a true statement here so we’ll say if 10 is greater than 5 let’s do a colon hit enter then we’ll say print and then we’ll type A String saying this nested if statement oops worked now let’s try this out and see what we get so it went through the first if statement it said it was true and it prints out it worked this is still the body of code so it goes down to this next if statement and it says if 10 is greater than five we’re going to print this out and you could do this on and on and on it can basically go on forever and you can create a really in-depth logic and that actually happens a lot when you start writing more advanced code hello everybody today we’re going to be learning about four Loops in Python the for Loop is used to iterate over a sequence which could be a list a tube an array a string or even a dictionary here’s the list that we’ll be working with throughout this video and I have this little diagram right here which kind of explains how a for Loop works the for Loop is going to start by looking at the very first item in our sequence or our list and that’s going to be our one right here it’s going to ask is this the last element in our list and it is not so it’s going to go down to this body of the for Loop now we can have a thousand different things that can happen in the body of the for loop as we’re about to look out in just second then it’s going to go up to the next element and ask is this the last element reached so it’ll be no again because we’ll be going to the two and then the three and then the four and the five once it reaches the five it’ll go to the body of the for Loop and then when it asks if that’s the last element the answer would be yes because it’s iterated through all the items within the list and then we would exit the loop and the for Loop would be over now that may not have made perfect sense but let’s actually start writing out the syntax of a for Loop so we can understand understand this better to start our for loop we’re going to say four and then we’re going to give it a temporary variable for this for Loop so it’s a variable as it iterates through these numbers it’s going to assign the variable to that number so for this one we’re just going to say number because it’s pretty appropriate because these are all numbers and then we’re going to say in integers now right here you can put just about anything this could be the list this could be a tuple this could be a string even but that is what we’re going to iterate through so we’re saying for the variables each of these numbers within this list of integers and then we’re going to write a colon this is the body of code that’s going to actually be executed when we run through and iterate through our list so for our first example we’re going to start off super simple and all we’re going to do is say print open parentheses and say number as it iterates through the one two 3 4 and five number becomes our variable that is going to be printed so during that first loop our one will be printed because that will be assigned right here then through the next iteration the two will be assigned and it’ll be put right here in each Loop until the very end so let’s hit shift enter and as you can see it did exactly that now in this body and I’ll copy and paste this down here in this body we really can do just about anything we want we don’t even have to use this variable number right here we can just print yep if we wanted to and and what it’s going to do is for each iteration all five of those every time it Loops through it’s going to print off yep so let’s hit shift enter and it printed it off for us so really we weren’t even using the numbers within the list we were really just using it as almost a counter now let’s copy this integers once again let’s go right up here and let’s go copy this for Loop that we wrote now we do not have to call this number this can be anything you want any variable name that you’d like to name it we could call it jelly and we can do jelly plus jelly I think you’re getting the picture right when it Loops through that one it’s doing one plus one when it Loops through the two it’s doing 2 + 2 that is basically how a for Loop works now for a dictionary it’s going to handle it a little bit differently so let’s create a dictionary really quickly so we’ll say ice cream d iary is equal to we’re going to do a squiggly brackets so we’re going to say name and we’re going to say colon we need to assign our value for that item so we’re going to say Alex freeberg we’ll do our next one separated by a comma and we’ll say weekly intake and I’ll say five Scoops per week the next one we will do is favorite ice creams and for this one we’re going to do something a little bit different for this we’re going to have a list list within this dictionary so we’ll say within our list of my favorite ice creams we’ll say mint chocolate chip and I’ll just do MCC for that and we’ll separate that out by a comma and we’ll say chocolate so now we have this dictionary ice cream dick and within it we have my name my weekly intake and my favorite ice creams with a list in there as well let’s hit shift enter and now we’re going to start writing our for Loop now the for Loop is going to look very similar but to call it dictionary it’s just a little bit different so we’re going to say for the cream in icore creamore dictionary. values and then we’re going to do parentheses and then a colon now we’re going to print the cream so in order to indicate what we actually want to pull we have to specify within the dictionary what we want are we pulling the item are we pulling the value we need to specify this so that’s why we have thist value right here so let’s run this and see what we get so as you can see we are pulling in the values right here that’s why we’re pulling in Alex freeberg 5 and mint chocolate chip SL chocolate now we are able to call both of those both the key and the value so let’s go right down here and we can do both the key and the value so we can pull two things at one time and we’re going to do this by saying do items so we could also do key if we just wanted to do a key but we want to do items so we going to do both of them so we’re going to go right down here and say four key and value in ice cream dictionary. items print and let’s write key and then we’ll do a comma and then let’s give it a little arrow or something like that uh something like this and then we’ll do a comma and we’ll say value and let’s print this off and see what we get so it’s looping through and for each key and value it’s saying here is the key so that’s the name then we have weekly intake then we have favorite ice creams it’s giving us a little arrow and then we’re also printing off the value so we have name Alex freeberg weekly intake five favorite ice creams mint chocolate chip and chocolate so now let’s talk about nested for Loops we’ve looked at for Loops we understand how they work and why they do what they do but what about a nested for Loop a for Loop within a for Loop for this example let’s create two separate lists let’s create flavors and let’s make that a list by making it a bracket and we’ll do vanilla the classic chocolate and then cookie dough all great flavors so that’s our first list and then we’re going to say toppings and we’ll do a bracket for that as well and we’ll say fudge and then we’ll do Oreos and then we’ll do Marsh mows is how you spell marshmallows I think it’s an e that looks wrong I might be spelling it wrong but that’s okay so let’s save this by clicking shift enter and now we have our flavors and our toppings so now let’s write our first for Loops we’re going to say 41 as in our number one for loop we’re going to say in flavors and we’ll do a colon we’ll click enter now we can write our second for Loop so we’re going to say 42 in toppings and then we’ll do a colon and enter and then we’re going to say print and we’ll do an open parenthesis and then we’re going to say one so we’re printing the one in flavors and then we’re going to say one comma we to say topped with comma two so what this is essentially going to do is we’re going to say for one we’re going to take the very first one in flavors and then we’re going to Loop through all of two as well so we’re going to Loop through hot fudge Oreos and marshmallows and once we print that off then we will Loop all the way back to Flavors and look at the next iteration or the next sequence within the first for Loop so let’s run this really quickly and see what we get so as you can see it goes vanilla vanilla vanilla and vanilla is topped with the hot fudge the Oreos and the marshmallows and then we start iterating through our second one in our first for Loop so there’s that hierarchy so we’re iterating completely through this one before we actually go to the very first for Loop and start iterating through that one again now that is essentially how a nested for Loop works these nested for Loops can get very complicated in fact for Loops in general can get very complicated the more you add to it and the more you’re wanting to do with it but that is basically how a for Loop and a nested for Loop Works hello everybody today we’re going to be taking a look at while Loops in Python the while loop in Python is used to iterate over a block of code as long as the test condition is true now the difference between a for Loop and a while loop is that a for Loop is going to iterate over the entire sequence regardless of a condition but the while loop is only going to iterate over that sequence as long as a specific condition is met once that condition is not met the code is going to stop and it’s not going to iterate through the rest of the sequence so if we take a look at this flowchart right here we’re going to enter this while loop and we have a test condition right here the first time that this test condition comes back false it’s going to exit the while loop so let’s start actually writing out the code and see how this while loop works so let’s create a variable we’re just going to say number is equal to one and then we’ll say while and now we need to write our condition that needs to be met in order for our block of code beneath this to run so we’re going to say while number is less than five and then we’ll do colon enter and now this is our block of code we’re going to say print and then we’ll say number now what we need to do is basically create a counter we’re going to say number equals number + 1 if you’ve never done something like this it’s kind of like a counter most people start it at zero in fact let’s start it at zero and then each time it runs through this while loop it’s going to add one to this number up here and then it’s going to become a one a two a three each time it iterates through this while loop now once this number is no longer less than five it’ll break out of the while loop and it will no longer run so let’s run this really quick by hitting shift enter so it starts at zero and it’s going to say while the number is less than five print number so the first time that it runs through it is zero and so it prints zero and then it adds one to number and then it continues that y Loop right here and it keeps looping through this portion it never goes back up here to this line of code this is just our variable that we start with and then once this condition is no longer met once it is false then it’s going to break out of that code now that we basically know how a y Loop Works let’s look at something called a break statement so let’s copy this right down here and what we’re going to say is if number is equal to three we’re going to break now with the break statement we can basically Stop the Loop even if the while condition is true so while this number is less than five it’s going to continue to Loop through but now we have this break statement so it’s going to say if the number equals three we’re going to break out of this while loop but if this is false we’re going to continue adding to that number just like normal so let’s execute this so as you can see it only went to three instead of four like before because each time it was running through this y while loop it was checking if the number was equal to three and once it got to three this became true and then we broke out of this while loop the next thing that I want to look at and we’ll copy this right down here is an else statement much like an if statement but we can use the else statement with a while loop which runs the block of code and when that condition is no longer true then it activates the else statement so we’ll go right down here and we’ll say else and we’ll do a colon and enter and then we’ll say print and we’ll say no no longer less than five now because this if statement is still in there it will break so let’s say six and then we’ll run this and so it’s going to iterate through this block of code and once this statement is no longer true once we break out of it we’re going to go to our else statement now as long as this statement is true it’s going to continue to iterate through but once this condition is not met then it will go to our L statement and we’ll run that line of code now the L statement is only going to trigger if the Y Loop no longer is true if we have something like this if statement that causes it to break out of the while loop the lse statement will no longer work so let’s say if the number is three and we run this the L statement is no longer going to trigger so this body of code will not be run now the next thing that I want to look at is the continue statement if the continue statement is triggered it basically rejects all remaining statements in the current iteration of the loop and then we’ll go to the next iteration now to demonstrate this I’m going to change this break into a continue so before when we had the break if the number was equal to three it would stop all the code completely but when we change this to continue which we’ll do right now what it’s going to do is it’s no longer going to run through any of the subsequent code in this block of code it’s just going to go straight up to the beginning and restart our while loop so what’s going to happen when we run this is it’s going to come to three it’s going to become three it’s going to continue back into the while loop but it’s never going to have that number changeed to be added to one to continue with the while loop this will create an infinite Loop let’s try this really quickly and as you can see it’s going to stay three forever eventually this would time out but I’m just going to stop the code really quick so if we just change up the order of which we’re doing things we’re going to say there and we’re going to put this down here so what it’s going to do now instead of printing the number immediately and then adding the number later we’re going to add the number right away and then we’re going to say if it is three we’re going to continue and it’s going to print the number so let’s try executing this and see what happens so as you can see we no longer have the three in our output what it did was when we got to the number three it continued and didn’t execute this right here which prints off that number hello everybody today we’re going to be taking a look at functions in Python a function is a block of code which is only run when you call it so right here we’re defining our function and then this is our body of code that when we actually call it is going to be ran so right here we have our function call and all we’re doing is putting the function with the parenthesis es that is basically us calling that function and then we have our output throughout this video I’m going to show you how to write a function as well as pass arguments to that function and then a few other things like arbitrary arguments keyword arguments and arbitrary keyword arguments all these things are really important to know when you are using functions so let’s get started by writing our very first function together we’re going to start off by saying DF that is the keyword for defining a function then we can actually name our function and for this one we’re just going to do first underscore function and then we do an open parenthesis and then we’ll put a colon we’ll hit enter and it’ll automatically indent for us and this is where our body of code is going to go now within our body of code we can write just about anything and in this video I’m not going to get super Advanced we’re just going to walk through the basics to make sure that you understand how to use functions so for right now all we’re going to say is print we’ll do an open parenthesis we’ll do an apostrophe and we’ll say we did it and now we’re going to hit shift enter and this is not going to do anything at least you won’t see any output from this if we want to see the output or we actually want to run that function and some functions don’t have outputs but if we want to run that function what we have to do is just copy this and put it right down here and now we’re going to actually call our function so let’s go ahead and click shift enter and now we’ve successfully called our first function this function is about as simple as it could possibly be but now let’s take it up a notch and start looking at arguments so let’s go right down here and we’re going to say Define number underscore squared we’ll do a parenthesis and our colon as well now really quickly when you’re naming your function it’s kind of like naming a variable you can use something like X or Y but I tend to like to be a little bit more descriptive but now let’s take a look at passing an argument into a function the argument is going to be passed right here in the parenthesis so for us I’m just going to call it a number and then we’re going to hit enter and now we’ll write our body of code and all we’re going to do for this is type print and open parenthesis and we’ll say number and we’ll do two stars at least that’s what I call it a star and a two and what this is going to do is it’s going to take the number that we pass into our function it’s going to put it right here in our body of code and then for what we’re doing it’s going to put it to the power of two and so when the user or you run this and call this function this number is something that you can specify it’s an argument that you can input that will then be run in this body of code so let’s copy this right here and then put it right down here into this next cell and we’ll say five and so this five is going to be passed through into this function and be called right here for this print statement let’s run it and it should come out as I believe 25 that is my fault I forgot to actually run this block of code so I’m going to hit shift enter so now we’ve defined our function up here and now we can actually call it so now we’ll hit shift enter and we got our output of 25 now in this function we only called one argument but you can basically call as many arguments arents as you want you just have to separate them by commas so let’s copy this and we’ll put it right down here now we’ll say number squared uncore custom and then we’ll do number and then we’ll do power so now we can specify our number as well as the power that we want to raise it to so instead of having two which is what you call hardcoded we can now customize that and we’ll have power and now when we call this function we can specify the number and the power and both of those will go into this body of code and be run and we can customize those numbers so let’s copy this and we’ll say 5 to the power of three and let’s make sure I Ram this so let’s do shift enter and now we will call our function and let’s hit shift enter and we got 5 to the^ of 3 which is 125 and just one last thing to mention is if you have two arguments within your function and you are calling right here you have to pass in two arguments you can’t just have one so if we have a five right here it’s going to error out we have to specify both Arguments for it to work now let’s take a look at arbitrary arguments now arbitrary arguments are really interesting because if you don’t know how many arguments you want to pass through if you don’t know if it’s a one a two or a three you can specify that later when you’re calling the argument so you don’t have to do it upfront and know that information ahead of time so let’s define our function so we’re going to say Define and then we’re going to say number underscore args and we’ll do an open parenthesis and a colon now within our argument right here typically we would just specify here’s what our argument will be it will be number or it will be a word right but what we’re going to do is something called an arbitrary argument so it’s unknown so we’re going to put star and then we’ll say args now you will see something exactly like this typically if you’re looking at tutorials that’ll have star args in there or you’re looking at just a generic piece of code this is what it will look like but for us we’re going to actually put number so again we have the star and then we have our arbitrary argument right here and then we’ll hit enter and we’re going to say print open parentheses and this is where it’s going to get a little bit different so we’re going to say number and then we’re going to do an open bracket and let’s say zero and then we’ll do that times and then we’ll say number again with a bracket of one so in a little bit once we run this and then we call this number args function right here we’re going to need to specify the number zero and the number one that’s going to be called so let’s go ahead and run this and then we are going to call it and let’s say 5 comma 6 comma 1 2 8 so right up here we did not know how many arguments we were going to pass through it could be five it could be a thousand and we could also call in a tuple and that’s what this is right here we’re calling in a tup so what it’s going to do now is when it calls this number it’s going to call the very first within that tupal which will be that five and then it’ll also call in this number which will be the first position which is the six so let’s hit shift enter and it’s going to multiply these numbers together so five * 6 is equal to 30 now like I just said this is a tuple so we don’t actually have to write out these numbers like we just did we can pass through a tuple when we are actually calling this function let’s do that right up here let’s just create um let’s call it argor Tuple and we’ll do open parentheses and we’ll do the same numbers let’s just copy it make it easier and now we’ve created this tupal right here which we can then pass in and this is a lot more handy a lot more specific and this is most likely how someone would do something like this but let’s now create this and now we can copy AR Tuple and pass it through now really quickly this is going to fail and I’m doing that on purpose but I want to show you what you need to do in order to pass through this tupal so right now it’s going to say Tuple index is out of range all you have to do in order to use this is you have to specify a star before it just like you did when you creating your argument up here we have to put a star in front of our Tuple that we just passed through and now let’s try running this and now it works properly now the last two things that we’re going to look at are keyword arguments and arbitrary keyword arguments there are more things that you can learn and do within functions but again I’m just trying to teach you the basics to make sure that you understand how they work so let’s go right up here and a keyword argument is kind of similar to this right here and let’s actually copy this and put it right down here now a keyword argument is very similar in that you’re going to specify your arguments right here but what we did up here let me bring this down when we actually called the function what we did was we just put a five and a three and when we did that it automatically assigned number to five and power to three and that’s totally fine and you can do that but if you want a little bit more control you can use a keyword argument so right here we could say our is equal to five and number is equal to three so I just switched it around right number was assigned to five and power was assigned to three but I just switched it to show you how this might work let’s run both of these and now it’s 3 to the^ of 5 which is 243 so that essentially is a keyword argument again it just gives you a little bit more control you don’t have to put them in specific positions like if you’re just calling multiple arguments now let’s come right down here we’re going to create basically another custom function uh so for this one we’re going to write Define number underscore org and then we’ll do an open parenthesis a colon and enter and what this one is is is this one is a keyword argument or an arbitrary keyword argument now to specify an arbitrary argument all we did was a star and then we input number but if we’re doing a keyword argument we actually have to have two stars right here so let’s start taking a look and again if you’re doing arbitrary it means we don’t really know how many keyword arguments we want to pass into our function so we’re just going to put star star number and then later within our body of code and when we’re calling it we’ll be able to specify it and just like the arbitrary argument before the arbitrary keyword argument means we really just don’t know how many keyword arguments we’re going to need to pass into our function so to demonstrate this let’s write print do an open parenthesis and we’ll say my oops need to do an apostrophe my number is we’ll do just like that little space and we’ll say plus and this is kind of where it gets a little interesting or a little bit more tricky so what we’re going to say is number So This Is Us calling our number and then we’re going to do a bracket and then I’m actually going to go to calling the function it’s a little bit backward or a little bit different than what you might think but when we’re calling it what I’m going to do is I’m going to say integer is equal to let’s just do some random number now when we’re calling that keyword within our body of code what we’re going to do is we’re going to actually type out integer just like this and this looks a little bit different but what this this allows us to do is we can put as many keyword arguments in here as we want later and I’ll show you in just a second but for us we’re just creating this key and this value when we are calling it within the function so now when we create this and we run this oh whoops I forgot this has to be a string um so let’s run this again now we will say my number is 2309 then we’re going to add we’ll say plus and this isn’t going to look great but we’ll say my other number this will all be in the same line that’s okay my other number and then we’ll say number and we can specify again what we want in there so now we can go down here to where we’re calling it we’ll just put a comma and we’ll say integer oops integer 2 is equal to we’ll do a random number and then we’ll put integer two right here and then we’ll add plus right here so we don’t error out we’ll create this we’ll run this and as you can see both numbers were passed through again the syntax is terrible but now you can see that you have this arbitrary keyword argument right here and all we have to do is put number number and we can pass through as many of these arbitrary keyword arguments as we want as long as we just specify within our function when we’re calling it hello everybody today we’re going to be talking about converting data types in Python in this video I’m going to show you how to convert several different data types in including strings numbers sets tupal and even dictionaries so let’s start off by creating a variable we’ll say numor int is equal to 7 and we can check that data type by saying type and then inserting our variable number undor int and that will tell us that our data type for this variable is an integer let’s go ahead and create another one we’re going to say numor string is equal to and for this one we’ll also do a seven but let’s check the type and and we’ll do an open parenthesis and we’ll say the type of num string and that one is a string now let’s say we wanted to add those we’ll say num underscore sum so the sum of numor int plus numor string now when we’re adding these two values it is not going to work it’s going to give us an error and it’s going to say unsupported operand for INT and string so it cannot add both an integer and a string what we need to do in order to add these two numbers is to convert that string into an integer so let’s go right up here let’s add another cell and let’s say numor string undor converted is equal to and we want to convert it into an integer so all we have to do to convert it into an integer is type int and then we’re going to say numor string and that is as easy as it’s going to get all we have to do is say integer with our numb string inside of it and then it’s going to convert it and we can even check it right after by saying type num string converted and let’s run this and now we can see that it was converted into an integer so now let’s add that num string converted right here let’s copy and replace that string with the string converted and let’s actually print out that numor sum and it worked properly now we did not specify what type of value this Num Sum was going to be but because it was two integers in here it’s going to automatically apply that data type of integer to that num suum let’s go right down here and now let’s look at how we can convert lists sets and tupal so now let’s say we have a listor type and that’s equal to 1 2 3 and we can check it again by saying type and that is a list let’s say we want to convert it to a tuple it’s fairly easy all we’re going to do is write Tuple say listor type that listor type is now going to be a tupal and we can check that by saying type and wrapping it around this tupal and it shows us that it is converting that list into a tupal now we can also convert a list into a set but it may change the actual values within it let’s check that out really quickly so let’s say we have this list and let’s add a few more values to this just like that now let’s say we want to convert it to a set so we’re going to run this and we’ll say set of listor type and let’s try running this and see what the output is so this is something that you really need to be aware of when you are converting data types because set does not act the same as a list a set is basically going to take the unique values in the list and convert it to a set and it fundamentally changes the data that was in that original list and just to check the data type we can say type I’m just doing this for all of them and as you can see that is now a set now let’s go down here and take a look at dictionaries now let’s say we have a dictionary called dictionary type and we’ll do a squiggly bracket and we’ll say name and we’ll do a colon and we’ll say Alex then we’ll do age and a colon and we’ll say 28 and then we’ll do hair col and so really quickly let’s take that dictionary type and just confirm that it is a dictionary and it is and now what we’re going to do is take a look at all the items within that dictionary so we’re going to do dictionary type. items open parenthesis and this is going to show us all the items within it now we can also take this and look at something like the values and when we run that these are our values So within our dictionary we have items and that’s what this is right here this is one item and then within that we have our values which are right here so Alex 28 and Na and then we have something called a key and this is the key the name age and hair are all keys and we can look at that by saying dot keys so let’s say we want to take all of the keys and put that into a list what we’re going to do is we’re going to take this right here to say list we’ll do an open parenthesis we’ll type that in right there so it says a list and we’re converting these Keys into a list and let’s run that and now this is a list and let’s just check the type as well just to confirm and as you can see it was converted properly into a list and we can do the exact same thing with value Val and the values can also be converted into a list now we can also convert longer strings that aren’t just numbers like we did above in our very first example so let’s do longcore string and we’ll say I like to party now we’re going to take this string and we’re going to say list long string so we’re going to convert this string into a list and let’s see what happens so it took every single character in that string and put it into a list and we could also do a set as well that one’s a lot shorter because it’s only looking at unique values so that is how you convert data types in Python hello everybody today we’re going to be working on building a BMI calculator in Python now before we get started I want to show you this BMI calculator that I found online and it shows you the basic calculation that they use and that’s the one we’re going to use in this video and they also have this calculator right down here and some ranges that we can use for our calculator as well so for reference I weigh about 170 I’m about 59 let’s calculate this so I’m about a 25.1 BMI which falls into the overweight category that’s unfortunate but we can see exactly how this works and how RS should work when we actually build it so we’re going to kind of reference this throughout the video so let’s go right over here to our BMI calculator we need to calculate weight and height and then run this calculation right here so let’s go ahead and copy this and we’re going to put it right down here and so now we have our calculation so what we need is we need input from a user and there is an input function within python that we’re going to be using so let’s actually give me a few more cells so the first thing that we need to calculate is their weight let’s type out weight right here we’ll say weight is equal to and this is where we’ll use our input function so we’ll say input and when we actually run this it’s just going to give us this blank square or a user can input something we’ll say Alex so this is our output is what the actual user input and it does save it to this variable so if we say print weight it will still print out Alex now this is where we want the user to just like we did before where they’ll input their weight so we want to kind of give them a prompt for this we’ll put a string in here so I’ll do a double quote and then I’ll say enter your weight in and we’re using pounds say pounds colon space so now when we do this it’ll say enter your weight in pounds I’ll say 170 and then when we run this it does store that now let’s do print I should have saved it wait again oops now it’s only storing the value of 170 it’s not actually storing this string right here so that’s really important for when we do our calculations later um I’m going to I’m going to save this right down here because I’m sure I’m going to use that later um so we have that it’s working now we need to also do our height so let’s copy this and we’ll put it right here and we’ll do height and enter your height in inches so now for this one if we hit enter it’s actually running let’s stop it really quick and interrupt it let’s try running this so it’s going to say enter your weight and pounds that’s the first input say 170 and then when I hit enter it’s going to prompt me for that second input and so in inches 59 is 69 in and then I can hit enter again and now we have both of our inputs now we need this calculation right down here and just like that so now we have weight in pounds * 703 divided by height in inches by height in inches so we actually have weight and it’s already written in there but I’m just going to do it like this we’ll do weight time 703 so that’s pounds there our weight in pounds time 703 divided by now we have our height in inches times the height in inches so this is our calculation right here so let’s do this exact same thing let’s run this and this times of course is not going to work oops we need to do our star for both of these right now this is our calculation so let’s run this so we have 170 and that’s pounds and inches was 69 hit enter and it says cannot multiply the sequence of non- integer type of string Ah that’s because these are being stored in strings if right down here I do and we’ll do type of height we run that this is actually a string so we want to change that cuz we don’t need that anymore that so we don’t want it to be a string we need those to be integers or Floats or really anything besides a string it just needs to be numerical so integer float really so let’s do integer and we’ll wrap that input in it and we’ll do the same thing for this one now we have an integer for our weight an integer for our height so now when we’re running this calculation it should work properly let’s run this again our pounds are 70 our height is 69 in and it’s not giving us our output because we’re not printing anything okay so I just need to do print BMI so let’s try this again 1 70 69 and there is our BMI 25.1 so it worked the exact same as this one so they input well we input our height we inputed our or we inputed our weight we inputed our height and then it calculated rbmi the next thing that we need to do is we need to kind of give the user some context is that good is there BMI in within a good range a bad range we don’t know uh so let’s go ahead and I’m going to see if I can copy this know if this will work or not let’s go ahead and copy this right down here perfect so what we now need to do is we need to say okay if the user has given us this input we want to give them or tell them if they are a normal weight overweight obese severely obese anything like that and we have these ranges so that should help us out quite a bit so let’s just write our if statement and then we’ll include it up here but let’s go down here and we’ll say if and then we’ll do BMI and let’s just say BMI is greater than zero so if it’s greater than zero if they had any input where the BMI was not zero which should be every time if they do it properly don’t you know put a string in there or something or type out 40 which maybe we should make a prompt for that if that happens then we can say if we’ll do BMI and now we need to give that first range so this range right here so if it’s under 18.5 so we need to do a less than so if it’s less than 18.5 and it just says under it doesn’t say under or equal to so I’ll keep it at 18.5 so if it’s under 18.5 then let’s give kind of the output we’ll say print and the output or the basically the prompt is underweight so we’ll just say you are under under case underweight and just like that um then we’re going to pass several ellf statements through here well let’s just say else so I guess this would be like if they are if they don’t input something properly or something messes up maybe I we could write something like um print oops I’m thinking all this through we can write print enter valid inputs or something like this or we can always change that but let’s really quickly let’s run this okay so I’m not in that range uh let’s make the next one so then I can be within a certain range oops and we need we should need one more a minimum so we’ll say LF and LF these next two are this 24.9 so it’s going to check this one first so if it’s 18.5 or below 18.5 it’s automatically going to print this one so this next one we don’t have to do like a range or anything we can just say if it’s below if it’s between 25 and 20 9.9 so this one actually should be less than or equal to um this one is normal oh whoops 24.9 so this one is 24.9 this one is going to say you are normal weight so let’s run this now let’s see BMI was 25.1 oh guys I’m just messing up here I apologize all right this is the one that I was part of so now it’s going to be part of the overweight crowd now let’s run this and now our prompt is you are overweight because remember the BMI was saved right here as 25.1 down here if we run through this it’s saying no you’re not in oops get rid of that no you’re not in under 18.5 you’re not under 24.9 if you are under 29.9 you are overweight so that did work properly so that’s really good and I don’t think I want this to be our output for the person because we’re going to add this up here it’s just going to give us the BMI and then the output is going to say you are overweight uh let’s make it a little bit more customized um I’m going to say name is equal to input and then we’ll say enter your name um so it’ll be enter your name we’ll do Alex 70 69 there’s our BMI now it’s going to run through this logic or it will run through this logic in just a second when we actually finished this then we have 34.9 and let’s do one more oops and then this one’s going to be for 39.9 so this one was overweight this one is obese severely obese OB we’ll say severely you spell it severely obese and then anything that’s over that 40 and over so if it’s not this one anything else should be S morbidly obese so actually this else statement right here should say uh you are you are severely obese this is going to say morbidly morbidly obese now I added that name up here here because I wanted to add that down below actually so we’re going to say uh name plus and then we’ll do like comma you are underweight so it’ll be a little bit more personalized uh I think it’ll I think it’ll be a nice touch I really do we’ll do it like this and we’ll say you and let’s go back and do that to all of them and let me see how quickly I can do this oh whoops what I do got rid of that name plus u like that geez you guys are seeing me mess up a ton name plus you and then name plus you so now let’s run this and now it’s a little more personalized it says Alex you are overweight so this is all really good now this is an if statement um what we had done before I think is actually what we should put right down here so we’ll say else and then if that doesn’t work we’ll say what do we say enter valid input we’ll just put that um and let let me see if I can test this out don’t I don’t know if this will error out or if this will even work let me just see if I can mess with it and see if I can get it to work actually let’s copy this we’re going to copy this whole thing we’re going to include it right here and now we have basically our entire calculator so um let’s run this enter your name we’ll say Alex enter your pounds 170 Ander your inches 69 and then it’s going to say 25.1 Alex you are overweight and that’s perfect we could even go as far as adding like some feedback we could say you are overweight and then it would be a period and we could say um you need to exercise more stop sitting and writing so many python tutorials so now if we run this we’ll do Alex 17069 it says Alex you are overweight you need to exercise more and stop sitting and writing so many python tutorials period and that’s it this is the entire project um you can go a ton farther you can include much more complex logic you could even build out a UI to create your own you know app just like this where it has this input and this UI you can build that out with in jupyter notebooks with python um but that’s not really what this tutorial is for this is just to kind of help you um think through some of the logic of creating something like this hello everybody in this lesson we’re going to be taking a look at beautiful soup and requests now these packages in Python are really useful these are the two main ones that I use when I was first starting out with web scraping it can get a lot of what you want done in order to get that information out now of course there are other packages that you can use that may be a little bit more advanced but again this is just the beginner Series in a future series we’ll look at other packages as well that have some more advanced functionality so what we’re going to be doing is we’re going to import these packages and then we’re going to get all of the HTML from our website and make sure that it’s in a usable State and then in the next lesson we’re going to kind of query around in the HTML kind of pick and choose exactly what we want we’ll look at things like tags variable strings classes attributes and more so let’s get started by importing our packages what we’re going to say is from bs4 this is the module that we’re taking it from we’re going to say import and then we’ll do beautiful soup then we’re going to come down and we’re going to say import requests now let’s go ahead and run this I’m going to hit shift enter and it works well for me now if this do does not work for you you may potentially need to actually install bs4 so you may have to go to your terminal window and say pip install bs4 I’ll just let you Google how to do that if you need to do that CU it’s pretty easy but if you’re using Jupiter notebooks through Anaconda like how we set it up at the beginning of this python series then you should be totally fine it should be there for you the next thing that we need to do is specify where we’re taking this HTML from so what we need to actually do is come right over here to our web page and we need to get the URL so we’re going to go here we’re going to copy this URL and I’m just going to put it right here for a second and what we’re going to do is we’re going to be using this URL quite a bit so we just want to assign it to a variable so just say URL is equal to and then we’ll put it right in here now we can get rid of that so now this is our URL going forward this is where we’re going be pulling data from let’s go ahead and run this now we’re going to use requests and what we’re going to do is we’re going to say requests.get and then we’re going to put in url now this get function is going to use the request Library it’s going to send a get request to that URL and it’s going to return a response object let’s go ahead and run this as you can see here I got a response of 200 if you got something like a 204 or a 400 or 401 or 404 all of these things are potentially bad something like a 204 would mean there was no content in the actual web page 400 means a bad request so it was invalid the server couldn’t process it and you don’t get any response if you you got a 404 that might be one that you’re familiar with that’s an error that means the server cannot be found the next thing that we’re going to do is take the HTML now if you remember we come right back here and we inspect this we have all of this HTML right here now on this web page specifically right now it’s completely static it’s not a bunch of moving stuff or anything like that usually when you’re looking at HTML if you’re looking at something like Amazon and those web pages can update but when you actually pull that into python you’re basically getting a snapshot of the HTM at that time so what we’re going to do is bring in all of this HTML which is our snapshot of our website and then we can take a look at it so we’re going to come right down here and now we’re going to say beautiful soup so now we’ll use the beautiful soup package or Library so we need to say beautiful soup and we’re going do an open parenthesis we’re going to do two things there’s two parameters that we need to put in here first we need to put in this get request we actually need to name this and we’ll call this page we’ll say page is equal to and let’s run this and now we’re going to put that page in here and what we’re going to say is text so the page is what’s sending that request and then the text is what’s retrieving the actual raw HTML that we’re going to be using then we’re going to put a comma here and what we need to specify is how we’re going to parse this information now this is an HTML so what we’re going to do is HTML just like this this is a standard this already built into to this Library so we don’t need to go any further but it’s basically going to parse the information in an HTML format now let’s go ahead and run this let’s see what we get and as you can see we have a lot of information and as we scroll down I’ll try to point out some things that we’ve already looked at in previous lessons umm something like this th tag that should be very similar that’s the title then we have these TD tags and then of course if we scroll down even further we’ll have things like ATR tag so these are all things that we looked at in that first lesson when learning about HTML now again we want to assign this to a variable so we’re going to say soup that’s going to say equal to this information right here now I’m not going to go into all the history behind beautiful soup what I will say is the guy who created this beautiful soup Library uh what he said was is that it takes this really messy HTML or XML which you can also use it for and makes it into this kind of beautiful soup so I just thought that was kind of funny uh but that’s why we’re calling it soup right here and we’re going to go ahead and run this and we’ll come right down here here and we’ll say print soup and let’s run it and now we have everything in here so we have our HTML our head we have some HR and some links in here let scroll down a little bit more and then we have our body right there and of course we have a bunch of information in here now in the next lesson what we’re going to be doing is learning how to kind of query all of this to take specific information out and basically understand a lot of what’s going on in this HTML to make sure we can actually get what we need now if this looks really kind of messy to you and it just doesn’t make a lot of sense there is one more thing that I’m going to show you and we’ll come right down here so we’ll say soup. prettify and if you’ve ever used a different type of programming languages uh pry is very common in a lot of them where it’ll just make it a little bit more easy to visualize and see uh you’ll notice that it kind of has this hierarchy built in whereas if we scroll up there’s no hierarchy built in it’s all just down this left hand side so if you kind of want to view it and just kind of visually see the differences this does help a lot but it doesn’t actually help a lot when you’re you know querying it or using you know find and find all which is what we’re going to look at in the next lesson now the first thing that we need to learn is HTML HTML stands for hypertext markup language and it’s used to describe all of the elements on a web page now when we actually go to a website and start pulling data and information we need to know HTML so we can specify exactly what we want to take off of that website so that’s where HTML comes in and we’re going to look at the basics understanding just the basic structure of HTML then we’ll go look at a real website and you’ll kind of see that’s a little bit more difficult than what we just have right here but this is the basic building blocks to get to what the HTML actually looks like on a website now this is basically what HTML looks like we have these angled brackets with things like HTML head title body and then you’ll notice that at the end we’ll have a body and then we’ll have a body at the bottom this forward SL body denotes that this is the end of the body section in HTML so everything inside of this is within this body so there is this hierarchy within HTML we have HTML and HTML at the bottom which encapsulates all the HTML on the website then we have things like head and head body and body now Within These sections we usually have things like classes tags attributes text and all these other things things that we’ll get to in different lessons but one of the easiest ones to notice and look at are tags things like a P tag or a title tag now Within These tags because this is a super simple example we have these strings here my first web page and this is what’s called a variable string and this is actual text that we could take out of this web page now that you understand the super basics of HTML let’s actually go to our website and I’m going to have a link down below but it’s going to be this one right here this is basically just a website that you can you know practice web scraping on it’s called scrape the site.com and what we’re going to do is look at the HTML behind this web page and you can do this on any website that you go on so we’re going to right click we’re going to go down to inspect now right off the bat this looks a lot more complicated and a lot more complex than the very simple illustration that we’re looking at but let’s kind of roll this up just a little bit you’ll notice we have HTML and HTM at the bottom we have a head and there is the end of the head and then a body and the end of the body so in a super simple sense it is similar but just the information that’s within it is a lot more difficult now if we look at this title right here this is our title tag if we click this little arrow this is our drop- down you’ll notice that here we have the string hockey teams forms searching imagination now let’s say we didn’t know we didn’t want to click on that and go find it there’s something that’s super helpful within this inspection page that you can click on right here it says select an element in the page to inspect it so we’re going to click on that and as we go through our page and let’s click on this title it’s going to take us to exactly where this is in our HTML this is extremely helpful extremely useful for example let’s say the data I want is down here I want to take in the Boston Bruins I can click on it and it’s going to take me to where that is exactly in the HTML this is where we can start writing our web scraping script to specify okay I’m looking for a TR tag I’m looking for a TD tag I’m looking for the class called team this is all information and things that we can use to specify exactly what we want to pull out of our web page now there are other things that we didn’t really look at as well in just our simple illustration let’s come right over here there’s things like HRS now these are hyperlinks so if we went and then clicked on this this is just regular text but inside of it is this hyperlink where if we clicked on it it would take us to another website and typically that’s denoted by this hre right here then you’ll typically see things like a P tag which usually stands for a paragraph now the last thing that I want to show you while we’re here and we’re going to learn a lot more in the next several lessons but if we come right down here there is this actual entire table here and let’s try to find this table and I’m having trouble selecting the entire thing but let’s select this team name and if we look at this team name you can see that this is encapsulating the tables this table tag now these are super helpful because it takes in the entire table now if we wrap this up and we look just at this it says class table and then we have the end of this table tag now when we open it it’s going to have all of this information so as you can see as I’m highlighting over it we have these th tags and we have these TD tags and even these TR tags which is the individual data and this is something that we’ll look at when we’re actually scraping all of the data from this table in a few future lesson so this is how we can use HTML how we can inspect the web page and see exactly what’s going on kind of under the hood and then in future lessons we’ll see how we can use this HTML to specify exactly what data we want to pull out thank hello everybody in this lesson we’re going to be taking a look at find and find all really we’re going to be looking at a ton of different things in this lesson this is where we really start digging in seeing how we can extract specific information from our web page but in order to do that let’s set everything up where we actually bring in the HTML like we did in the last lesson and we’re just going to write all this out one more time just for practice if nothing else and then we’ll get into actually getting that information from the HTML so we’re going to start by saying from bs4 import beautiful soup there we go and import requests we’ll go ahead and run this then we’re going to come up here grab our HTML or sorry our URL we’ll say URL is equal to to and we’ll have that right here now we need to say page is equal to and then we’ll do requests.get and then we’ll put in our URL right here and we’re going to come over here and run this and lastly we need to say soup so we’ll say soup is equal to beautiful soup there we go and then within our parentheses we need to specify the page. text because we need that and our parser which is HTML and there we go and let’s go ahead and run this let’s print it out make sure it’s working and there we go so we have our soup right here all this should look really similar to uh our last lesson and so now we’ brought in our HTML from our page we have a lot a lot a lot of information in here now really quickly let’s come over and let’s inspect our web page now in here we have a ton of information right we have bunch of different tags and classes and all these other things but how do we actually use these well that’s where the find and find all is going to come into play and they’re pretty similar and you’ll see that in just a little bit but let’s say we want to take uh one of these tags and let’s come down let’s say we just want to take this div tag now there’s going to be a lot of different div tags in our HTML but let’s just come right here let’s go down and let’s say we’re going to call soup we’re going to say soup that’s all of our information we’re going to say do find now within our parentheses we can specify a lot of different things but we’re going to keep it really simple right now we’re just going to say di let’s go ahead and run this what this is going to bring up is the very first div tag in our HTML and that’s going to be this information right here now let’s copy this and we’re going to do the exact same thing except we’re going to say find underscore all now let’s run this now we’re going to have a ton more information really all find and find all do is that they find the information now find is only going to find the first response in our HTML lead that’s the div class container let’s go back up to the top that’s our div class container but find all is going to find all of them so it’ll put it in this list for you so it’s going to have this first one and it goes down to uh this word SL div which should be right here and then we have have a comma which separates our next div tag so that is how we can use it now what if we want to specify one of these div tags we pulled in a ton of them but we want to just look for one of them well this is something where the class comes in handy because right now we have classes equal to container class is equal to co md-12 I don’t know what these are at the off the top of my head but um usually they’ll be somewhat unique and we can use these to help us specify what we’re looking for for example just kind of glancing of this we could also use this a tag if we wanted to look at this so we could say oh we’re looking for uh these H refs so we have an hre here and this right down here we have this hre as well which again uh if you remember from previous lesson that stands for a hyperlink now something like the class or the href um or these IDs these are all attributes so we can specify or kind of filter Down based off of these now let’s try it so what we can do is we can do class first and this is kind of the default uh within something like find all is you can even do class underscore we can come right back up we have this div and then here’s our class so again we have to have the div and the class if we took this a tag this is an a tag which would go right here with the class of something like navlink or something like navlink again down here we need to specify that more but we have our div so we’ll say CL Cole md12 right here and let’s go ahead and run this and now it’s going to pull in just that information now we’re still getting a list because we have multiple of these so this div class uh Co md-12 doesn’t just happen once if we scroll down we’ll see it multiple times something like right here uh or actually let me see right here so here’s this comma then here’s our next one so we have two of these uh div tags with a class of coal- md-12 and in each of these we have different information this looks like a paragraph with this P tag right here and let’s scroll back up uh so I also think we should try out doing something like this P tag typically these P tags stand for paragraphs or they have text information in them let’s try to P tag really quickly let’s just see what we get and let’s run this and it looks like we get multiple P tags now if we come back here you can see that there’s this information and it’s this information that we’re pulling in and I’m just you know noticing that from right here and then we have this information right here and it looks like there’s one more which is this hre which looks like this open source so data via and then that uh hyperlink or that link right there so we have three different P tags now just to verify and make sure that that’s correct what we could do is come over here we’re going to click on this paragraph it’s going to take us to that P tag where the class is equal to lead let’s come over here and look at this paragraph now we have another P tag right over here where the class is equal to glyphicon glyphicon education I have no idea what that means um and then we’ll go to our last one which is right here where the P tag is equal to uh we have AAG hre class uh and a bunch of other information so let’s say we just wanted to pull in this paragraph right here let’s go here and see how we can specify this information so it looks like P or the class is equal to lead that looks like it’s going to be unique to just that one so if we come down here we’re going to say comma and it was class so you can do uh class underscore is equal to and then we’re going to say lead let’s try running this and we’re just pulling in that information now let’s say we actually want to pull in this paragraph We actually want this text right here and this is a very real use case you know let’s say I’m trying to pull in some information or or a paragraph of text well let’s copy this and what we’re going to then do is say. text and let’s run this now we’re going to get an error right here and this is a very common error because we’re trying to use find all unfortunately find all does not have a text attribute we actually need to change this to find typically when I’m working with these find and find alls I’m using find all most of the time until I want to start extracting text then when I specify it I’ll change this back to find just like this now let’s try this and now we’re getting in parentheses this information now this is all wonky it needs to definitely be cleaned up a little bit but if we Cod back up it’s no longer in a list and we no longer have things like these P tags in here or this class attribute so we’re really just trying to pull out this information now again this does not look perfect we could even trying to do something like strip look like there’s some white space uh that cleans it up a little bit this definitely looks a little better um and we could definitely go in here and clean this up more but just for you know an example this is how we can then extract that information now let’s look at one more example this is some information and this is what we’re going to do kind of our little mini project in the next lesson on let’s say we wanted to take all this information well what if we wanted to pull in something like the team name that’s going to be in right here in this TR tag and each of these TR tags have th tags underneath them so if we scroll down you’ll notice that each row is this TR tag so let’s go ahead and search for let’s do th let’s just search for that first so let’s come right back up here let’s use this find all and we’ll get rid of this text for right now and let’s just say we want to look for the TR is that what we said we were looking for no th so let’s say we’re looking for th let’s go ahead and run this so we’re going to have underneath this th we have team name year wins losses and notice these are all the titles so these titles are the only ones with these th tags if we go down you’ll notice that the data is actually TD tags so now let’s go back and look for TD we’ll say d and this is going to be a lot longer we have a lot of information but these are all the rows of data let’s see if we can just get one piece of this data we’re going to get back we want just this team name that’s all we’re trying to pull in for now um and then we’ll try to get this row and then in the next lesson we’re going to try to get all of this information make it look really nice and then we’ll put it into a panda’s data frame so let’s just get this team name right now let’s go ahead we’re going to say th let’s run this and we have this th and now that we know we’re getting this information in we can do find let’s run this so there’s our team name I’m just going to say. text and again we can do do strip just like that and Bam we have our team name so you can kind of start getting the idea of how we’re pulling this information out we’re really just specifying exactly what we’re seeing in this HTML and and what’s really really helpful and you know something that I do all the time is I’m inspecting it I’m just kind of searching like how what do I want what piece of information do I want then I go ahead and click on it and then I’m looking you know where is this sitting in the hierarchy it’s within the body it’s within this table with the class of table then it’s down here where this TR tag and then this TD tag so I’m looking kind of at the hierarchy and I’m specifying exactly what I’m looking for so that is what we’re going to look at in today’s lesson that’s how we can use f find and find all we were able to look at classes and tags and attributes and variable strings which is this right here getting that text uh and variable strings and we will look at find and find all and how it’s pulling that information in and how we can specify exactly what we’re looking for hello everybody in this lesson we are going to be scraping data from a real website and putting it into a panda’s data frame and maybe even exporting it to CSV if we’re feeling a bit spicy now in the last several lessons we’ve been looking at this page right here and I even promised that we were going to be pulling this data but as I was building out the project I just I honestly thought it was a little bit too easy since in the last lesson we kind of already pulled out some information from this table and I want to kind of throw you guys off so we’re going to be pulling from a different table we’re going to be going on to Wikipedia and looking at the list of the largest companies in the United States by revenue and we’re going to be pulling all of this information so if you thought this was going to be easy in a little mini project uh it’s now a full project because why not so let’s get started uh what we’re going to do is we’re going to import beautiful soup and requests we’re going to get this information and we’re going to see how we can do this and it’s going to get a little bit more complicated and a little bit more tricky we’re going to have to you know format things properly to get it into our Panda data frame to make it looking good and making it more usable so let’s go ahead and get rid of this easy table we don’t want that one uh and we’re going to come in here and we’re just going to start off this should look uh really familiar by now we’re going to say from bs4 import beautiful soup I don’t know if you’ve noticed but I’ve messed up spelling beautiful soup in every single uh video I’ve noticed uh let’s run this and now we need to go ahead and get our URL so let’s come up here let’s get our URL say URL is equal to and we’ll just keep it all in the same thing really quickly because we know this by Heart by now right uh we’ll say request. get and then URL to make sure that we’re getting that information it give us a response object um hopefully it’ll be 200 that’ll mean a good response and then we’ll say soup is equal to and then we’ll say beautiful soup and we’ll do our page. text now we’re pulling in the information from this URL and then we use our parser which will be oops HTML and let’s go ahead and run this looks like everything went well let’s print our soup now this is completely new to you it’s completely new to me I don’t know what I’m doing uh but it looks like we’re pulling in the information am I right so we got a lot of things going for us uh the uh stuff was imported properly we got our URL we got our soup which is uh not beautiful in my opinion but let’s keep on rolling let’s come right down here now what we need to do is we need to specify what data we’re looking for so let’s come and let’s inspect this web page now the only information that we’re going to want want is right in here we’re going to want these uh titles or these headers whoops so we’re going to want rank name industry Etc and then we are for sure going to want all of this information let’s just scroll down see if there’s anything tricky in here all right that looks pretty good uh and there is another table so there’s not just one table in here there are two tables in this page so that might change things for us but let’s come right back and let’s inspect our page by using this little button right here and let’s specify in let’s see if I can highlight just this page oh it’s not oh let’s do that right there so now we have this uh Wiki table sorter now I’m going to actually come right here I’m going to copy and I’m just going to say copy the outer HTML I’m just going to paste it in here real quick and that’s a ton of information I didn’t think it was going to copy all of it and we’re just going to delete that I just wanted to keep that class uh because I wanted to then come right down here at the bottom and just see what this table uh looks like I don’t know if it’s part of it or if it’s a if it’s its own table um I can’t tell let’s look at this Rank and let’s come up so it says uh it’s under this table and it looks like it’s its own table but it says Wiki table sort sortable jQuery table sorter what could be do a sortable jQuery table Ser so it looks like there are two tables with the same class which shouldn’t be a problem if we’re using find to get our text because we should be taking the first one which will be this table and this is the table we want um and if we wanted this one we could just use find all and since it’s a list we could use indexing to pull this table right um but I think we’re going to be okay with just pulling in this one so let’s go ahead and let’s do our find so we’ll do soup. find and we could find all or we could just do find a table let’s just try this and see what we get and if it pulls in the right one that we’re looking for that’ be great now this does not look correct at all um I don’t know what table it’s pulling in oh maybe it’s this right here this might be a table yeah it is so we have this uh box more citations so actually we are going to have to do exactly like what I was talking about uh let’s pull this and we well we could do comma class uh right here and let’s do both you know what this is a learning opportunity let’s do both so let me go back up to the top because I need these um and what we’re going to do let come right down here I want to add in uh another thing actually I’ll just push this one up there we go so we’re going to say findor all let’s run this so now we have multiple and again we got that weird one first but if we scroll down here’s our comma and then here’s our wik Wiki table sortable and then we have rank name industry all the ones that we were hoping to see and I guarantee you if you scroll all the way to the bottom um we’re going to see potentially Wells Fargo Goldman Sachs I’m pretty sure those are um let’s see yeah here we go like Ford motor Wells Fargo Goldman Soxs that’s this table right here so now we’re looking at the third table but again this is a list so we can use indexing on this and we’ll just choose not position zero because that’s this one right here which we did not like well now we’ll take position one let’s run this let’s go back up to the top and this is our table right here rank name industry this is the information that that we were actually wanting just to confirm rank name industry Etc so this is the information we’re wanting and we’re able to specify that with our find all and this is the information we want so we now want to make this the only information that we’re looking at so I’m just going to copy this we didn’t need to use our class for this one you could probably could have um but we could so let’s actually um put this right down here this will be our table we’ll say equal to but then I’ll come right here and I’m going to say soup. find this is just for demonstration purposes we do table comma glcore is equal to and then we’ll look at this right here whoops me do this let’s see if we get the correct output and let’s run this and looks like we’re getting a nun type object uh if I remember looks like the actual class is this right here so let’s run this instead and I got to get rid of the index there we go okay so we were able to pull it in just using the find so the find table class and it says Wiki table sortable at least that’s the HTML that we’re pulling in right here let me go back because I don’t I don’t know if that’s what I was seeing earlier let’s just get this rank let’s go back up where’s the rank go rank there we go so here’s our Rank and let’s go up to the table and there’s our class yeah and and that’s just uh to me that’s a little bit odd so it says Wiki table sortable jQuery Das table sorder right here but in our actual um in our actual python script that were running it was only pulling in the wiki table sortable so it wasn’t pulling in the jQuery dasht sorter why uh I’m not 100% sure but all things that we’re working through and we were able to uh we were able to figure out so we’re going to make this our table we’re going to say tables equal to uh soup. findall and let’s run this and if we print out our table we have this table now this is our only data that we are looking at now the first thing that I want to get is I want to get these titles or these headers right here that’s what we’re going to get first so let’s go in here we can just look in this information you can see that these are with these th tags and we can pull out those th tags really easily let’s come right down here we’re just going to say t and we can get rid of this let’s run this now these are our only th tags because everything else is a TR tag for these rows of data so these th tags are pretty unique which makes it really easy which is really great because then we can just do worldcore titles is equal to so now we have these titles but uh they’re not perfect but what we’re going to do is we’re going to Loop through it so I’m going to say worldcore titles and I’ll kind of walk through what I’m talking about is in a list and each one is Within These th tags so th and then there’s our um string that we’re trying to get so we can easily take this list and use list comprehension and we can do that right down here so I’m going to keep this to where we can see it um we’ll do worldcore tore titles that’s equal to now we’ll do our list comprehension should be super easy uh we’ll just say for title in worldcore titles and then what do we want we want title. text that’s it um because we’re just taking the text from each of these we’re just looping through and we’re getting rank then We’re looping through getting name looping through getting industry that’s it so let’s go and print our world table titles and see if it worked and it’s did uh this looks like it needs to be cleaned up just a little bit so let’s go ahead and do that while we’re here before we actually put it into the uh P’s data frame oops I just wanted uh I just wanted this actually so what we’re going to do is try to get rid of those back slash ends if we do dot strip that may actually not work yeah uh because this is a list what we need to do is we can actually do it dot. text. strip right here let’s try to do it in there there there we go so now we have uh this and now this world tables is good to go now I’m actually noticing one thing that may be odd yeah so we have rank name industry it goes to headquarters but then in here we’re getting rank name industry and then the profits which is from this table right here which we don’t want uh let’s scroll back up let’s kind of backtrack this and see where this happened we did find all table we’re looking at the first one right and then we’re doing [Music] headquarters uh so we’re doing print table ah okay I think I found the issue here and let’s backtrack again this is we’re working through this together we’re going to make mistakes uh the table is what we actually wanted to do we just did soup. findall th which is going to pull in that secondary table um jeez we were not thinking here um so now we need to do find all on the table not the soup because now we were looking at all of them oh what a rookie mistake okay uh let’s go back now let’s look at this now it’s just down to headquarters okay okay let’s go ahead and run this let’s run this now we just have headquarters now let’s run this now we are sitting pretty okay excuse my mistakes Hey listen you know if it happens to me it happens to you I promise you this is you know this is a project this a little U little project we’re creating here so we’re going to run into issues and that’s okay we’re figuring out as we go now what I want to do before we start pulling in all the data is I want to put this into our Panda data frame we’ll have the uh you know headers there for us to go so we won’t have to get that later and it just makes it easier uh in general trust me so we’re going to import pandas as PD let’s go ahead and run this and now we’re going to create our data frame so we’ll say PD dot now we have these world uh t titles so what we’re going to do is pd. data frame and then in here for our columns we’ll say that’s equal to the world table titles and let’s just go ahead and say that’s our data frame and call our data frame right here let’s run it there we go so we were able to pull out and extract those headers and those titles of these columns we’re able to put it into our data frame so we’re set up and we’re ready to go we’re rocking and rolling the next thing we need let’s go back up next thing we need is to start pulling in this data right here so we have to see how we can pull this data in now if you remember that we had those th tags those were our titles as you can see I’m highlighting over it but down here now we have these TD tags and those are all encapsulated within a TR tag so these TR represent the rows right then the D represents the data within those rows so R for rows D for data so let’s see how we can use that in order to get the information that we want so let’s go back up here just going to take this cuz again we’re only pulling from table not soup not soup what were we thinking um and let’s go ahead and let’s look at TR let’s run this now when we’re doing this TR these do come in with the headers so we’re going to have to later on we’re going to have to get rid of these we don’t want to pull those in um and have that as part of our data but if we scroll down there’s our Walmart um we have the location these are all with these TD tags and then of course it’s separated by a comma then we have our td2 so above we had our td1 so Row one row two Row three all the way down now we will easily be able to use this right because this is our column data and we can even call it that column underscore data is equal to we’ll run that um and what we’re going to do is we’re going to Loop through that cuz it was all in a list so we’re going to Loop through that information but instead of looking at the TR tag we’re going to look at the T D tag so let’s come right down here we’ll say for the row in column row and we’ll do a colon now we need to Loop through this we’ll do something like row. findor all and then what are we looking for we’re not looking for the TR looking for the TD and just for now let’s print this off see what this looks like apparently I didn’t run this uh column data that’s why and let’s run this and what we actually need to do is something almost exactly like this and I’m going to put it right below it um instead of printing this off because again this is all in a list we’re using find all so we’re we’re printing off another list which isn’t actually super helpful um for each of or all these data that we’re pulling in what we can do is we can call this uh the rowcor data and then we’ll put the row data in here so we’ll say four and we’ll say in row data so we’ll just say for the data in row data and we’ll take the data we’ll exchange that and now instead of uh World Table titles we can change this into uh individual row data right and now let’s print off the individual row data so it’s the exact same process that we were doing up here and that’s how we cleaned it up and got this and we may not need to strip but let’s just run this and see what we get there we go um and strip I’m sure was helpful let’s actually get rid of this yeah strip was helpful it’s the exact same thing that happened on the last one so let’s keep that actually let’s run this and now let’s just kind of glance glance at this information let’s look through it this looks exactly like the information that’s in the table let’s just confirm with this first one uh 25 uh two what am I saying 572 754 2.4 2300 57275 2.4 2200 so this looks exactly correct now we have to figure out a way to get this into our table because again these are all individual lists it’s not like we’re just you know putting all of this in at one time we can’t just take the entire table and plop it into um into the data frame we need a way to kind of put this in one at a time now if you’re just here for web scraping and you haven’t taken like my panda series that’s totally fine that’s not what we’re here for anyways um but what we can do we’ll have our individual row data and we’re going to put it in kind of one at a time now the reason we have to do that is because when we had it like this and let’s go back when we had it like this it’s printing out all of it but what it’s really doing and let’s get rid of it um what it’s really doing is it’s kind of doing it like this it’s printing it off one at a time and it’s only going to save that current row of data this last one it’s only going to save that as it’s looping through so what we actually want to do is every time it Loops through we append this information onto the data frame so as it goes through and eventually it’s going to end up with this one but as it goes through let’s run this as it goes through it puts this one in and then the next time it Loops through it puts this one in and the next time it Loops through Etc all the way down um so let’s see how we can do this so we have our data frame right here let’s get rid of this let’s bring our data frame in now again like I just mentioned if you don’t know pandas and you haven’t learned that uh you know go take my uh series on that it’s really good and we do something very similar to this in that Series so I’m not going to kind of walk through the entire logic um but there is something called l which stands for location when you’re looking at the index on a data frame and we’re going to use that to our advantage so we’re going to say the length of the data frame so we’re looking at how many rows are in this data frame and then we’re going to say that’s our length then we’re going to take that length and use it when we’re actually putting in this new information pretty um pretty cool so we’re going to say df.loc then a bracket and we’re putting in that length so we’re checking the length of our data frame each time it’s looping through and then we’re going to put the information in the next position that’s exactly what we’re doing let’s go ahead and put in the individual row data um so let’s just recap We’re looping through this TR this is our column data so these TR that’s our row of data then we’re as as We’re looping through it we’re doing find all and looking for TD tags that’s our individual data so that’s our row data then we’re taking that that data each piece of data and we’re getting out the text and we’re stripping it to kind of clean it and now it’s in a list for each individual row then we’re looking at our current data frame which has nothing in it right now we’re looking at the length of it and we’re appending each row of this information into the next position so let’s go ahead and run this it’s working it’s thinking and it looks like we got an issue and not set a row with mismatched columns now we’re encountering an issue not one that I got earlier but we’re going to cancel this out we’re going to figure this out together so let’s print off our individual row data let’s look at this this one is empty uh this is I’m almost certain is probably the issue um I didn’t encounter this issue when I wrote these uh when I wrote this lesson um but I’m almost certain that this is the issue right here so let’s do the column data but let’s start at position um let’s try one and not parentheses I need brackets because this is a list right so it should work and there we go so now that first one’s gone so now we just have the information I didn’t even think about that um just a second ago but I’m glad we’re running into it in case you ran into that uh issue let’s go ahead and try this again and it looked like it worked so let’s pull our data frame down I could have just wrote DF let’s pull our data frame down and now this is looking fantastic fantastic now um these three dots just mean there’s information in there just doesn’t want to display it but it looks like we have our rank we have our name have the industry revenue revenue growth employees and headquarters for every single one so this is perfect now this is exactly what I was hoping to get now you can go in and use pandas and manipulate this and change it and you know dive into all the information in there but we can also export this into a CSV if that’s what you’re wanting so we could easily do that by saying we’ll do DF do2 CSV and then within here we’re just going to do R and specify our file path so let’s come down here to our file path then we’ll go to our folder for our output so we’re just going to take this path and let me do it like that so I have this path in my one drive documents python web scraping folder for output so you know I already made this um and I’m just going to put this right down here now I do have to specify what we’re going to call this um we’ll just call this companies and then we have to say CSV that is very important now if we run this I already know just because uh we have this Rank and this index here we’re going to keep this index in the output not great uh but let’s run it let’s look at our output there’s our companies and when we pull this up as you can see this is not what we want because we have this extra thing right here now if we’re automating this this would get super annoying so what we’re going to do is go back and just say index equals false let’s go out of here and now we’re just going to come right down here we’re going to say comma index equals false and so it’s going to take this index and it’s not going to import or actually export it into the CSV now let’s go ahead and run this let’s pull up our folder one more time and let’s refresh just to make sure should be good and now this looks a lot better so we’re able to take all of that information and put it into a CSV and it’s all there so this is the whole project so if we scroll all the way back up let’s just kind of glance at what we did here scroll down we brought in our libraries and packages we specified our URL we brought in our soup um and then we tried to find our table now that took a little bit of uh testing out but we knew that the table was the second one so in position one so we took that table we were also able to specify it using find but then we use the class and of course we just wanted to work with that table that’s all the data we wanted so we specified this is our table and we worked with just our table going forward of course uh we encountered some small issues user errors on my end but we were able to get our world titles and we put those into our data frame right here using pandas then next we went back and we got all the row data and the individual data from those rows and we put it into our Panda’s data frame then we came below and we exported this into an actual CSV file so that is how we can use web scraping to get data from something like a table and put it into a panda’s data frame I hope that this lesson was helpful I know we encountered some issues that’s on my end and I apologize but if you run into those same issues hopefully that helped uh but I hope this was helpful and if you like this be sure to like And subscribe below I appreciate you I love you and I will see you in the next lesson [Music]

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Python Programming Fundamentals

    Python Programming Fundamentals

    This comprehensive resource introduces the Python programming language, covering its fundamental concepts and practical applications. It emphasizes Python’s versatility, highlighting its use in AI, machine learning, web development, and automation. The material guides learners from beginner to advanced levels, explaining installation, syntax, and various programming constructs. It underscores best practices for writing clean and maintainable code, while also exploring complex data types, functions, and loops. The training also covers how to effectively use a code editor to streamline the development process. The course then illustrates complex topics such as working with operators, modules, and data structures.

    Python Fundamentals: A Comprehensive Study Guide

    Quiz (Short Answer)

    1. What is the Python interpreter, and what is its role in executing Python code? The Python interpreter is a program that reads and executes Python code, line by line. It translates the human-readable code into instructions that the computer can understand and perform.
    2. Briefly explain the difference between a code editor and an IDE (Integrated Development Environment). A code editor is a basic text editor with features for writing and editing code, such as syntax highlighting. An IDE is a more comprehensive tool that includes a code editor along with debugging, testing, and auto-completion features.
    3. Why is “linting” important in software development, and how does it benefit the coding process? Linting involves analyzing code for potential errors and stylistic inconsistencies before execution. It helps catch syntax errors and ensures code adheres to style guides, making it cleaner and more maintainable.
    4. What is Pep 8, and why is it important for Python developers to adhere to it? Pep 8 is the style guide for Python code, outlining rules for formatting and styling to ensure consistency across different codebases. Adhering to it promotes readability and collaboration.
    5. Explain the concept of a variable in programming and provide examples of different data types that can be stored in variables. A variable is a named storage location in a computer’s memory used to store data. Data types that can be stored in variables include integers, floats, booleans, and strings.
    6. What is the purpose of the len() function in Python, and what type of argument does it typically take? The len() function returns the length of a sequence, such as a string or a list. It takes the sequence as its argument and returns the number of items in the sequence.
    7. Explain the use of escape characters in Python strings and provide a few common examples. Escape characters are special characters in strings used to represent characters that are difficult or impossible to type directly. Examples include \n (newline), \t (tab), \\ (backslash), \” (double quote), and \’ (single quote).
    8. Describe the purpose and syntax of formatted strings (f-strings) in Python and explain their benefits over traditional string concatenation. Formatted strings (f-strings) allow embedding expressions inside string literals, making string formatting more readable and concise. Using an f-string, you can put variables and expressions inside curly braces {} within the string.
    9. What is the difference between functions that “perform a task” versus those that “calculate and return a value”? Give an example of each. Functions that perform a task carry out actions, often with side effects, but don’t necessarily return a value (e.g., print(), which displays output on the console). Functions that calculate and return a value perform computations and return the result, which can then be used elsewhere in the program (e.g., round(), which returns a rounded number).
    10. Explain the purpose and usage of a for loop and a while loop, highlighting the key differences between them. A for loop is used to iterate over a sequence (e.g., list, string, range), executing a block of code for each element in the sequence. A while loop is used to repeatedly execute a block of code as long as a specified condition is true, making it useful when the number of iterations is not known in advance.

    Essay Questions

    1. Discuss the benefits of using Python for various applications, such as data analysis, AI and machine learning, web development, and automation. Explain how Python’s features contribute to its popularity in these fields.
    2. Explain the significance of code readability and maintainability in software development. Discuss how tools like linters and formatters, along with adherence to style guides like Pep 8, contribute to these aspects of code quality.
    3. Describe the importance of variables and data types in programming. Provide examples of how different data types are used in Python and explain how type conversion functions help ensure data compatibility.
    4. Explain the purpose and usage of control flow statements (if statements, loops) in programming. Describe how these statements enable programs to make decisions and perform repetitive tasks.
    5. Discuss the benefits of using functions in programming. Explain how functions help organize code, promote reusability, and improve the overall structure and maintainability of programs.

    Glossary of Key Terms

    • AI (Artificial Intelligence): The simulation of human intelligence processes by computer systems.
    • Argument: A value passed to a function when it is called.
    • Auto-completion: A feature in IDEs that suggests code completions as you type.
    • Boolean: A data type with two possible values: True or False.
    • Bytecode: Intermediate code produced by a compiler that is then executed by a virtual machine.
    • Cpython: The default and most widely used implementation of the Python programming language, written in C.
    • Data Analysis: The process of inspecting, cleaning, transforming, and modeling data to discover useful information, draw conclusions, and support decision-making.
    • Debugging: The process of finding and fixing errors in code.
    • Expression: A piece of code that produces a value.
    • Float: A data type representing a floating-point number (a number with a decimal point).
    • For Loop: A control flow statement that repeats a block of code for each item in a sequence.
    • Function: A reusable block of code that performs a specific task.
    • IDE (Integrated Development Environment): A software application that provides comprehensive facilities to computer programmers for software development.
    • If Statement: A control flow statement that executes a block of code if a specified condition is true.
    • Integer: A data type representing whole numbers.
    • Iterable: An object that can be looped over, such as a list, string, or range.
    • Library: A collection of pre-written code that provides reusable functions and classes for performing specific tasks.
    • Linting: The process of analyzing code for potential errors and stylistic issues.
    • Machine Learning: A type of artificial intelligence (AI) that provides computer systems with the ability to automatically learn and improve from experience without being explicitly programmed.
    • Module: A separate file containing Python code that can be imported and used in other programs.
    • Parameter: A variable defined in a function definition that receives a value when the function is called.
    • Pep 8: The style guide for Python code, outlining rules for formatting and styling.
    • Syntax: The set of rules that define the structure of a programming language.
    • Syntax Error: An error in code caused by violating the syntax rules of the language.
    • Tuple: An immutable sequence of objects, similar to a list but cannot be modified after creation.
    • Variable: A named storage location in a computer’s memory used to store data.
    • While Loop: A control flow statement that repeats a block of code as long as a specified condition is true.

    Complete Python Mastery: Course Overview

    Okay, here’s a briefing document summarizing the key concepts and ideas from the provided text, focusing on the structure of a Python course and fundamental programming concepts:

    Briefing Document: Complete Python Mastery Course

    I. Overview

    The source material is an excerpt from the “Complete Python Mastery” course introduction, outlining the curriculum and key features of the course. The course promises a comprehensive journey from basic to advanced Python concepts, enabling confident application in areas like AI, machine learning, web development, and automation. It emphasizes a practical, easy-to-follow structure suitable for beginners with no prior programming experience.

    II. Key Themes & Ideas

    • Comprehensive Python Learning: The course covers a wide range of topics, aiming to equip students with the skills to use Python in diverse fields:
    • “In this course you’re going to learn everything about python from Basics to more advanced concepts so by the end of the course you’ll be able to confidently use Python for AI machine learning web development and automation”
    • Beginner-Friendly Approach: The course is explicitly designed for individuals with no prior programming knowledge, with step-by-step explanations.
    • “You don’t need any prior knowledge of python to get started I will explain everything step by step in simple terms so you can build a solid foundation”
    • Python’s Popularity and Versatility: The course highlights Python’s widespread adoption and its suitability for various applications.
    • “Python is the world’s fastest growing and most popular programming language not just amongst software developers but also amongst mathematicians data analysts scientists accountants Network engineers and even kids”
    • Advantages of Python: The reasons for Python’s popularity are outlined:
    • Conciseness and Readability: Python allows solving complex problems with fewer lines of code compared to languages like C or JavaScript.
    • Example code snippets are provided to illustrate this.
    • “With python you can solve complex problems in less time with fewer lines of code than many other languages”
    • Multi-purpose Language: Python can be used in different industries such as data analysis, AI and machine learning, writing automation scripts, building web, mobile, and desktop applications as well as software testing or even hacking.
    • High-level language Python takes care of memory management so you don’t have to worry about it like you do in C++
    • Cross-platform compatibility: Python runs on Windows, Mac, and Linux.
    • Large community and ecosystem: Extensive support and resources are available.
    • Career Opportunities: The course emphasizes the potential for high-paying careers, particularly in AI and machine learning.
    • “if you want a high-paying long lasting career in any of these areas especially Ai and machine learning python is the language to put those opportunities at your fingertips”
    • Cites a statistic regarding the average salary of a Python developer.
    • Python 3 Focus: The course teaches Python 3, the current and future version of the language.
    • “There are two versions of python out there python 2 which is the Legacy version of python and is going to be supported until year 2020 and Python 3 which is python for the future in this course you’re going to Learn Python 3”
    • Course Structure: The course guides learners through installation, basic syntax, and using code editors (specifically VS Code) and IDEs.
    • VS Code and Extensions: The course uses VS Code as the primary code editor and demonstrates how to enhance it with the Python extension for features like linting, debugging, auto-completion, and code formatting.
    • “In this lecture I’m going to show you how to convert vs code to a powerful IDE by using an extension called python with this extension or plug-in we get a number of features such as linting which basically means analyzing our code for potential errors we also get debugging which involves finding and fixing errors we’ll look at this later in the course we also get autoc completion which basically helps us write code faster so we don’t have to type every character”
    • Coding style guidelines (PEP 8): The course emphasizes the use of the style guide to maintain cleaner code and automatically formats the code by using AutoPep8.
    • “in Python Community we have a bunch of documents called python enhancement proposals or peps here on Google if you search for python peps you can see the list of all these PS under python.org sdev peps let’s have a quick look here so here are the peps you can see each pep has a number and a title the one that is very popular amongst python developers is Pep 8 which is a style guide for python code a style guide is basically a document that defines a bunch of rules for formatting and styling our code if you follow these conventions the code that you right will end up being consistent with other people’s code”
    • CPython execution: The course describes that CPython compiles Python into Python Byte code then passes the Byte code to the Python virtual machine to be converted into machine code and executed.

    III. Fundamental Concepts Covered (Excerpt)

    • Variables: Used to store data in computer memory. Examples given include integers, floats, booleans and strings.
    • “we use variables to store data in computer’s memory here are a few examples I’m going to Define a variable called students underline count and setting it to a th000”
    • Data Types: Introduction to primitive data types (integers, floats, booleans, and strings) and type conversion.
    • “primitive types can be numbers booleans and strings”
    • “In Python we have a few built-in functions for type conversion we have int for converting a number to an integer we have float we have bull and stir or string”
    • String Manipulation: Demonstrates string slicing, escaping characters, formatted strings, and built-in string methods (e.g., len(), upper(), lower(), strip(), find(), replace(), in).
    • “using a similar syntax you can slice strings”
    • “I’m going to show you a few useful functions available to work with strings”
    • Arithmetic Operations: Covers basic arithmetic operators (+, -, *, /, %, **) and augmented assignment operators (+=, -=, etc.).
    • “for all these types of numbers we have the standard arithmetic operations that we have in math let me show you so we have addition subtraction multiplication division but we actually have two different types of divisions”
    • User Input: Using the input() function to get input from the user and convert it to the correct type.
    • “we use the input function to get input from the user as an argument we pass a string this will be a label that will be displayed in the terminal you’ll see that in a second so let’s add X colon now this function returns a string”
    • Comparison Operators: Used to compare values to form a boolean expression.
    • “we use comparison operators to compare values here are a few examples so 10 is greater than three we get true so what we have here is a Boolean expression because when this expression is evaluated we’ll get a Boolean value that is true or false”
    • Conditional Statements: Demonstrate if, elif, and else statements for decision-making, along with the use of logical operators (and, or, not).
    • “in almost every program there are times you need to make decisions and that’s when you use use an if statement here’s an example let’s say we have a variable called temperature we set it to 35 now if temperature is greater than 30 perhaps we want to display a message to the user”
    • Loops: Explain for and while loops for repetition, including the range() function, break statement, and for…else construct.
    • “there are times that we may want to repeat a task a number of times for example let’s say we send a message to a user if that message cannot be delivered perhaps we want to retry three times now for Simplicity let’s imagine this print statement is equivalent to sending a message in a real world program to send a message to a user we have to write five to 10 lines of code now if you want to retry three times we don’t want to repeat all that code that is ugly that’s when we use a loop we use Loops to create repetition”
    • Functions: Defining custom functions, passing parameters (arguments), returning values, optional parameters, and variable number of arguments using *args.
    • “so far you have learned how to use some of the built-in functions in Python such as print round and so on in this section you’re going to learn how to write your own functions now you might ask but why do we even need to write our own functions well when you build a real program that program is going to consist hundreds or thousands of lines of code you shouldn’t write all that code in one file like we have done so far you should break that code into a smaller more maintainable and potentially more reusable chunks you refer to these chunks as functions”

    IV. Target Audience

    The target audience is individuals with no prior Python or programming experience seeking a comprehensive and practical understanding of Python.

    V. Overall Impression

    The “Complete Python Mastery” course appears to be a well-structured and beginner-friendly resource for learning Python, emphasizing practical application and best practices.

    Python Programming: Frequently Asked Questions

    Frequently Asked Questions About Python Programming

    1. Why should I learn Python, especially if I’m new to programming?

    Python is an excellent choice for beginners due to its clean, simple syntax, making it highly readable and easier to learn than many other languages. It’s versatile, suitable for various applications like data analysis, AI, machine learning, web development, and automation. Its large and active community provides ample support and resources, and Python’s high-level nature simplifies tasks like memory management, allowing you to focus on problem-solving. Big companies like Google and Spotify use it, meaning high-paying job opportunities are abundant.

    2. What are the key advantages of Python over other programming languages?

    Python stands out for several reasons. Its code is concise, enabling you to solve complex problems with fewer lines compared to languages like C or Java. It’s a multi-purpose language suitable for data analysis, AI, machine learning, scripting, web development, and more. Python is also cross-platform, running seamlessly on Windows, Mac, and Linux. It has a massive community that provides great support, with vast libraries and tools available for almost any task. Its high-level nature abstracts away complexities like memory management.

    3. How do I get started with Python on my computer?

    First, download the latest version of Python from python.org. When installing on Windows, be sure to check the box that says “Add Python to PATH.” This step is critical to avoid headaches later. To verify installation, open your terminal (or command prompt on Windows) and type python –version (or python3 –version on Mac) to confirm that Python is correctly installed.

    4. What tools do I need to write and run Python code effectively?

    You have two primary options: code editors or Integrated Development Environments (IDEs). Code editors like VS Code, Atom, and Sublime are lightweight and excellent for general coding. IDEs like PyCharm offer advanced features such as auto-completion, debugging, and testing tools. VS Code can be transformed into a powerful IDE by installing the Python extension from Microsoft.

    5. How can I use VS Code effectively for Python development?

    Install the official Python extension from Microsoft in VS Code. This extension provides features like linting (code analysis for errors), debugging, auto-completion, code formatting, unit testing support, and code snippets. Enable “format on save” in VS Code’s settings for automatic code formatting according to PEP 8 style guidelines. Also, learn to use the command palette (Shift+Command+P or Shift+Ctrl+P) for accessing various commands related to the Python extension, including linting options.

    6. What are variables in Python, and what types of data can they store?

    Variables are used to store data in a computer’s memory, acting as labels for memory locations. Python has built-in primitive data types:

    • Integers: Whole numbers (e.g., 1000)
    • Floats: Numbers with decimal points (e.g., 4.99)
    • Booleans: True or False values used for decision-making
    • Strings: Text surrounded by quotes (e.g., “Python Programming”)

    7. What are functions in Python and how are they created?

    Functions are reusable blocks of code designed to perform specific tasks. They are created using the def keyword, followed by the function name, parentheses for parameters (inputs), and a colon. The code within the function is indented. Functions can either perform a task (e.g., printing something to the console) or calculate and return a value.

    Example:

    def greet(first_name, last_name):

    “””Greets a person by their full name.”””

    return f”Hi {first_name} {last_name}”

    message = greet(“Mosh”, “Hamedani”)

    print(message)

    8. How do loops work in Python, and what are the differences between for and while loops?

    Loops allow you to repeat a block of code multiple times.

    • for loops: Iterate over iterable objects like ranges, strings, or lists.
    • for number in range(5):
    • print(number) # Prints numbers 0 to 4
    • while loops: Repeat a block of code as long as a specified condition remains true.

    number = 100

    while number > 0:

    print(number)

    number //= 2 # Integer division by 2

    `break` statements can be used to exit a loop prematurely.

    Python Programming: A Concise Introduction

    Python is a popular programming language used for various purposes, including AI, machine learning, web development, and automation. Here are some of its basic concepts:

    • Clean and Simple Syntax: Python allows complex problems to be solved with fewer lines of code compared to other languages like C or JavaScript.
    • Multi-purpose Language: Python can be used for data analysis, AI, machine learning, automation, web, mobile, and desktop applications, software testing, and even hacking.
    • High-Level Language: Python handles memory management automatically.
    • Cross-Platform: Python applications can run on Windows, Mac, and Linux.
    • Large Community and Ecosystem: Python has a broad support network and many libraries, frameworks, and tools.

    Setting up Python

    1. Installation: Download the latest version of Python from python.org. On Windows, ensure you check the “Add Python to PATH” box during installation.
    2. Verification: Open a terminal and type python –version (or python3 –version on Mac) to verify the installation.

    Basic Concepts

    • Interpreter: Python code is executed by an interpreter, which can run code directly from an interactive shell or from a file.
    • Expressions: Expressions are pieces of code that produce a value (e.g., 2 + 2).
    • Syntax: Python has a specific grammar, and syntax errors occur when the code doesn’t follow this grammar.

    Code Editors and IDEs

    • Code Editors: VS Code, Atom, and Sublime are popular code editors.
    • IDEs: PyCharm is a popular Integrated Development Environment that offers features like auto-completion, debugging, and testing.
    • VS Code with Python Extension: VS Code can be converted into an IDE by installing the Python extension from Microsoft. This extension provides features like linting, debugging, auto-completion, code formatting, unit testing, and code snippets.

    Writing and Running Python Code

    1. Create a File: Create a new file with a .py extension (e.g., app.py).
    2. Write Code: Use the print() function to display text on the screen.
    3. Run Code: Open the integrated terminal in VS Code (using Ctrl +) and type python app.py (or python3 app.py on Mac/Linux).
    4. VS Code Extension: The Python extension adds a play button to run code directly.

    Code Formatting

    • Linting: Linting analyzes code for potential errors. The Python extension in VS Code uses a linter called Pylint by default.
    • PEP 8: This is a style guide for Python code that promotes consistency.
    • Auto-formatting: Tools like AutoPep8 can automatically format code according to PEP 8. VS Code can be configured to format files on save by enabling the editor.formatOnSave setting.

    Python Implementations

    • CPython: The default implementation of Python, written in C.
    • Jython: Implemented in Java, allowing the use of Java code in Python programs.
    • IronPython: Written in C#, useful for integrating C# code with Python.
    • Execution: CPython first compiles Python code into Python byte code, which is then executed by the Python Virtual Machine. Jython compiles Python code into Java byte code, which is executed by the Java Virtual Machine (JVM).

    Variables and Data Types

    • Variables: Used to store data in the computer’s memory. A variable is like a label for a memory location.
    • Naming Conventions: Use descriptive and meaningful names, lowercase letters, and underscores to separate words.
    • Primitive Types:
    • Integers: Whole numbers (e.g., 1000).
    • Floats: Numbers with a decimal point (e.g., 4.99).
    • Booleans: True or False values (case-sensitive).
    • Strings: Text surrounded by quotes (e.g., “Python Programming”).
    • Strings:
    • Can be defined using single, double, or triple quotes. Triple quotes are used for multi-line strings.
    • len() function: Returns the length of a string.
    • Square brackets: Used to access specific characters in a string. Strings are zero-indexed.
    • Slicing: Extract portions of a string using [start:end] notation.
    • Escape Sequences: Use backslashes to include special characters in strings (e.g., \, \n, \”).
    • Formatted Strings: Prefix a string with f and use curly braces to embed expressions (e.g., f”Result: {2 + 2}”).
    • String Methods: Functions specific to string objects. Accessed using dot notation (e.g., course.upper()). Common methods include upper(), lower(), title(), strip(), find(), and replace().
    • in Operator: Checks for the existence of a character or sequence of characters in a string (returns a Boolean value).
    • Numbers:
    • Types: Integers, floats, and complex numbers. Complex numbers are written in the form a + bj.
    • Arithmetic Operators: +, -, *, / (float division), // (integer division), % (modulus), ** (exponentiation).
    • Augmented Assignment Operators: Shorthand for updating a variable (e.g., x += 3 is equivalent to x = x + 3).
    • Built-in Functions: round() (rounds a number), abs() (returns the absolute value).
    • Math Module: Provides additional mathematical functions. Import the module using import math. Common functions include math.ceil().
    • Input:
    • input() function: Gets input from the user. The input is always returned as a string.
    • Type Conversion: Use int(), float(), bool(), and str() to convert between data types.
    • Truthy and Falsy Values: Values that are not exactly True or False but are interpreted as such. Falsy values include empty strings, zero, and the object None.

    Operators

    • Comparison Operators: Used to compare values. Examples include >, >=, <, <=, == (equality), and != (not equal).
    • Logical Operators: and, or, and not. Used to create complex conditions. These operators are short circuit.
    • Chaining Comparison Operators: A cleaner way to write complex comparisons (e.g., 18 <= age < 65).

    Conditional Statements

    • If Statements: Used to make decisions based on conditions. Terminate the if statement with a colon (:). Use indentation to define the block of code to be executed.
    • Elif Statements: Short for “else if,” used to check multiple conditions.
    • Else Statements: Executed if none of the previous conditions are true.
    • Ternary Operator: A shorthand for simple if-else assignments (e.g., message = “eligible” if age >= 18 else “not eligible”).

    Loops

    • For Loops: Used to iterate over a sequence (e.g., a range of numbers, a string, or a list).
    • Range Function: Generates a sequence of numbers. range(start, end, step).
    • Break Statement: Used to exit a loop early.
    • For-Else Statement: The else block is executed if the loop completes without hitting a break statement.
    • Nested Loops: One loop inside another.
    • Iterable Objects: Objects that can be iterated over (e.g., range objects, strings, lists).
    • While Loops: Used to repeat a block of code as long as a condition is true.
    • Infinite Loops: Loops that run forever. Ensure there is a way to exit the loop (e.g., using a break statement).

    Functions

    • Definition: Use the def keyword to define a function. Follow naming conventions similar to variables.
    • Parameters: Inputs to a function, defined in the parentheses.
    • Arguments: The actual values passed to a function when it is called.
    • Calling a Function: Use the function name followed by parentheses.
    • Return Statement: Used to return a value from a function. If no return statement is used, the function returns None by default.
    • Keyword Arguments: Improve code readability by explicitly specifying the parameter name when calling a function (e.g., increment(2, by=1)).
    • Optional Parameters: Give a parameter a default value to make it optional (e.g., def increment(number, by=1)). Optional parameters must come after required parameters.
    • Variable Number of Arguments: Use an asterisk (*) to collect a variable number of positional arguments into a tuple.

    Python Fundamentals for AI and Machine Learning

    The sources provided focus on the fundamentals of Python programming and do not contain specific information about machine learning. However, they do establish that Python is a language used for AI and machine learning.

    The course aims to equip learners to use Python confidently for AI and machine learning, along with web development and automation. Furthermore, a long-lasting career with high pay is available in AI and machine learning for those who learn Python.

    Beyond what is in the sources, it is important to note that machine learning involves algorithms that enable computers to learn from data without explicit programming. Since the sources do not elaborate, it would be best to independently verify that information.

    Python for Web Development

    The provided source material does not offer specifics on web development. However, it does identify web development as one of the applications for Python. The course outlined in the source aims to equip learners to confidently use Python for web development, along with AI, machine learning, and automation.

    Outside of the provided sources, it is important to note that web development typically involves creating websites and web applications using a combination of front-end and back-end technologies, but since the source does not elaborate, it would be best to independently verify that information.

    Python for Code Automation

    The sources identify code automation as one of the applications of Python. The course is designed to equip learners to confidently use Python for automation, along with AI, machine learning, and web development.

    Outside of the provided sources, it is important to note that code automation involves using programming to automate repetitive tasks. However, since the sources do not elaborate, it would be best to independently verify that information.

    Understanding Python Function Arguments

    Here’s a discussion of function arguments, based on the sources:

    • Parameters vs. Arguments: A parameter is an input defined within a function’s definition, while an argument is the actual value provided for that parameter when the function is called.
    • Required Arguments: By default, all parameters defined in a function are required. If a required argument is missing when the function is called, Python will raise a TypeError.
    • Keyword Arguments: When calling a function, you can specify arguments using the parameter name, which can improve code readability. For example, increment(2, by=1) uses a keyword argument to specify the value for the by parameter.
    • Optional Parameters: To make a parameter optional, provide a default value in the function definition. For example, def increment(number, by=1) makes the by parameter optional with a default value of 1. If the caller omits the argument, the default value is used; otherwise, the provided value is used. All optional parameters must come after the required parameters in the function definition.
    • Variable Number of Arguments: You can define a function to accept a variable number of arguments using an asterisk (*) before the parameter name. This collects all positional arguments into a tuple, which can then be iterated over within the function. For example:
    • def multiply(*numbers):
    • total = 1
    • for number in numbers:
    • total *= number
    • return total
    • result = multiply(2, 3, 4, 5) # result will be 120
    Python Full Course for Beginners [2025]

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Python Tutorial with Generative AI

    Python Tutorial with Generative AI

    This Python tutorial PDF covers fundamental programming concepts, including data structures (lists, tuples, dictionaries), file handling (reading, writing, appending), exception handling (try-except-else-finally blocks), object-oriented programming (classes and inheritance), and basic algorithms (sorting, searching). The tutorial also introduces NumPy arrays and data visualization using Matplotlib and Seaborn. Finally, it explores the creation of simple GUI applications with Tkinter and integrates open AI’s GPT API with Flask for chatbot functionality and Langchain for personalized story generation.

    Python Study Guide

    Quiz

    Instructions: Answer each question in 2-3 sentences.

    1. What is a kernel in the context of Jupyter Notebook?
    2. Explain the difference between the single equal to (=) and the double equal to (==) operators in Python.
    3. What are the basic Python tokens?
    4. What are literals in Python, and give an example?
    5. How do you create a multi-line string in Python?
    6. Explain the difference between the append() and pop() list methods.
    7. What is the main difference between a list and a tuple in Python?
    8. How are key-value pairs stored in a Python dictionary?
    9. Describe the use of if, elif, and else statements in Python.
    10. Explain how a for loop works in Python with an example using a list.

    Quiz – Answer Key

    1. A kernel is the executor of Python code in Jupyter Notebook. When you write code and click “run,” the kernel interprets and runs the code, displaying the output.
    2. The single equal to (=) operator is used for assignment, giving a value to a variable, while the double equal to (==) operator is used for comparison, checking if two values are equal.
    3. The basic Python tokens are keywords (reserved words), identifiers (names for variables, functions, or objects), literals (constants), and operators (symbols for operations).
    4. Literals are constant values in Python that do not change, such as numbers, strings, or boolean values. For example, 10, “hello”, and True are literals.
    5. You create a multi-line string in Python by enclosing the string within triple quotes, which can be either single quotes (”’) or double quotes (“””).
    6. The append() method adds an element to the end of a list, while the pop() method removes and returns the last element of a list, modifying the original list.
    7. Both lists and tuples are ordered collections of elements, but lists are mutable, meaning their contents can be changed after creation, while tuples are immutable and their contents cannot be modified.
    8. In a Python dictionary, key-value pairs are stored using curly braces {} with a colon separating each key from its value, like {“key”: “value”}.
    9. The if statement starts a conditional block based on a condition; elif introduces more conditional blocks to check if the previous if or elif conditions were false; and else executes if none of the preceding if or elif conditions were true.
    10. A for loop iterates over each item in a sequence, such as a list, executing a block of code for each item. For example, for fruit in fruits: print(fruit) would print each element in the fruits list.

    Essay Questions

    1. Compare and contrast lists, tuples, and dictionaries in Python, highlighting their mutability, ordering, and use cases. Provide code examples to illustrate each data structure.
    2. Discuss the different types of operators in Python, providing examples of how each is used. Focus on arithmetic, relational, and logical operators, and how they are utilized in decision-making statements.
    3. Explain the significance of file handling in Python, describing the different modes for opening files (read, write, append). Describe how to read, write, and modify text files, and also discuss how to handle potential errors using try-except blocks.
    4. Describe the concept of looping in Python using both for and while loops. Provide examples that demonstrate how these loops can be used to process lists, and illustrate the utility of nested loops, and include an example showing how to apply a loop to dictionaries.
    5. Discuss the core concepts of the following Python libraries: NumPy, Pandas, Matplotlib, and Seaborn. Explain their primary purposes, how they are used to manipulate, analyze, and visualize data, and offer practical examples of the kind of work they can be used to accomplish.

    Glossary

    Alias: A shorter name given to a library or module when importing it, e.g., import numpy as np uses “np” as an alias for the NumPy library.

    Append (list method): A method used to add an element to the end of a list.

    Arithmetic Operators: Symbols used to perform mathematical calculations such as addition (+), subtraction (-), multiplication (*), and division (/).

    Axis (NumPy): A dimension in a multi-dimensional array used to specify operations like summing along rows or columns, where axis 0 is for columns, and axis 1 is for rows.

    Boolean: A data type that has one of two possible values, true or false.

    Box Plot (Seaborn): A type of plot used to visualize the distribution of a dataset through quartiles.

    CBOR (Seaborn): A Python library used to create statistical graphics. It extends Matplotlib and offers a high-level interface for drawing attractive informative plots.

    Column Stack (NumPy): A function used to combine multiple arrays together column-wise.

    Data Frame (Pandas): A two-dimensional, labeled data structure in Pandas with rows and columns, similar to a spreadsheet or a SQL table.

    Dictionary: A Python data structure that stores key-value pairs enclosed in curly braces {}.

    Distribution Plot (Seaborn): A plot that shows the distribution of a single variable using a histogram and a density curve (KDE).

    Else (conditional statement): A block of code that executes only if the previous if or elif conditions are false.

    Elif (conditional statement): An intermediate conditional block that checks if the previous if condition is false before checking if the elif statement is true.

    Exception Handling: The process of anticipating errors and preventing them from crashing a program using try-except blocks.

    File Handling: The process of interacting with files, including opening, reading from, writing to, and closing them.

    Flask: A lightweight Python web framework used for building web applications.

    For Loop: A control flow statement used to iterate over a sequence (like a list, tuple, or string), executing a code block for each item.

    Grid (Matplotlib): A method used to add grid lines to a graph.

    Horizontal Stack (NumPy): A function used to stack arrays side by side horizontally.

    Identifier: A name used to identify a variable, function, class, or other objects in Python.

    If (conditional statement): A control flow statement used to execute a block of code only if a specified condition is true.

    Immutable: An object that cannot be changed after it is created, like a tuple.

    Join Plot (Seaborn): A type of plot that displays the relationship between two variables along with their marginal distributions.

    Jupyter Notebook: An interactive web-based environment for writing and running code, often used for data analysis.

    Kernel (Jupyter): The process that runs your code in a Jupyter Notebook.

    Keyword: A reserved word in Python with a predefined meaning that cannot be used as an identifier.

    Line Plot (Matplotlib/Seaborn): A type of plot that displays information as a series of data points connected by straight line segments.

    List: A mutable, ordered collection of elements in Python, enclosed in square brackets [].

    Literals: Constant values in Python, such as numbers, strings, boolean values.

    Logical Operators: Symbols used for logical comparisons, such as and, or, and not.

    Looping Statements: Control flow statements that execute a block of code repeatedly until a condition is met, including for and while loops.

    Matplotlib: A widely used Python library for creating static, interactive, and animated visualizations.

    Mean (NumPy/Pandas): A function that calculates the average of a set of values.

    Median (NumPy/Pandas): A function that calculates the middle value in a sorted dataset.

    Mode (file handling): Specifies how a file should be opened, such as read (‘r’), write (‘w’), or append (‘a’).

    Multi-dimensional Array (NumPy): An array with more than one dimension, also known as a matrix.

    Mutable: An object that can be changed after it is created, like a list or dictionary.

    Numpy: A core library for numeric and scientific computing in Python, providing support for multi-dimensional arrays and mathematical operations.

    Operators: Symbols used for performing operations, such as arithmetic, relational, or logical operations.

    Pandas: A Python library that provides powerful and easy-to-use data structures and data analysis tools, notably DataFrames and Series.

    Pop (list method): A method used to remove the last element from a list.

    PyCharm: An Integrated Development Environment (IDE) used for coding in Python.

    Relational Operators: Symbols used to compare the relationship between two operands, such as less than (<), greater than (>), equal to (==), or not equal to (!=).

    Replace (string method): A method used to find a specified substring within a string and replaces it with another substring.

    Scatter Plot (Matplotlib): A type of plot that displays the relationship between two numerical values by using points on a cartesian plane.

    Seaborn: A Python visualization library built on top of Matplotlib that provides a higher-level interface for statistical graphics.

    Series (Pandas): A one-dimensional labeled array in Pandas.

    Shape (NumPy): The dimensions of a numpy array.

    Split (string method): A method used to divide a string into a list of substrings based on a split criterion.

    Stacking (NumPy): Combining multiple arrays, either vertically (one array on top of another), horizontally (side by side), or column-wise.

    Standard Deviation (NumPy): Measures the amount of variation or dispersion of data in a dataset.

    Streamlit: An open-source Python library that makes it easy to create custom web apps for machine learning and data science.

    String: A sequence of characters enclosed within single, double, or triple quotes.

    Subplot (Matplotlib): A method to create multiple plots within a single figure.

    Tokens (Python): The smallest meaningful component of a Python program, such as keywords, identifiers, literals, and operators.

    Triple Quotes: Used in Python to create multi-line strings, enclosed in either single or double quotes.

    Tuple: An immutable, ordered collection of elements enclosed in parentheses ().

    Type Casting: Explicitly converting data from one type to another like changing a string into a number.

    Vertical Stack (NumPy): A function used to stack arrays one on top of the other.

    While Loop: A control flow statement used to repeatedly execute a block of code as long as a condition is true.

    Python Tutorial Deep Dive

    Okay, here’s a detailed briefing document summarizing the main themes and important ideas from the provided Python tutorial excerpts.

    Briefing Document: Python Tutorial Review

    Document: Excerpts from “749-Python Tutorial with Gen AI for 2024 Python for Beginners Python full course 02.pdf”

    Date: October 25, 2024

    Overview:

    This document summarizes key concepts and functionalities of the Python programming language, as presented in the provided tutorial excerpts. The tutorial covers a range of fundamental topics, from basic syntax and data types to more advanced concepts such as control flow, file handling, and data manipulation with libraries like NumPy, Pandas, Matplotlib and Seaborn. This document will review the major topics covered, including code snippets and quotes to support the summarization.

    Key Themes & Concepts:

    1. Basic Python Setup & First Program
    • Jupyter Notebook: The tutorial uses Jupyter Notebook as the development environment. The document shows how to:
    • Save files as HTML or Latex documents
    • Rename notebooks.
    • Add and delete cells
    • Run cells.
    • The “kernel” as the program executor is introduced as well.
    • print() function: The tutorial begins with a basic “Hello World” style program, printing “This is Sparta” to the console using the print() function.
    • “to print something out on the console we would have to use the print command”
    1. Fundamental Data Types & Operators
    • Variables: Shows how to create and assign values to variables (e.g., num1 = 10, num2 = 20).
    • Arithmetic Operators: The tutorial goes through basic arithmetic operations:
    • Addition (+): “if you want to add two numbers you have to use the plus symbol between those two operant”
    • Subtraction (-)
    • Multiplication (*)
    • Division (/)
    • Relational Operators: The tutorial introduces relational operators for comparing values:
    • Less than (<)
    • Greater than (>)
    • Equal to (==): “this is the double equal to operator…helps us to understand if these two values if the operant on the left hand side and the operant on the right hand side are equal to each other or not”
    • Not equal to (!=)
    • Logical Operators: The tutorial explains logical operators such as:
    • and: Returns True if both operands are true.
    • or: Returns True if at least one of the operands is true.
    • Tokens: The tutorial defines Python tokens as the smallest meaningful components in a program.
    • Includes keywords, identifiers, literals, and operators.
    • Keywords: Reserved words that cannot be used for any other purpose (e.g., if, def, while).
    • “python keywords as it is stated are special reserved words…you can’t use these special reserved words for any other purpose”
    • Identifiers: Names given to variables, functions, or objects. There are specific rules for identifiers, like:
    • Can not have special characters except underscores
    • Are case sensitive
    • Can not start with a digit
    • Literals: Constants or the values stored in variables.
    • “literals are just the constants in python…whatever values you are storing inside a variable that is called as a literal”
    1. Strings in Python
    • String Declaration: Strings are sequences of characters enclosed in single, double, or triple quotes.
    • “strings are basically sequence of characters which are enclosed within single quotes double quotes or triple quotes”
    • String Methods: Common string manipulation methods covered include:
    • len(): Returns the length of a string.
    • lower(): Converts a string to lowercase.
    • upper(): Converts a string to uppercase.
    • replace(): Replaces a substring with another.
    • count(): Counts the number of occurrences of a substring.
    • find(): Returns the starting index of a substring.
    • split(): Splits a string into a list of substrings based on a delimiter.
    1. Data Structures: Lists, Tuples and Dictionaries
    • Lists: Ordered, mutable collections of elements enclosed in square brackets []. Lists can be modified after creation.
    • Access elements by index (starting from 0).
    • Extract slices (subsets of the list)
    • Modify elements, add elements using append(), and remove elements using pop()
    • Tuples: Ordered, immutable collections of elements enclosed in parentheses (). Tuples cannot be modified after creation.
    • Access elements by index.
    • Extract slices (subsets of the tuple)
    • Min and Max functions can be used for numerical tuples.
    • Dictionaries: Unordered collections of key-value pairs enclosed in curly braces {}. Dictionaries are mutable.
    • “dictionary is an unordered collection of key value pairs enclosed within curly braces and a dictionary again is mutable”
    • Access values by key.
    • Extract keys using keys() and values using values().
    • Add or modify key-value pairs.
    • Remove elements using pop().
    • Can merge dictionaries using update()
    1. Control Flow: Decision Making (if/else) & Looping
    • if/else/elif statements: Used for conditional execution of code blocks based on given conditions. Examples with comparisons, tuples, lists, and dictionaries are presented.
    • “decision making statements would help us to make a decision on the basis of a condition”
    • “with the help of this [if/elif/else] we can compare multiple variables together or we can have multiple conditions together”
    • for Loops: Used to iterate over a sequence (like a list). The examples include nested for loops.
    • “for loop… would help me to pick a color…inner for loop…would help me to choose an item”
    • while Loops: Used to repeatedly execute a code block as long as a condition remains true. Examples include printing numbers and multiplication tables, and manipulating list elements.
    • “while again would help us to repeat a particular task and this task is repeated on the basis of a condition”
    1. File Handling
    • File Modes: Explains the different modes for opening files:
    • r: Read mode.
    • w: Write mode (creates a new file or overwrites an existing one).
    • a: Append mode (adds to the end of a file).
    • File Operations: Shows how to:
    • Open a file using the open() function.
    • Read the contents using read(), readline() and readlines() function.
    • Write to a file using the write() function.
    • Append to a file.
    • Close a file using the close() function.
    • Length of File Content Using Len()”the length one is used for calculating that basically how many characters you are happen here”
    1. Exception Handling
    • try, except, else, finally: Explain the use of these blocks for handling errors and executing code in all cases.
    • “whenever you are having no error into your program so your try block actually gets executed and when you are having any error in your program so your accept statement gets executed”
    • “whenever you do not have any exception into your program after the execution of the try block you want one more statement to get printed…in that case we simply use out this else clause”
    • “finally is a keyword that would execute either you are having an exception in your program or you are not having an exception in your program”
    1. Implementation of Stack using List, Deque and Queue module
    • Stack using list: Stacks can be implemented using lists. The tutorial demonstrated the use of append() to add elements and pop() to remove elements, and explained last in first out (LIFO) behavior.
    • Stack using Deque: Double-ended queue data structure allows faster append and pop operations.
    • Stack using Queue module: Shows the use of put() to add elements and get() to remove elements, and explained last in first out (LIFO) behavior.
    1. Data Analysis and Visualization
    • NumPy:NumPy arrays can be created using np.array().
    • Multi-dimensional arrays can be created.
    • The shape attribute can be used to determine the dimensions and to reshape arrays.
    • Vertical, horizontal, and column stacking methods (vstack(), hstack(), column_stack()).
    • Summation can be performed using np.sum(), both with default behavior and with an axis attribute for column-wise or row-wise summation.
    • Scalar addition, multiplication, subtraction, and division on NumPy arrays.
    • Mathematical functions on arrays such as mean, median, and standard deviation (np.mean(), np.median(), np.std()).
    • Pandas * Series can be created using pd.Series().
    • DataFrames can be created by reading CSV files using pd.read_csv().
    • The shape attribute shows the dimension of a DataFrames. *The describe() method provides descriptive statistics of numeric columns.
    • Access rows and columns using .iloc and .loc indexers, and through column names.
    • Remove columns using drop().
    • Mathematical functions on DataFrames such as mean, median, min and max(mean(), median(), min(), max()).
    • MatplotlibLine plots are created using plt.plot() and customized with attributes such as color, line style and line width.
    • Titles, axis labels and grids are added using methods like plt.title(), plt.xlabel(), plt.ylabel() and plt.grid().
    • Multiple plots and subplots are created.
    • Scatter plots are created using plt.scatter() and markers, colors and sizes can be set.
    • Seabornlineplot() can be used to create line plots between columns of a DataFrames.
    • displot() creates distribution plots.
    • jointplot() can be used to visualize the relationship between two variables using scatter and histograms.
    • boxplot() creates box plots to visualize the distribution of numerical data across categories.
    1. Development Environment Setup
    • Command Prompt Used to install python libraries via pip install
    • Library Installation Libraries like NumPy, Flask and Streamlet are installed through the pip command. The commands, and the way the console behaves when a package is new, vs when a package already exists are demonstrated.
    1. GUI Development
    • Tkinter: The Tkinter module, a standard GUI toolkit for Python, is discussed.
    • Window Creation: How to create a basic window, and the use of the window attribute, background color (bg) and border width (bd).
    • ListBox Creation: Creation of a ListBox with tk.ListBox
    • Item insertion and removal Adding of items in a list using insert() function and looping, and removal using delete().

    Conclusion:

    The tutorial excerpts provide a comprehensive overview of Python’s fundamental concepts and key libraries. It introduces Python’s basic syntax, various data structures, control flow mechanisms, and fundamental libraries for file handling, data analysis and visualization and GUI creation. The tutorial utilizes a hands-on, example-driven approach, making it ideal for beginners learning Python. The inclusion of code snippets and explanations helps to solidify understanding. It is a good foundation for continued learning of more advanced Python topics.

    Essential Python Programming Concepts

    FAQ

    1. What is a kernel in the context of Python programming, particularly when using a Jupyter notebook?

    A kernel is essentially the executor of your Python code in a Jupyter Notebook environment. When you write a piece of code and want to run it, the kernel is what actually processes and executes that code. You can think of it as the engine that brings your Python code to life, producing results that you can see in the notebook.

    2. How are basic arithmetic operations performed in Python?

    Python uses standard symbols for arithmetic operations. Addition is done with the + symbol, subtraction with -, multiplication with *, and division with /. These operators are placed between two operands, and the interpreter will carry out the specified calculation. For example, num1 + num2 will add the values stored in the variables num1 and num2.

    3. What are relational operators and how are they used in Python?

    Relational operators in Python are used to compare the values of two operands. They help determine if one value is less than, greater than, equal to, or not equal to another. The less than operator is <, greater than is >, equal to is ==, and not equal to is !=. These operators return a boolean value (True or False) based on the comparison result.

    4. What are Python tokens, and what are some of the basic types?

    Python tokens are the smallest meaningful components of a Python program. When combined, they form the executable code. The basic types of tokens include: keywords (reserved words with specific meanings like if, def, while), identifiers (names given to variables, functions, or objects), literals (constant values like numbers or strings), and operators (symbols used for calculations or comparisons).

    5. How can strings be defined and manipulated in Python?

    Strings in Python are sequences of characters enclosed in single quotes, double quotes, or triple quotes (for multi-line strings). Python provides various methods for string manipulation. lower() and upper() convert strings to lowercase or uppercase respectively. len() finds the length of a string. replace() replaces parts of a string. count() counts the occurrences of a substring. find() locates the starting index of a substring, and split() divides a string into substrings based on a delimiter.

    6. What are lists in Python, and how do they differ from tuples?

    Lists in Python are ordered collections of elements, enclosed in square brackets ([]). They are mutable, meaning their elements can be changed after the list is created. Lists support various operations, including adding elements (append()), removing elements (pop()), accessing elements by index, and modifying existing elements. Tuples, on the other hand, are similar to lists but are immutable and are enclosed in round parentheses ().

    7. What are dictionaries in Python, and how are they used?

    Dictionaries in Python are unordered collections of key-value pairs, enclosed in curly braces ({}). Each key in a dictionary must be unique and immutable (e.g., strings, numbers, tuples), and it maps to a corresponding value. Dictionaries are mutable and allow for adding, modifying, and removing key-value pairs. They can be accessed using the key, and various methods exist for extracting keys (keys()) and values (values()).

    8. How are decision-making (if-else) and looping (for, while) statements implemented in Python?

    Decision-making in Python is implemented using if, elif (else if), and else statements, which enable conditional execution of code based on whether a specific condition is true or false. Looping statements allow for the repetition of a task. The for loop is used to iterate over a sequence of items (such as a list or string) a certain number of times, while the while loop is used to repeat a task as long as a specific condition remains true. Both types of loops allow for controlled repetition of code.

    Python Lists: A Comprehensive Guide

    Python lists are ordered collections of elements enclosed within square brackets [1, 2]. Unlike tuples, which are immutable, lists are mutable, meaning their values can be changed after creation [1]. Lists can store elements of different types [3].

    Here’s a breakdown of key concepts and operations related to lists:

    • Creating a List: Lists are created using square brackets and can contain various data types [1, 3]:
    • L1 = [1, ‘e’, True]
    • L2 = [1, ‘a’, 2, ‘B’, 3, ‘C’]
    • Accessing Elements: Elements in a list are accessed using their index, starting from 0 [2]:
    • L1 will extract the first element (1) [2].
    • L1[4] will extract the second element (‘e’) [2].
    • L2[-1] will extract the last element (‘C’) [5].
    • Slicing can be used to extract a series of elements [2]: L2[2:5] will extract elements from index 2 up to (but not including) index 5, resulting in [2, ‘B’, 3] [2, 5].
    • Modifying Lists:
    • Changing values: Existing values in a list can be changed by assigning a new value to a specific index [5]:
    • L2 = 100 # Changes the value at index 0 from 1 to 100
    • Appending elements: New elements can be added to the end of a list using the append() method [5]:
    • L1.append(‘Sparta’) # Adds ‘Sparta’ to the end of L1
    • Popping elements: The pop() method removes and returns the last element of a list [5]:
    • L1.pop() # Removes the last element of L1
    • Other List Operations:
    • Reversing: The order of elements in a list can be reversed using the reverse() method [6]:
    • L1.reverse()
    • Inserting: Elements can be inserted at a specific index using the insert() method, which takes the index and the value as parameters [7]:
    • L1.insert(1, ‘Sparta’) # Inserts ‘Sparta’ at index 1, shifting other elements
    • Sorting: Elements can be sorted in alphabetical order using the sort() method [7, 8]:
    • L3 = [‘mango’, ‘apple’, ‘guava’, ‘lii’]
    • L3.sort() # Sorts L3 alphabetically: [‘apple’, ‘guava’, ‘lii’, ‘mango’]
    • Concatenation: Two lists can be combined using the + operator [9]:
    • L1 = [4, 10, 11]
    • L2 = [‘a’, ‘b’, ‘c’]
    • L1 + L2 # Results in [1, 2, 3, ‘a’, ‘b’, ‘c’]
    • Repeating: A list can be repeated by multiplying it by a scalar number [9]:
    • L1 * 3 # Repeats the elements of L1 three times
    • Checking Data Type: To confirm the data type of a variable, the type() method can be used [2]:
    • type(L1) # Returns that L1 is a list.

    Lists are a fundamental data structure in Python, widely used for storing and manipulating collections of items [1, 3].

    Python List Indexing

    List indexing in Python is a way to access individual elements or a range of elements within a list using their position or index [1, 2]. Indexing starts from zero for the first element, and negative indices can be used to access elements from the end of the list [2].

    Here’s a detailed look at list indexing:

    • Basic Indexing:
    • Elements are accessed using their index within square brackets [] [1, 2].
    • The first element is at index 0, the second at index 1, and so on [2].
    • For a list L1 = [1, ‘e’, True], L1 would return 1, L1[3] would return ‘e’, and L1[4] would return True [2].
    • Negative Indexing:
    • Negative indices allow access to elements from the end of the list, with -1 being the last element, -2 the second-to-last, and so on [2].
    • For a list L2 = [1, ‘a’, 2, ‘B’, 3, ‘C’], L2[-1] would return ‘C’, L2[-2] would return 3, and so on [2].
    • Slicing:
    • Slicing is used to extract a range or series of elements from a list [2].
    • The syntax for slicing is list[start:end], where start is the index of the first element to include, and end is the index of the first element not to include [2].
    • For example, L2[2:5] would return [2, ‘B’, 3], which includes elements at indices 2, 3, and 4, but not 5 [2].
    • If the start index is omitted, slicing begins from the start of the list, and if the end index is omitted, it goes up to the end of the list. For example, L2[:3] will return the first three elements, and L2[3:] will return the elements from the 4th element to the end.
    • You can use negative indices for slicing as well. For example, if you want to extract elements starting from the third element from the end of the list to the end, you can use the slice L2[-3:] [5].
    • Index Out of Range:
    • Attempting to access an index that is outside the valid range of the list will result in an IndexError. For example if L1 has 3 elements, attempting to access L1[6] would raise an error because there is no element at index 3.
    • Modifying elements with indexing:
    • Indexing is not just for accessing elements; you can also modify the value of an element at a given index. For example, with L2 = 100, the first element of L2 is updated to the value 100 [7].

    Understanding list indexing is crucial for effectively manipulating and accessing data within lists in Python.

    Modifying Python Lists

    Python lists are mutable, meaning they can be modified after creation. Here’s how lists can be modified, based on the sources:

    • Changing values: Existing values in a list can be changed by assigning a new value to a specific index [1]. For example, if L2 = [1, ‘a’, 2, ‘B’, 3, ‘C’], then L2 = 100 would change the value at index 0 from 1 to 100 [1].
    • Appending elements: New elements can be added to the end of a list using the append() method [1]:
    • L1 = [1, ‘e’, True]
    • L1.append(‘Sparta’) # Adds ‘Sparta’ to the end of L1
    • Popping elements: The pop() method removes and returns the last element of a list [1, 2]. For example:
    • L1 = [1, ‘e’, True, ‘Sparta’]
    • L1.pop() # Removes ‘Sparta’ from L1, and L1 becomes [1, ‘e’, True]
    • Inserting elements: New elements can be inserted at a specific index using the insert() method [3]. The method takes the index where the new element should be inserted, and the value of the new element as parameters. For example:
    • L1 = [1, ‘a’, 2, ‘B’, 3, ‘C’]
    • L1.insert(1, ‘Sparta’) # Inserts ‘Sparta’ at index 1, shifting other elements
    • # L1 is now [1, ‘Sparta’, ‘a’, 2, ‘B’, 3, ‘C’]
    • Reversing elements: The order of elements in a list can be reversed using the reverse() method [2]:
    • L1 = [1, ‘a’, 2, ‘B’, 3, ‘C’]
    • L1.reverse() # L1 is now [‘C’, 3, ‘B’, 2, ‘a’, 1]
    • Sorting elements: Elements in a list can be sorted using the sort() method [3]. By default, the sort method will sort alphabetically:
    • L3 = [‘mango’, ‘apple’, ‘guava’, ‘lii’]
    • L3.sort() # Sorts L3 alphabetically: [‘apple’, ‘guava’, ‘lii’, ‘mango’]

    These operations allow for flexible manipulation of list data by adding, removing, and reordering list items.

    Python File Handling

    File handling in Python involves working with text files, allowing for operations such as opening, reading, writing, appending, and altering text [1-4]. It is also referred to as IO (input/output) functions [2].

    Here are the key aspects of file handling:

    • Opening Files:The open() function is used to open a text file [5].
    • The open() function takes the filename as an argument, and the mode in which the file is to be opened [6, 7].
    • The file must be in the same folder as the Python file [5].
    • Modes include:
    • Read mode (“r”): Opens a file for reading [7]. This is used when you want to read the text already stored in the text file [8].
    • Write mode (“w”): Opens a file for writing [7]. This is used when you want to add or overwrite text in the file [8].
    • Append mode (“a”): Opens a file for appending [9, 10]. This is used when you want to add text to the end of a file without overwriting the existing content [9, 10].
    • Reading Files:The read() function is used to read the entire content of a file [7, 11].
    • The readline() function reads a file line by line [12, 13]. It can be used to print the text in a file line by line [14, 15]. Each subsequent call to readline() will read the next line in the file [15, 16].
    • Writing to Files:The write() function is used to write text to a file [17].
    • When using the write() function, you must specify the text to be written within the function’s parentheses [17].
    • Appending to Files:The append mode (“a”) allows you to add text to the end of a file without overwriting the existing content [9, 10].
    • The write() function is also used for appending text [18].
    • To add text on a new line when appending, use the \n operator at the beginning of the text to be added [9, 10, 18].
    • Closing Files:It’s important to close a file after it has been opened, using the close() method [17, 19].
    • Closing files is a good practice [19].
    • Counting Characters:The len() function is used to count the total number of characters in a file [10, 20, 21].
    • You must read the file content into a variable, and apply the len() function to this variable [20].

    Important Notes:

    • Online IDEs may not support file handling, as they may not support both .py and .txt files simultaneously [2, 3].
    • Offline IDEs, like PyCharm, VS Code, and Jupyter Notebooks, are recommended for file handling [3].
    • When working with text files, you do not need to use comments, hash signs, or quotation marks, since these are plain text files [22].

    File handling is essential for working with data stored in external files. It involves a few key steps, with different methods for reading, writing, and modifying files.

    Generative AI: A Comprehensive Overview

    Generative AI (GenAI) is a rapidly evolving field of artificial intelligence focused on creating new content, transforming existing content, or generating content based on provided inputs [1, 2]. It differs from traditional AI by using input instructions to produce outputs in various formats, including text, audio, video, and images [1, 3].

    Here are some key concepts in GenAI, based on the sources:

    • Core Function: GenAI employs neural networks to analyze data patterns and generate new content based on those patterns [2]. It is a mimicry of biological neurons, based on how the brain functions [2].
    • Evolution of Computers: Computers initially served as calculating machines but have evolved to incorporate human-like intelligence and creativity [1]. AI is the mimicking of human intelligence, and GenAI combines AI with creativity [1].
    • Discriminative vs. Generative AI:Discriminative AI acts as a judge, classifying data into categories. For example, when given a data set of images of cats and dogs, discriminative AI will classify the images into categories of cats and dogs [2].
    • Generative AI acts as an artist by creating new content. For example, when given a data set of images of cats and dogs, generative AI will create new images of a new species of dogs or cats [2].
    • Generative Models: GenAI works through the use of generative models that are pre-trained on data and fine-tuned to perform specific tasks, such as text summarization, image generation, or code creation [4].
    • Types of Generative AI: There are different types of GenAI models, including:
    • Generative Adversarial Networks (GANs): Two models work together, one to generate content and the other to judge it [4].
    • Variational Autoencoders: These AIs learn to recreate and generate new, similar data [4].
    • Transformers: These AIs produce sequences using context [4].
    • Diffusion Models: These models refine noisy data until it becomes realistic [4].
    • Applications of Generative AI:Content Creation: Generating text, code, and other media [4, 5].
    • Customer Support and Engagement: Improving interactions and service [4].
    • Data Analysis: Assisting in data visualization and analysis [4, 5].
    • Code Generation: Helping to create code [5].
    • Research and Information Retrieval: Helping researchers extract information from various sources [4, 5].
    • Machine Translation: Translating text and audio into other languages [5].
    • Sentiment Analysis: Analyzing text to determine if it contains positive, negative or neutral sentiment [5].
    • Other Domains: Including healthcare and transportation [5].

    GenAI is impactful across many fields because it can work with various forms of inputs to generate new and original content, unlike traditional AI which is dependent on the input format. It is also constantly evolving, making it close to magic [3].

    Python Tutorial with Gen AI for 2025 | Python for Beginners | Python full course

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Python Programming Fundamentals: Data Types, Functions, and User Input

    Python Programming Fundamentals: Data Types, Functions, and User Input

    The source is a Python programming tutorial. It explains fundamental concepts, data types, and structures like strings, integers, booleans, lists, sets, and dictionaries. It also covers functions, modules, object-oriented programming (OOP) principles using classes, and file handling, specifically with spreadsheet data. The tutorial provides practical coding examples and discusses built-in modules for tasks like date/time management. It further explores how to install external packages for more specialized operations and encourages logical thinking alongside coding skills. The tutorial is geared towards beginners, particularly those interested in devops engineering.

    Python Fundamentals Study Guide

    Quiz

    Instructions: Answer the following questions in 2-3 sentences each.

    1. What is an Integrated Development Environment (IDE), and what are some of the benefits of using one?
    2. Explain the difference between integers and strings in Python. Provide examples of each.
    3. What is string concatenation, and how is it achieved in Python? Show an example of string concatenation.
    4. Why are variables useful in programming? Describe the advantages of using variables in your code.
    5. In Python, what is a reserved word? Provide two examples and explain why they can’t be used as variable names.
    6. What are functions? Describe the advantages of using functions in your code.
    7. Differentiate between global and local variables. Why is understanding variable scope important?
    8. What is a conditional statement? Explain how ‘if,’ ‘elif,’ and ‘else’ statements are used.
    9. How can you handle potential errors or exceptions when asking for user input in Python? Describe what a ‘try/except’ block does.
    10. Explain the difference between a list and a set in Python. When would you choose to use one over the other?

    Answer Key

    1. An Integrated Development Environment (IDE) is a software application that provides comprehensive facilities to computer programmers for software development. Benefits include syntax highlighting, code completion, and integrated debugging tools, all in one place to streamline development and make a developer’s job easier.
    2. Integers are whole numbers (positive, negative, or zero), while strings are sequences of characters (text). For example, 10 is an integer, and “Hello” is a string.
    3. String concatenation is the process of combining two or more strings into a single string. In Python, it can be done using the plus sign (+) or f-strings. For instance, “Hello” + ” ” + “World” results in “Hello World”.
    4. Variables are useful because they allow you to store and reuse values throughout your code, avoiding repetition and making your code more readable and maintainable. By using variables, you only need to change the value in one place, and it will be reflected everywhere the variable is used.
    5. Reserved words are words that have special meanings to Python and cannot be used as variable names. Examples include def and if. Using them as variable names would cause syntax errors, as they would conflict with Python’s built-in language constructs.
    6. Functions are blocks of organized, reusable code that perform a specific task. Functions promote code reusability and make your code modular and easier to understand by breaking down complex tasks into smaller, manageable units.
    7. Global variables are defined outside of any function and can be accessed from anywhere in the code, while local variables are defined within a function and can only be accessed within that function. Understanding scope is important because it determines where a variable can be used and helps prevent naming conflicts.
    8. A conditional statement allows you to execute different blocks of code based on whether a certain condition is true or false. The if statement executes a block of code if a condition is true, elif (else if) checks an additional condition if the first condition is false, and else executes a block of code if none of the preceding conditions are true.
    9. To handle potential errors when asking for user input, you can use a try/except block. The code that might raise an error (e.g., converting user input to an integer) is placed inside the try block, and if an error occurs, the code inside the except block is executed, allowing you to handle the error gracefully.
    10. A list is an ordered collection of items that can contain duplicates, while a set is an unordered collection of unique items (no duplicates). You would use a set when you need to ensure that all elements are unique and when the order of elements doesn’t matter, and a list when you need to maintain the order of elements and allow duplicates.

    Essay Questions

    Instructions: Answer the following questions in essay format, drawing upon the source material.

    1. Discuss the importance of code style and readability. How can tools like PyCharm aid in maintaining consistent code style?
    2. Explain the concept of “decomposition” in programming. How do functions contribute to code decomposition, and why is it important for managing complex projects?
    3. Describe the process of validating user input. Why is input validation crucial, and what techniques can be employed to ensure data integrity?
    4. Explain the benefits of using modules to organize your code. How do modules promote code reusability and maintainability in larger projects?
    5. Discuss the different data types available in Python, such as strings, integers, floats, lists, sets, and dictionaries. Explain why it’s important to understand and utilize appropriate data types to accomplish specific tasks.

    Glossary of Key Terms

    • IDE (Integrated Development Environment): A software application that provides comprehensive facilities to computer programmers for software development.
    • Data Type: A classification identifying one of various types of values that determine the possible values for that type, the operations that can be performed on that type, and the way values of that type can be stored.
    • String: A sequence of characters; a data type used to represent text.
    • Integer: A whole number (positive, negative, or zero); a data type used to represent numeric values without fractional parts.
    • Float: A number with a decimal point; a data type used to represent numbers with fractional parts.
    • Boolean: A data type with only two possible values: true or false.
    • String Concatenation: The process of combining two or more strings into a single string.
    • Variable: A storage location paired with an associated symbolic name (an identifier), which contains a known or unknown quantity of information referred to as a value.
    • Reserved Word: A word that has special meaning to a programming language and cannot be used as a variable name.
    • Function: A block of organized, reusable code that performs a specific task.
    • Global Variable: A variable defined outside of any function, accessible from anywhere in the code.
    • Local Variable: A variable defined within a function, accessible only within that function.
    • Variable Scope: The region of a program where a variable can be accessed.
    • Conditional Statement: A statement that executes different blocks of code based on whether a certain condition is true or false (if, elif, else).
    • Comparison Operator: Symbols used to compare two values (e.g., >, <, ==).
    • Boolean Value: A value that is either true or false.
    • Exception Handling: The process of responding to the occurrence, during computation, of exceptions – anomalous or exceptional conditions requiring special processing – often changing the normal flow of program execution.
    • Try/Except Block: A construct used to handle exceptions.
    • Loop: A sequence of instructions that is continually repeated until a certain condition is reached.
    • List: An ordered collection of items that can contain duplicates.
    • Set: An unordered collection of unique items (no duplicates).
    • Dictionary: A collection of key-value pairs, where each key is unique.
    • Module: A file containing Python definitions and statements; a way to organize code into reusable units.
    • Built-in Function: Functions that are available in Python without needing to import a module (e.g., print(), input(), int()).
    • Package: A way of organizing related modules into a directory hierarchy.
    • pip: A package management system used to install and manage software packages written in Python.
    • Library: Describes package that includes multiple other packages, a hierarchy of packages.

    Python Programming: Core Concepts and Usage

    Okay, here’s a detailed briefing document summarizing the main themes and important ideas from the provided text.

    Briefing Document: Python Programming Concepts

    Overview:

    This document summarizes key concepts in Python programming, as taught in a course or tutorial. It covers fundamental topics like Integrated Development Environments (IDEs), data types (strings, integers, floats, booleans), string concatenation and formatting, variables, functions, user input, conditional statements (if/else), loops (while, for), lists, sets, dictionaries, built-in functions, modules (including datetime and OS), package management (pip), and file handling with external packages (openpyxl).

    I. Setting up the Development Environment:

    • Integrated Development Environments (IDEs): IDEs like PyCharm provide a comprehensive environment for writing and executing code. They offer features like:
    • File navigation within the project.
    • Built-in execution environment (eliminating the need to use a separate terminal).
    • Syntax highlighting.
    • Error highlighting.
    • Code suggestions and autocompletion.
    • “Integrated because you have everything in one place so you don’t need to use terminal but in addition to this integration you get more cool features which helps you in writing python code for example syntax highlighting highlighting errors or code suggestions autocomplete suggestions and we will see those cool features actually also throughout this course so basically just makes your life as a developer easier…”

    II. Data Types:

    • Strings: Textual data is represented as strings, enclosed in either double quotes or single quotes. There’s no functional difference between using single or double quotes.
    • “everything within the double quotes is basically a string but note that in python you can also use single quotes for strings so double quotes or single quotes they both work the same and there’s actually no difference between them”
    • Integers: Whole numbers (positive, negative, or zero) are represented as integers.
    • “for whole numbers like 2 20 but also 0 and negative numbers as well we have a data type called integer and that’s also how it’s called in most programming languages”
    • Floats: Numbers with decimal precision (e.g., currency values, weights) are represented as floats.
    • “however you also have numbers for currency for example how much a product costs right so if you have an online shop you would have prices like this for example so these are basically numbers with precision”
    • Booleans: Represent truth values: True or False. Used extensively in conditional statements.
    • “and those true and false values in programming actually are represented by its own data type which is called boolean”

    III. String Concatenation and Formatting:

    • String Concatenation: Combining strings using the + operator. Requires explicit conversion of non-string data types to strings using str().
    • “we combine the strings using plus sign so apart from adding numbers obviously using plus plus is also used in programming for combining multiple strings”
    • “if we just put a number here python interpreter tells us it’s not a string it’s a number so we need to turn it into a string”
    • Formatted String Literals (f-strings): A more elegant way to embed expressions within strings, using curly braces {} and the f prefix before the string. Requires Python 3.6 or later.
    • “instead of having these plus we have curly braces and we write our number inside or whatever non-textual value and at the beginning right here basically before we start writing a string which starts with quotes we just write the letter f”
    • “this f actually stands for format so this is basically formatting our text or our string in a correct way”

    IV. Variables:

    • Variables store values that can be reused throughout the code. Python’s variable definition is simple: variable_name = value. No explicit data type declaration is needed (unlike some other languages).
    • “in python defining or creating a variable and giving it a value like this syntax for that is actually very simple compared to other languages because you just have the variable name and the value in many programming languages you actually have to define here some kind of data type for that variable for example if it’s a number like float or integer or string etc in python you don’t have to define that”
    • Naming Conventions: Use descriptive variable names, separating words with underscores (e.g., calculation_to_seconds). Avoid using reserved words (keywords) as variable names.
    • “variables that are descriptive so basically they tell you what this value actually is about so they have multiple words in them you can separate them using these underlines”

    V. Functions:

    • Functions are reusable blocks of code that perform specific tasks. They are defined using the def keyword.
    • “functions are basically blocks of code like this right or basically logic in code that does something it’s not just simply a value but actually does something more complex that is again used in order to avoid repeating the same logic or most of the same logic in your code”
    • “we start with def so we define a function just like we define a variable but for function we need this keyword basically called def”
    • Parameters: Functions can accept input values called parameters, defined within the parentheses () in the function definition.
    • “instead of having this 20 basically here hard coded as we said here and here we provide that value of 20 or 35 or whatever that value is basically whenever we use the function”
    • Calling Functions: Functions are executed (or “called”) using their name followed by parentheses, optionally including arguments for the parameters: function_name(argument1, argument2).
    • “whenever you create a function or define a function like this you actually have to use that function right”
    • “How do we use a function or in programming languages it’s called calling a function or executing a function and we do that using the name of the function like this”
    • Variable Scope:Global Scope: Variables defined outside a function are accessible to all functions in the code.
    • Local Scope: Variables defined within a function are only accessible within that function.
    • “variable has a global scope for a function if it is defined outside the function like these two variables right here could be completely in a different file not even in the same file where the function is so these are global variables”
    • “local variables are variables that are created within that function right so these two variables are basically only available inside that function because it was created within that function so internal scope and global scope”

    VI. User Input:

    • The input() function prompts the user to enter a value. The input is always returned as a string.
    • “accepting a user input from a python application is actually pretty easy let’s get rid of all of these lines first and we can do that by writing input and this will basically give a user a prompt to enter some input value”

    VII. Conditional Statements (if/else):

    • if statements execute a block of code if a condition is true. else statements provide an alternative block of code to execute if the if condition is false. elif (else if) allows for multiple conditions to be checked in sequence.
    • “if condition then do something otherwise do something else and that conditional can be true or false”
    • “in the if else statement in programming we can have multiple conditionals so basically we can have multiple ifs so how do we do that first we check number of days is greater than zero okay great now we want to check whether number of days is equal to zero and we can do that using another if here and in python the syntax for that is el if which basically is a combination of else and if”
    • Comparison Operators: Used to compare values in conditional statements (e.g., >, <, == (equals), >=, <=, != (not equals)). == checks for equality; a single = is used for assignment.
    • “this greater than sign is called a comparison operator and we have three of them we have greater than less than and equals and these are called comparison operators because they are used in an operation to compare two values”
    • Boolean Data Type in Conditionals: The condition in an if statement evaluates to a boolean value (True or False).
    • “this conditional will either give true or false what i’m going to do is i’m going to print this conditional right before i do the check so for a positive number input this should print true and if it’s negative so it’s not greater than 0 this should print false”

    VIII. Loops:

    • while Loops: Execute a block of code repeatedly as long as a condition is true.
    • “the second type of loop is called while loop and that while loop will basically keep that block of code that is part of it executed again and again as many times as needed and in order to say how many times the code needs to get repeated we again need a condition”
    • for Loops: Iterate over a sequence (e.g., a list, a string) and execute a block of code for each item in the sequence.
    • “we have another type of loop called for loop and basically we want to execute validate and execute function using a for loop”

    IX. Exception Handling (try/except):

    • The try block encloses code that might raise an exception (error). The except block handles the exception if it occurs, preventing the program from crashing.
    • “we put potentially dangerous code in that try and if anything bad happens within this logic within this logic block that we put in the try block if there is any error happening python will automatically catch this error and will transfer the execution flow automatically right here to the code that we specify after the accept”

    X. Data Structures:

    • Lists: Ordered, mutable (changeable) collections of items, enclosed in square brackets []. Lists can contain items of different data types. Lists allow duplicate values.
    • “the syntax for list is using square brackets and inside the square brackets we have a list of elements and those elements can again be either strings numbers or boolean values”
    • Sets: Unordered collections of unique items, enclosed in curly braces {}. Sets do not allow duplicate values.
    • “set is basically a list of elements but with unique values inside so list data type allows duplicate values the same value multiple times set does not allow duplicate values”
    • Dictionaries: Unordered collections of key-value pairs, enclosed in curly braces {}. Keys must be unique and immutable (e.g., strings, numbers).
    • “dictionary is basically a collection of key value pairs”
    • “each element in this dictionary has key and a value”

    XI. Built-in Functions:

    • Python provides a variety of built-in functions that perform common tasks (e.g., print(), input(), int(), str(), len(), set(), type()).
    • “functions that we ourselves didn’t actually write and the functions that python basically makes available for us to use are called built-in functions”
    • Some built-in functions are called directly (e.g. print(x)). Other built-in functions are called on a specific object (e.g., my_string.split(), my_list.append()).

    XII. Modules:

    • Modules are files containing Python code that define functions, classes, and variables. They provide a way to organize and reuse code.
    • “modules are basically just organizing your code into multiple python files like that and then accessing some parts from a module like functions variables etc from one file from another and the goal here is basically not to put the whole logic into one single massive file but rather to have it nicely separated based on the logic”
    • Importing Modules: Modules are imported using the import statement. Specific elements (functions, variables) can be imported using from module import element. All elements can be imported using from module import *. Modules can be renamed using import module as alias.
    • “you can pick and choose which specific functions you want to make available inside another file or another module and you can do that very easily using the following syntax we say from helper that’s the module again import and the name of the function like this”
    • Built-in Modules: Python includes several built-in modules that provide functionality for various tasks (e.g., os, datetime, logging).
    • “we can actually use modules that python itself already includes so just like we used some functions that python gives us out of the box like inputs or ins so basically all of those the same way python also gives us modules for different scenarios so that we don’t have to write this logic ourselves”

    XIII. Package Management (pip):

    • pip is the package installer for Python. It is used to install and manage external packages and libraries from the Python Package Index (PyPI).
    • “in python we install packages using a package manager tool called peep”
    • “pip is a package manager for python”
    • pip install package_name installs a package.
    • External packages extend Python’s functionality and provide ready-made solutions for common programming tasks.

    XIV. File Handling with External Packages (openpyxl):

    • External packages, such as openpyxl, provide specialized tools for working with specific file formats (e.g., spreadsheets).
    • “there is an external package that allows you to work with spreadsheets specifically”
    • Packages like openpyxl offer functions for reading, writing, and manipulating data in spreadsheet files.

    This document provides a high-level overview of the Python concepts covered in the source text. It emphasizes definitions, syntax, and key use cases for each topic.

    Python Development Fundamentals

    IDEs, Data Types, and String Concatenation

    • What is an IDE and why is it useful for Python development?
    • An Integrated Development Environment (IDE) is a software application that provides comprehensive facilities to computer programmers for software development. IDEs like PyCharm bundle common developer tools into a single graphical user interface (GUI). This usually consists of a source code editor, build automation tools, and a debugger. In the context of Python, an IDE integrates file navigation, code execution (eliminating the need for a separate terminal), syntax highlighting, error highlighting, code completion, and other features that simplify and accelerate the coding process, making developers more productive.
    • What are data types in Python, and can you provide examples of common data types?
    • Data types are classifications that specify which type of value a variable has and what type of mathematical, relational or logical operations can be applied to it without causing an error. Common data types in Python include:
    • Strings: Used for text. Strings are enclosed in either single quotes (‘) or double quotes (“) e.g., “Hello” or ‘World’.
    • Integers: Used for whole numbers (positive, negative, and zero) e.g., 2, -20, 0.
    • Floats: Used for numbers with decimal points, representing numbers with precision e.g., 2.99, 150.00.
    • Booleans: Represents true or false values.
    • What is string concatenation and how is it achieved in Python?
    • String concatenation is the process of combining multiple strings into a single string. In Python, string concatenation can be achieved using the + operator or f-strings (formatted string literals). The + operator joins strings together, while f-strings allow you to embed expressions inside string literals, which are evaluated at runtime and formatted accordingly. F-strings are generally considered more readable and efficient.
    • What are f-strings in Python, and what advantages do they offer over traditional string concatenation methods?
    • F-strings, introduced in Python 3.6, are a more concise and readable way to format strings. An f-string is a string literal prefixed with f or F. F-strings offer several advantages:
    • Readability: They allow you to embed expressions directly within string literals, making the code easier to read and understand.
    • Conciseness: They eliminate the need for explicit string concatenation operators or formatting methods.
    • Efficiency: F-strings are generally faster than other string formatting methods because they are evaluated at runtime.
    • Direct Embedding: Instead of needing to convert a data type to a string and then concatenate, f-strings allow for direct embedding using curly braces.

    Variables, Functions, and Program Control

    • What are variables, and why are they used in programming?
    • Variables are named storage locations that hold values in a computer’s memory. Variables are used in programming to store data that can be accessed, modified, and reused throughout a program. Variables help to avoid repetition of values, enhance code readability, and make it easier to update values in multiple places by changing the value of the variable once.
    • What are functions, and how do they help in writing modular and reusable code?
    • Functions are self-contained blocks of code that perform a specific task. Functions help in writing modular and reusable code by encapsulating logic into named units that can be called from different parts of a program. Functions promote code organization, reduce redundancy, and make it easier to maintain and update code. Functions can accept inputs (parameters) and return outputs.
    • What are variable scopes (local vs. global), and how do they affect the accessibility of variables within a program?
    • Variable scope refers to the region of a program where a variable can be accessed. There are two main types of variable scopes:
    • Local scope: Variables defined within a function have local scope, meaning they can only be accessed within that function.
    • Global scope: Variables defined outside of any function have global scope, meaning they can be accessed from anywhere in the program, including inside functions. It is possible to have a local and global variable with the same name, where the local variable “shadows” the global variable.
    • How can conditional statements (if/else) and loops (for/while) control the flow of execution in a Python program?
    • Conditional statements (if/else) allow you to execute different blocks of code based on whether a condition is true or false. Loops (for/while) allow you to repeat a block of code multiple times, either a fixed number of times (for loop) or until a condition is met (while loop). These control structures enable you to create programs that can make decisions and perform repetitive tasks efficiently. If-else statements can be chained using elif to check multiple conditions in sequence.

    User Input, Error Handling, and Data Structures

    • How can you prompt the user for input in Python, and why is it important to validate user input?
    • You can prompt the user for input in Python using the input() function, which displays a message to the user and returns the text entered by the user as a string. It is important to validate user input to ensure that it is in the expected format and range, preventing errors and crashes in your program. Validation can involve checking data types, verifying numeric ranges, and sanitizing input to prevent security vulnerabilities.
    • What is exception handling (try/except), and how does it help in writing robust and error-resistant code?
    • Exception handling (try/except) is a mechanism for handling errors that occur during program execution. The try block encloses code that might raise an exception, and the except block specifies how to handle that exception if it occurs. Exception handling allows you to gracefully recover from errors, prevent program crashes, and provide informative error messages to the user. Using exception handling allows a program to continue running even when an error occurs.
    • What are lists, sets, and dictionaries in Python, and what are their key differences and use cases?
    • Lists: Ordered collections of items that can be of any data type. Lists are mutable, meaning their elements can be changed after creation. Lists allow duplicate values.
    • Sets: Unordered collections of unique items. Sets are mutable and do not allow duplicate values. Sets are useful for removing duplicates from a collection and for performing set operations like union, intersection, and difference.
    • Dictionaries: Collections of key-value pairs, where each key is associated with a value. Dictionaries are mutable and allow you to access values efficiently using their corresponding keys. Dictionaries are useful for storing and retrieving data based on unique identifiers.
    • How can you iterate over a list or set using a for loop, and how can you access values in a dictionary using keys?
    • You can iterate over a list or set using a for loop by specifying the list or set as the iterable object. The loop variable will take on the value of each element in the list or set, one at a time. You can access values in a dictionary using keys by specifying the key inside square brackets ([]) or by using the get() method.
    • my_list = [1, 2, 3]
    • for item in my_list:
    • print(item) # Prints each element: 1, 2, 3
    • my_dict = {“a”: 1, “b”: 2}
    • print(my_dict[“a”]) # Prints 1
    • print(my_dict.get(“b”)) # Prints 2

    Modules, Packages, and File Handling

    • What are modules and packages in Python, and how do they help in organizing and reusing code?
    • Modules are individual Python files that contain functions, classes, and variables. Packages are collections of modules organized into directories. Modules and packages help in organizing and reusing code by breaking down large programs into smaller, manageable units. Modules can be imported into other Python files, allowing you to access their contents. Packages provide a hierarchical structure for organizing modules, making it easier to manage large codebases.
    • How can you import modules and packages into your Python code using the import statement?
    • You can import modules and packages into your Python code using the import statement. The import statement specifies the name of the module or package you want to import, making its contents available in your current file. You can also use the from … import syntax to import specific functions or classes from a module, or from … import * to import everything. Aliases can be created when importing using import X as Y.
    • What is pip, and how can it be used to install external packages from the Python Package Index (PyPI)?
    • pip is the package installer for Python. You can use pip to install external packages from the Python Package Index (PyPI), which is a repository of third-party Python packages. To install a package using pip, you can use the command pip install package_name in your terminal. pip will download and install the package and any dependencies it may have.
    • How can you read data from and write data to files in Python, including working with spreadsheet files using external libraries like openpyxl?
    • You can read data from files in Python using the open() function to open the file and then using methods like read(), readline(), or readlines() to read the file contents. You can write data to files using the open() function with the ‘w’ or ‘a’ mode and then using the write() method to write data to the file. For working with spreadsheet files, you can use external libraries like openpyxl, which provide functions for reading data from and writing data to Excel files. openpyxl allows you to load workbooks, access worksheets, read cell values, and write new data to cells.

    Comprehensive Introduction to Python Programming

    This Python course covers everything needed for a beginner to get started with Python.

    Here’s a summary of the course content:

    • Introduction to Python: Includes Python’s advantages, flexibility, and multi-purpose nature.
    • Basic building blocks: Covers important data types (strings, numbers, lists, sets, dictionaries, booleans), variables, and functions.
    • User input and validation: Writing programs that accept user input and validating it using conditionals.
    • Error handling: Using “try…except” blocks.
    • Loops: Utilizing “while” and “for” loops.
    • Modularizing programs: Writing modules and using built-in Python modules.
    • Demo project: Writing a program that accepts a goal and a deadline as user input and outputs the number of days remaining until the deadline, using the “datetime” module.
    • Packages: Explanation of packages versus modules and usage of external Python packages.
    • Demo project: Automating tasks for working with spreadsheet files.
    • Object-oriented programming: Learning about classes and objects.
    • Final demo project: Communicating with other applications over the internet by making a request to fetch data from Gitlab API.

    The course also includes information on:

    • Setting up a local Python development environment: Installing Python and a code editor (PyCharm).
    • Integrated Development Environments (IDEs): Using IDEs like PyCharm for syntax highlighting, error highlighting, and code suggestions.
    • String concatenation: Combining text and numbers.
    • Variables: Defining and using variables, naming conventions, and reserved words.
    • Functions: Defining and calling functions, input parameters, and global vs. local variables.
    • User input: Accepting user input with the input function.
    • Data type conversion: Changing a value from one data type to another (casting).
    • Conditionals: Using “if,” “elif,” and “else” statements.
    • Error handling: Using “try” and “except” blocks.
    • Loops: Using “while” and “for” loops for repetitive tasks.
    • Lists: Creating, accessing, and modifying lists.
    • Comments: Writing comments for code documentation.
    • Sets: Creating and manipulating sets.
    • Built-in functions: Overview of useful built-in functions.
    • String functions: Using built-in string functions.
    • Dictionaries: Creating and using dictionaries.
    • Modules: Structuring code using modules.
    • Built-in modules: Using built-in modules like “os,” “logging,” and “datetime”.
    • External packages: Installing and using external packages.
    • Spreadsheet automation: Reading, writing, and manipulating spreadsheet files using “openpyxl”.
    • Object-oriented programming: Defining classes, creating objects, and using methods.
    • API requests: Interacting with external applications using API requests.

    Python Data Types: A Concise Overview

    The Python course introduces several key data types. Data types are a fundamental concept in programming because the data type influences what can be done with the data. Here’s a discussion of data types covered in the course:

    • Strings: Used for text. Strings are usually represented within double quotes, but single quotes work as well. String concatenation, using the plus sign (+), combines multiple strings.
    • Integers: Used for whole numbers, including zero and negative numbers.
    • Floats: Used for numbers with precision, such as currency or weight.
    • Booleans: Represent True or False values, often resulting from a conditional check.
    • Lists: Used to store an ordered collection of items, which can be of any data type. Lists are defined using square brackets []. Lists allow duplicate values. Individual elements of a list can be accessed using their index, starting from zero. You can add elements to a list using the append function.
    • Sets: Similar to lists, but sets only store unique values. Sets are defined using curly braces {}.
    • Dictionaries: Store data in key-value pairs. Dictionaries are also defined using curly braces {}. Values in a dictionary are accessed using their corresponding key.

    The course notes that knowing how to check the type of value can be useful, and this can be done using the type function.

    Also discussed is that each data type has its own built-in functions. For example, string values can use functions like split and isdigit. Similarly, lists have functions like append and remove.

    Python String Concatenation Techniques

    The Python course covers string concatenation, which is the process of combining multiple strings.

    Key points include:

    • Using the plus sign (+): In Python, the + operator is used to combine strings.
    • Explicit string conversion: When combining strings with numbers or other non-string data types, it’s necessary to explicitly convert the number into a string using a function that looks like this: str(number). Python does not automatically convert numbers to strings in concatenation.
    • Elegant Syntax with f-strings: Python offers a more readable and cleaner way to concatenate strings using f-strings. By prefixing a string with f and using curly braces {} to enclose variables or expressions, you can directly embed their values into the string. For example: f”20 days are {20 * 24 * 60} minutes”. This syntax requires Python 3.6 or later.
    • String literals: Any character within single or double quotes is interpreted as a string, including space characters.

    The course notes that f-strings are a newer and more elegant way to handle string formatting in Python.

    Python User Input: Capturing and Validation

    The Python course includes detailed instruction on how to handle user input.

    Key concepts:

    • input() function: The input() function is used to accept input from a user. It takes a string as a parameter, which is displayed as a prompt to the user. The program waits for the user to enter a value and press Enter.
    • Input as a string: The value entered by the user is always treated as a string, even if the user enters a number.
    • Prompts: It is good practice to provide a clear prompt to the user, so they know what type of input is expected. Newline characters (\n) can be added to the prompt string to ensure the user input begins on a new line.

    input function example:

    input(“Enter a number of days:\n”)

    User Input Validation

    Since the input() function returns a string, it’s important to validate the user’s input.

    Here are the key points regarding validation:

    • Data type conversion (casting): If the program requires a number, the input string must be converted to an integer or a float using int() or float(), respectively. This conversion is also called “casting”.
    • Error handling with try and except: To prevent the program from crashing if the user enters an invalid input (e.g., text when a number is expected), use a try…except block. The try block contains the code that might raise an error, and the except block contains the code that will be executed if an error occurs.
    • Validating input type with isdigit(): Before attempting to convert the input to an integer, the isdigit() method can be used to check if the string contains only digits. However, isdigit() returns False for float numbers and negative numbers.
    • Conditional checks: Use if, elif, and else statements to check if the input meets certain criteria (e.g., positive number, within a specific range).

    Validation examples

    • Checking for digits:

    if user_input.isdigit():

    # Code to execute if the input is a digit

    else:

    # Code to execute if the input is not a digit

    • Using try and except to handle potential ValueError:

    try:

    user_input_number = int(user_input)

    # Code to execute if the conversion is successful

    except ValueError:

    # Code to execute if the conversion fails

    Continuous Input

    • while loops: To continuously prompt the user for input until a specific condition is met, a while loop can be used. For example, the program can continue to ask for input until the user enters “exit”.
    • Breaking loops: The break statement can be used to exit a loop prematurely if a certain condition is met.

    while loop example:

    user_input = “”

    while user_input != “exit”:

    user_input = input(“Enter a value (or ‘exit’ to quit):\n”)

    # Process the user input

    Python Tutorial for Beginners – Learn Python in 5 Hours [FULL COURSE]

    The Original Text

    hello and welcome to this python course in this full course you’ll learn everything you need to get started with python python is the most popular programming language out there and is used for so many different industries like web development data science machine learning or generally for writing automation programs to automate repetitive tasks so learning python is definitely a good idea let me give you a short overview of all the topics i’ll cover in this course after giving a short introduction to python we will start with the basic building blocks of programming the most important data types like strings numbers lists sets dictionaries boolean data types etc and how to work with them learn about variables and functions and why we need them write a program that accepts user input and learn how to validate the user input using conditionals error handling with try accept and also learn loops with while and for loops and again why we actually need them you will learn all these concepts with hands-on examples as a next step you will learn how to modularize your program by writing your own modules and then see how to use some built-in python modules with all this knowledge we can then build our next demo project to write a small program that accepts a goal and a deadline as user input and then outputs the number of days remaining till the goal deadline within this exercise you will learn how to use the date time module to work with dates after that you will learn about packages and comparison of package versus module and we will use an external python package in our next demo project in which we will automate some tasks for working with a spreadsheet file finally we dive into object-oriented programming you will learn what classes and objects are in programming and python specifically and why this concept is so useful in the final demo project you will learn another common use case with python which is communicating with other applications over the internet by making a request to fetch some data from gitlab api in this specific case we will list the gitlab projects of a specific user so that’s what we’re gonna learn if you like this course don’t forget to give this video a thumbs up i’m really excited to teach you all of these so let’s get started first of all python is a programming language just like java or javascript python compared to other languages has two very big advantages first of all it’s easy to learn it has a simple syntax and it’s very easy to set up and get started with for example compared to java where you need some initial configuration before you can even start your application but it’s equally or even more powerful than java now what makes a language powerful or how can i say that python is more powerful well that comes from the ecosystem which means libraries and modules that python developers themselves develop but also external developers create and maintain so the more people adopt the language the more powerful it gets because new libraries and so new functionalities get added to it and the second advantage is that it’s flexible now what does a flexible mean in this case what makes a language flexible it is easy to mold to your wishes so you are not limited or restricted by the language specifics like syntax or data types or some other constraints or even library functionalities you can extend python widely and as one of the results of this flexibility python also became a multi-purpose language meaning it is used for many different categories so let’s see what these categories are first you can use it to write web applications the popular libraries for that are django or more lightweight flask python became extremely popular because of the rise of data science machine learning and artificial intelligence industries and more and more libraries were created and are still being added for python for all these categories they are very popular and highly used libraries for data analysis and data visualization libraries for artificial intelligence projects for things like face recognition voice recognition and a bunch of very powerful and widely used machine learning libraries python is also often used for data collection like scraping the web creating web crawlers that are basically programs that collect data from internet which you can save and then process later again many different powerful libraries to do all of that and finally automation with python python has many great libraries to automate devops tasks for example starting from ci cd pipelines to cloud platforms and monitoring your infrastructure etc you can also write python scripts to do automated backups cleanups on the servers etc in addition to devops tasks you can also automate just general tasks with python like when working with excel sheets which is a common use case in many big companies or automating some tasks on your own laptop and there are also libraries for mobile development gaming desktop applications but these are less likely use cases for python because there are better alternatives for that so you see that the use cases for python are pretty vast and it actually spans several industries and it’s mostly concentrated around data analytics machine learning and automation areas and note that this isn’t the case for many other programming languages usually one programming language is good for just few things and you should use something else for other use cases so now you see how useful python knowledge could be and how it can help you in your job but also make you more valuable at your work and for your entire team i hope you are already excited to learn python so let’s get started as a first step we’re going to configure our local python development environment so the first thing we need is install python locally on our laptop so first we install or download python package for your specific operating system and then basically just click through the installer wizard to install python locally on your laptop and note that if you’re doing this on windows very important step in the installation process would be to check the ed python to path option basically that you see here because by default it is unchecked and you have to check mark it so that after the installation you’ll be able to execute python commands in your terminal now an interesting note here if you’re using mac os like i do is that by default on mac os there is python already installed so if i do python version and execute i see that python version 2.7 10 is installed and that is actually python that mac os the operating system itself is using however for our tutorial and generally when working with python we want to be using the newest version which is python 3. so we’re going to leave that default python installation alone we’re not going to use that or touched it and instead we’re going to be using the python version 3 that we just installed locally so now if i clean this up and we want to execute python version 3 commands we’re going to do python 3 instead and version and that will give us the version so that’s how we can differentiate between the already installed python and the newest version that we just installed so just be aware of that difference now that we have python available locally it’s time to download a code editor for python because we’re going to be writing files with python code so we need a proper editor for writing python code and actually the best python code editor available out there currently is pycharm which is from jetbrains so that’s what we’re going to be using throughout our tutorial so let’s go to pycharm it is an intelligent code editor which makes it much easier to write code so it makes you actually very productive when writing code and we will see why throughout the course as you can see there are two versions we have the community version and professional one community version is free and already has a lot of powerful features but the professional edition gives you additional very useful features especially if you’re creating web applications or scientific projects in python so with professional version additionally you will get scientific tools that you can use in scientific projects with python but also you get support for python web frameworks and database integration which can be of course very helpful if you’re developing web applications if you want to get the professional edition jetbrains actually provided me with a code for my channel to try it out for three months for free just use my code when you install it but for this demo community version is absolutely fine so i will go with this one and install it and just click download and once the pycharm installer is fully downloaded we can just click on it move it to the application and now i can actually use it locally so i’m just gonna open the application and we’re gonna take a quick tour around pychar it’s actually pretty simple to set it up and there you go we have our pycharm and we can now create a new project and let’s call it my python project and that’s it basically we don’t need to change anything else and here you see the location basically of where this application folder will be created you see pycharm projects folder got created in my users directory so this is basically very convenient because all my pycharm projects or my python projects that i create using pycharm will be created in one location and here you also see that python version 3 that we installed is automatically being used for this project which is exactly what we want and you see it says base interpreter and python interpreter is basically a program that knows how to execute python code it will know how to interpret or translate our python code into instructions that computer can understand so with this configuration we don’t have to change anything we’re gonna create our project so first of all i’m going to make all this a little bit bigger so that you can see the menu here on the side and the code a little bit better so in preferences editor font we’re going to set the size to 20. if i apply this right here you see that this code editor font basically got bigger and i also want to increase the size of this menu font here so in appearance i’m going to set it to maybe 18 and there you go so basically everything is bigger now so you can follow along and see exactly what i’m typing and also another note here if you want to configure your theme basically so if you don’t want it to be dark or maybe you want some other color scheme then you can select it here in appearance you have four themes available let’s actually try this one out and apply and there you go you have a different theme i actually prefer this one so let’s leave it at that so as you see we have a very simple project with one main main.pi file the extension is for python files which basically contains very simple code and we’re gonna basically just remove all of these and start from a clean python file state and in the next section we’re gonna dive right in and write our first simple python application we’re gonna start with the simplest example in python to basically learn python syntax and get started as simply as possible so first of all we’re gonna write a very simple application that just prints some output and in python when we want to print basically display results of what we wrote we use this syntax where we say print and here we can pass in basically whatever we want to display and now if i want to see whether this super simple application works i can run it or execute it with this triangle here and i have the output so the basically the output is displayed or printed right here and i see the output is 1. i can display some other values like 200 and run it and there you go let’s say we want to display some text basically whatever some sentence and again triangle and we have that output here right so again very simple example of writing python code that basically displays some information when we execute it one thing that i want to note here is you see that we write some code basically in this window right here so in our main.pi file and when we run it or execute it our code we see some display in this window so you may be wondering what is this window and why do we see some output right here the answer to that is that whenever you’re working with tools like pycharm which basically have all the functionality that you need to write your code and then execute your code you basically have everything in one place so whatever we write we can execute or run right away now without such tool how would we write code and how would we execute that code and this will help you understand what’s going on here and to show that i’m going to go back to my terminal and i’m going to create a new file and i’m going to call it test dot py we’re going to write the same code basically in this file you can do it in a file editor i’m just doing it directly in the command line and save it so now we have the same identical file as here but not inside our code editor right not inside this pycharm tool and we have python 3 available locally so now how do i actually execute a python file outside this pie chart i can do that using python 3 test dot p y and if i do that i get the same output in the command line so basically what you see right here this whole thing is integrated so basically all in one place where you can write your code the editor right here where you can navigate your files in your project so basically this is just a folder on your laptop and you can navigate the files here and you have the execution environment at the same time so you have to go to terminal and execute python 3 whatever you have everything in one place and tools that provide you with this type of environment for different programming languages for python it happens to be pycharm these are called ides which stand for integrated development environment integrated because you have everything in one place so you don’t need to use terminal but in addition to this integration you get more cool features which helps you in writing python code for example syntax highlighting highlighting errors or code suggestions autocomplete suggestions and we will see those cool features actually also throughout this course so basically just makes your life as a developer easier however it’s good to understand that connection between executing your files on the terminal when you don’t have such a tool versus executing and working on your application inside that tool awesome so let’s get back to our code editor a file where we write our code and till now we have done something really simple like print a text basically and print a number right and this leads to the first concept in programming languages which are data types so in python just like in any other programming language you have data types for text and numbers the text data types are called strings so everything within the double quotes is basically a string but note that in python you can also use single quotes for strings so double quotes or single quotes they both work the same and there’s actually no difference between them and for numbers we actually have different data types so for whole numbers like 2 20 but also 0 and negative numbers as well we have a data type called integer and that’s also how it’s called in most programming languages however you also have numbers for currency for example how much a product costs right so if you have an online shop you would have prices like this for example so these are basically numbers with precision this could also be for example when you’re shipping something you could have a weight of a package that is also not a whole number but has a precision so this type of numbers in python and many other programming languages are represented as float data type so again you have integers and float data types and if we execute that you basically see all of that printed as we wrote them now obviously printing values like numbers and text like this doesn’t make much sense unless we’re getting some useful information from our simple program right here right so let’s do something more useful with python now let’s clean all this up and let’s say we want to do some calculations very simple logic that basically calculates how many minutes there are in 20 days so we have 20 days which have 24 hours per day which have 60 minutes per hour so this line will give us basically calculation of minutes for 20 days and there you go that’s our number now this makes a little bit more sense because now we have a program that actually does something for us so basically as you see you can do any math operations on numbers in python and again in many other programming languages you can do plus minus division whatever just like you know it from basic math however i want to note right here something that many people think about programming and maybe are misinformed about which is if you’re doing web development or maybe devops automation with python and not something like data science or data analytics this is probably an example of the highest math knowledge that you need for programming in python because even though we’re going to use some calculation examples because they’re just good as examples to show you the basic concepts of python you do not really need any advanced or even intermediate knowledge of mathematics when programming because it’s really not about meth however what you need is logical thinking and we’re going to be doing some of that and see that as examples so just bear that in mind in case you are misinformed about that so back to our example we have this number that is displayed here as a result however maybe if we use this program we don’t remember or we don’t know what this number stands for if somebody else is using so we want to add some descriptive information about this number that says this is how many minutes there are in 20 days so basically we need a line that says 20 days are this many minutes and this should basically be exactly this calculation right here so how do we put this calculation basically right here in the middle so that we end up with this whole phrase displayed right here so how do we combine text and numbers basically or calculation of numbers and in programming languages again this is not specific to python we would do that using something called string concatenation and string concatenation is basically a fancy word for gluing together or combining multiple strings now how does the syntax for that look like we combine the strings using plus sign so apart from adding numbers obviously using plus plus is also used in programming for combining multiple strings so in our example we have three string values and we want to put them all together in one string or one sentence we have the first string 20 days r and then we have the second string minutes and in the middle the third string which will be the value of the calculation however if we just put a number here python interpreter tells us it’s not a string it’s a number so we need to turn it into a string other programming languages do that automatically in python we need to do that explicitly so we need to tell python take this number but not as a number but as a string and we do that using a syntax that looks exactly like that so basically we have a non-string value but we’re telling python we want it as a string because it needs to be printed out as a text basically so if i execute this line let’s see what happened and there you go we have our output just like we wrote it here but you see that there are no spaces around so basically 50 is just really glued together without any space around and how do we put spaces around these 50 basically add a space here add a space here now why does that work because this whole thing for python is a string again because we are putting it within these quotes so basically any character that you see on your keyboard right now if you put it between those quotes is interpreted by python as a string including this space character right so if we execute it again we have spaces around 50 and our sentence our phrase looks fine and if you’re thinking right now this is actually kind of annoying because first of all it looks ugly and also there’s a high chance you’re gonna forget it that is absolutely right so in python again specifically there is a way to do it in a more elegant way using a different syntax and the more elegant syntax for that let’s actually close this is print and let’s write that again and instead of having these plus we have curly braces and we write our number inside or whatever non-textual value and at the beginning right here basically before we start writing a string which starts with quotes we just write the letter f and you see the syntax highlighting as well basically sees that this is not part of the text this is non-text value and if i execute it i should see the same output from the second line and this is really a way cooler way to write this instead of using plus but this is something very common and also something that you would encounter in most programming languages so just important to know that this is a syntax for string concatenation as well so we can basically just remove it and use this syntax for our examples and also note that this syntax is actually a new addition to python so it only works if you have a latest python version in our project if you remember we actually configured and chose version 3.9 and that’s why it works for us if you use python 2 for example python version 2 this syntax is not going to work for you we can actually demonstrate it so i’m going to copy that line and i’m going to change our test.pi and now if i execute it using my python 3 you see it works fine if i do it with python which is version two point something let’s see what happens there you go syntax error invalid syntax because python version 2.7.10 so older version basically doesn’t recognize this syntax so just be aware of that so this syntax actually only works for python versions starting from 3.6 so everything below that every python version basically will not recognize this syntax as we see right here so again back to our code and now we just have a number here but what we actually want is the calculation for getting the correct result right so we want again 20 days in hours and then in minutes and if i execute it you see that the calculation was done and here we have the full complete sentence with the result in it and if you’re curious this f actually stands for format so this is basically formatting our text or our string in a correct way awesome so we have this line of code here that basically calculates for us how many minutes there are in 20 days let’s say we want to do the same for 35 days right what we can do is basically copy that line and replace the values for 20 with 35 and if i execute it i get the same calculation but for 35 days and we can do that basically multiple times for different values so let’s say we want it for 50 days and we want the same calculation for i don’t know let’s say 110 days doesn’t really matter and we have obviously different number of minutes for each of these values and now let’s say we wrote this program it’s ready and we’re using it and at some point we decide you know what i want this program to actually calculate how many seconds there are for these provided days instead of minutes so what we would need to do in that case is basically change the calculation in all those four lines so instead of minutes it should actually calculate number of seconds in a day right so we have the hours minutes and seconds and we would have to change the text as well here and we would need to do that for each one of those lines right so we would have it here like this and again if we need to modify this for hours or milliseconds or whatever we basically have to do these changes multiple times right even though if you actually look at that this is the same exact calculation for each line that doesn’t change right if you want seconds then this is the calculation that you need to do so how can we actually avoid repeating the same calculation and the same text in our code and the answer to that is variables so in programming languages we have variables that basically hold values that will repeat throughout your code that you can set once and use it in multiple different places so instead of basically repeating this calculation four times we basically do this calculation once like this and we basically save this value in a variable so that we can use it whenever we need right and the way that variables are defined in python is variable name let’s call it two seconds equals and whatever that value is that repeats itself and that we want to save into a variable now i want to make two notes here regarding the variables in python first of all in python defining or creating a variable and giving it a value like this syntax for that is actually very simple compared to other languages because you just have the variable name and the value in many programming languages you actually have to define here some kind of data type for that variable for example if it’s a number like float or integer or string etc in python you don’t have to define that you just have name of the variable simple as that the second one is the naming convention or standard for the variables so we have two words for example if we name our variable calculation to seconds right we have actually three words here so variables that are descriptive so basically they tell you what this value actually is about so they have multiple words in them you can separate them using these underlines again in different languages the naming for variables can be different in python this is actually one of the standard ways of defining variable with underscores which i find pretty nice and easy to read so we’re gonna use this syntax basically throughout the course it will be totally and absolutely okay if we wrote it like this or if we used capital letters instead but again this is probably the most readable form and this is what we’re going to use now here note that we can decide whatever name we want to give our variable but in python there are some specific words that have special meaning to python these are called reserved words so you can’t use these words as variable names and we will use some of these reserved words throughout the course so you will see some examples great so we have our variable defined here and this is the value that this variable gives us so how do we replace now these repeating values with this variable so we’re going to delete that and again inside we’re simply going to copy the name of the variable so let’s execute and as you see we have our value printed just fine and we’re going to do the same for all those values and again execute everything works just like before now you may be thinking if we change this to minutes we would have to change the variable in all these places so that’s our case we can basically just rename our variable something more generic so let’s say calculation to units and this could be now any unit that we want second meaning it doesn’t matter and this is exactly the advantage of variable because you can name it whatever you want which basically just describes what this variable is about and now you won’t have to change that again and we can also replace this one here accordingly since it’s a text we can call it a name of unit we can also call it unit doesn’t really matter we’re the ones deciding what that variable name is and once we have that variable we can now replace it here how do we do this because this is actually part of a text a string the same way we did right here we’re gonna delete that and create an expression create a syntax that basically tells python hey this is not a string this is a non-string value and you already know this could be either number or variable itself and so we’re going to use the curly braces and the name of the variable and just like that we have substituted these values here and if i execute it works perfectly fine and we can do that in all four lines and our code is still working and this syntax right here with this format at the beginning basically prevents us or avoids basically saves us from having a bunch of plus signs here and then space characters etc this all looks way elegant now and now if at some point we actually decide you know what i want this program to calculate how many hours there are in the given days instead of seconds and we want to change the program to do that we could basically just change the calculation here and instead of seconds we have hours and if i execute there you go we see the changes right away so this is why when you’re programming doesn’t matter in which language including python using variables will be probably some of the most frequent thing that you do because you always have values that are repeating themselves and you want to write clean code so you create variables and one of the best practices when creating and using variables is as we’re using actually here is to name your variables so that you later and also other programmers who are working with you understand what this variable actually does or what type of value it actually has because if you just look at 24 you would probably not know what this 24 is about right but with variable you actually know that this actually represents a number that is used for calculating units right it could also be more descriptive like units for days but generally another advantage of variable is to basically describe that value as well that you’re using in your code now another thing you probably also noticed is that even though we’re using variables here so that we don’t have to change those values in four different places a lot of these four lines are actually pretty similar the only difference in those four lines are actually these numbers right here everything else is exactly the same so what if instead we wanted to make this code cleaner and basically avoid this type of duplication in our code right so for example if we did this for 10 different values we would have the same line this long line basically 10 times right so how do we avoid this type of duplication so right here we actually avoided duplication for specific values right piece of string here a whole calculation here but how do we actually avoid duplicating a whole line right the whole piece of code basically which has multiple different stuff in it not just a value and we do that using functions so functions are basically blocks of code like this right or basically logic in code that does something it’s not just simply a value but actually does something more complex that is again used in order to avoid repeating the same logic or most of the same logic in your code so how do we create functions just like we created variables here we create functions and the way we do that is using following syntax right here let’s create our first function we start with def so we define a function just like we define a variable but for function we need this keyword basically called def and now we can give our function a name just like we gave name to our variable we can give our function a name and here we can use the same standards like for variable we can name the function something descriptive something that actually says what this function does and let’s call our function days to units and then we have the brackets and a column so this line basically defines a function it tells python hey whatever comes after this is actually going to be a block of code that is going to be referred to or is going to be named these two units and how do you write a function i’m just going to copy this one actually here and let’s give us some space and again this is very specific to python we need to indent here with spaces and i’m going to paste in what i copied inside these two lines basically tell python this piece of code or this line of code because we just have one line here belongs to a function called these two units and again we just have one line but this could be function with hundreds of lines right so i can write whatever i want the next line all good and then i can do some calculations and i can basically write whatever logic i want here and all these will belong to this function so now this logic is inside a function that is called these two units and we can actually get rid of this and test our function and here if you noticed we have this yellow line under the function name that’s actually a warning for our code style it says we need two blank lines before so pycharm has a built-in official style guide for python that tells you how to style your code or how to write your code correctly now why is code style important well just like you write code you need to read code from other developers or your own code to understand what the code is actually doing so it’s important that code is easily readable and this is just another example of how an editor like pycharm helps you to write code so to fix the warning we’re just going to add a new blank line before the function definition so now what happens if i execute this block of code i have the variables defined here that i’m using in the function and then we have these two print statements so what happens if i execute now and as you see in the output here there is no output right nothing actually got printed so what actually happened because we have those two print statements that we defined in the function but we don’t see anything in the output and the way it works is whenever you create a function or define a function like this you actually have to use that function right again this is a similar concept to variables we have created variables here and we’re using that variable in our code the same way we create a function and we need to use that function how do we use a function or in programming languages it’s called calling a function or executing a function and we do that using the name of the function like this and as you see in the suggestion as well using brackets like this so this syntax here basically is what we call calling the function that we defined right here or using that function so now if we execute it there you go you see that those two lines got executed and we have the results here so we’re creating variables and we’re using that here we’re creating a function and we’re using that function here and note the difference between using a variable and using a function python knows this is a function because we are providing these brackets at the end right that tells us we’re making a function call basically but as you see now we have these 20 days so this only works for 20 days right what about other values that we had what about 35 days and 100 days we haven’t de-duplicated that right we have just one case here so how do we use functions so that everything else except for these two values right here actually stay the same and we do that in programming by giving our functions some kind of input value which are also called parameters so instead of having this 20 basically here hard coded as we said here and here we provide that value of 20 or 35 or whatever that value is basically whenever we use the function so we are telling python use these days to units function with a value of 20 or use that function with a value of 35 and way we define this input parameter in functions is very simply by defining this parameter between those brackets right so this is where the input we as programmers define the input parameters so right here how do we define that using our already familiar variables so basically right here i’m going to define a variable and i’m going to call it whatever i want i’m going to call it days or number of days but i’m not assigning a value to that variable right like i did here because i want it to be assigned whenever i use the function so this basically tells python that a function these two units can be used using one input parameter which is called num of dates right number of days so now the last part which is remaining is replacing these values using this variable right and just like we do it in these two places where we’re also using variables defined here exactly the same way we’re gonna remove this and define a block for non-textual value and we’re gonna put our variable num updates here and also here so you see now that our function actually doesn’t have any fixed numbers in it instead we’re using variables we’re using two variables that are defined outside that function and we’re using one variable that is defined within that function right this variable actually belongs to that function and now as you see whenever we want to use that function we’re telling python hey call this function called days to units with a parameter an input basically of 35. so now if we execute it by the way we can also do it here you see 35 days are and the calculation was done here and hours and now if we go back to our previous example where we wanted to calculate these for four different values right for different number of days we can actually do the same so we had 20 then we had 50 and we had 110 right so this basically gives us exactly the same logic that we had previously but with different syntax right so you see the difference that instead of having this basically four times we have much cleaner syntax where we actually see what this logic is doing which is days to units and then we have the number of days that we pass or give our function as parameter and if i execute this you see that it was printed four times for all different values we can actually remove this line and now if we make some change in our function for example we change the name of this variable we want it to be hours instead of units we just do it once in one place and that’s basically it so whatever changes we make inside that function and that is actually the big advantage of using functions in code whatever change we make inside here it doesn’t affect how we use the function because for using the function we only need the name of that function and the input parameter now probably you’re wondering what happens if i do not give my function a value let’s delete those lines and let’s say we do not provide any value here and we try to execute or call our function without the parameter and let’s execute and you see that python interpreter is complaining because we have told python here is a function called these two units and whenever i want to use that or my colleague another programmer wants to use that function they have to provide an input value here right so now whenever python sees the usage of that function and there is no input parameter that we are giving that function it cannot execute that function right because basically this value is missing here right and that’s why we get an error which also says missing one required argument so as you see whenever we define a function with a parameter with input parameter we have to also provide that input parameter another thing that you may be also wondering is what if i want to provide multiple input parameters to functions how do i do that it’s actually very simple you can do that by simply defining here another input parameter separated by comma and let’s say we want to pass here something that we want to print out additionally like a custom message doesn’t really matter and the same way exactly the same way as the first one we can actually use it in here we can even create a new line and basically just print out that message right and note that if you are using a variable without stream so basically it’s just the variable itself we’re not using any text in that case you don’t need this format right so you can basically just print it out directly and now again we have told python i have this function and two input parameters are required so i also need to pass to input values whenever i use that function so now let me just pass in some custom message let’s say i’m happy about the calculation or i know i’m going to be happy so let’s say awesome and let’s do another calculation and this time i say looks good and if i execute it you see that i get awesome the first time and then for 35 i get looks good so you can basically define and provide as many input parameters as you want common practice and also what you will see in just normal code basically is just a handful of input parameters maybe one or two so it’s not actually overloaded with 10 parameters cool now that we know functions and variables why they’re used or why are they useful and how we use them there is one point that i want to mention which is variable scopes in functions what does it mean as i mentioned previously in this function we’re using multiple variables right we’re using two variables that are part of the input right that we provide when using a function and we’re using two variables that are defined outside the function right somewhere else in the code so variable scope basically means where is the variable that function uses defined and variable has a global scope for a function if it is defined outside the function like these two variables right here could be completely in a different file not even in the same file where the function is so these are global variables so all the functions that you have in your python code can use those global variables and then you have local variables local variables are variables that are created within that function right so these two variables are basically only available inside that function because it was created within that function so internal scope and global scope so that means that when we create another function let’s call it scope check because that’s what we’re going to do we want to test the scope in this function i can access the global variables like name of units but i cannot access the internal variables like number of days and let’s actually test that so i have num of units which is a global variable defined here outside the function and the second one i have a variable that is defined inside another function right so as i said internal and as you see right here we already get a red line underneath that says unresolved reference num of days so for this function basically that variable is not visible it’s not accessible it doesn’t exist basically at all and we can even test it out actually so again if we want to see the results we have to actually use that function like this run the function and if i execute it you see that we get an error that says name num of days is not defined right it doesn’t know that there is a function like that anywhere in code however it does recognize the global variable and that means that variables defined outside function itself global variables are accessible to all the functions and if you have variables defined inside the function then they’re only accessible for that specific function and not for other ones and that means actually that if num of days variable does not exist for scope check variable we can actually create a variable inside scope check with the same name and we would have basically no problem at all so this is not going to be a duplicate because this function doesn’t know about this variable the number of days here and scope check doesn’t know anything about variable num of days right here and if we want to use that function now we have to put provide the value let’s do 20 and if i execute there you go you have name of units and the 20 that we provided so global variable local variable defined here another interesting thing is that as i said inside the function body so to say so this is basically whatever is part of the function right in this indentation is called function body so we can create whatever logic we want inside that function body so whatever i can do in python generally i can do inside the function body so one of those things is actually creating variables right just like we created variables here we can create variables here like this let’s call it myvariable and variable inside function and we can print that out as well so now we have three types of variables that we are using in this function we have a global variable we have internal variable that is passed in as a parameter and we have internal variable again that is basically defined so the variable isn’t provided when we use the function but it’s basically just defined inside the variable and again if i execute this see hours num updates and variable inside function text printed out like this and obviously this is just for demonstration but we’re going to see more realistic examples of that in our projects so i’m going to clean this up and we can move on to the next concept so now let’s go back to the example where we calculate number of hours and we do that for four different values now if you want this application to be really useful for us or somebody else it doesn’t help that we have to fixate here just four different values right the application should be able to take any value that we basically fit it right so we should be able to provide any number of days and the program should calculate the number of hours in those days so what we need here is user input so when we give this application program to somebody else or use it ourselves it should allow some user input so how do we write a program that asks for and accepts a user input and then does something some kind of calculation some kind of other logic based on that user input accepting a user input from a python application is actually pretty easy let’s get rid of all of these lines first and we can do that by writing input and this will basically give a user a prompt to enter some input value now you probably already see from the syntax that this looks very much like using our days to units function right in this case with the parameter so input is actually a function that python provides us with so we didn’t have to write this input function right we wrote the days to units function but input function is available in python so that we can use it whenever we want and this parenthesis here tells python we want to call an input function and we’re calling it or using a function without a parameter so now we know that we can write functions ourselves for logic that we need but python has tons of functions that python developers already wrote and is part of python and we can use it in our code so that not everybody has to write their own input function logic and the code or the functions that python provides are again part of this python that we use in a project and obviously if you’re using the latest version of python you will get the latest code and latest functions that python basically provides so back to our function execution and let’s see what happens when we execute this program i’m going to run it and in the outputs you actually do not see anything other than my cursor is blinking here so it’s actually waiting for user input so i can actually type in something here so i can do 20 and enter and process finished with exit code so i was able to input something doesn’t really matter it could also be a string actually doesn’t really matter and program basically finishes so that’s the simplest usage of input however as you noticed here running this program and basically having this blank output here is a little bit confusing so if another user is using our program they will probably be wondering what’s happening here so what we can do is in input function we can provide a parameter that actually tells a user something right like enter a value for number of days or something similar so that it’s not just a blank prompt right so we can do that by passing in a parameter a string which is going to be our message so we can do a user enter a number of days and i will convert it to hours and here you see right now that the program wasn’t finished because we didn’t enter anything so this program finished line wasn’t output yet and that means the program is still running it is still waiting for our input and in pycharm in this ide if you want to terminate the program manually yourself you can click this stop button and as you see process finished so now we can run the program again and as you see here we already have a message that we’re displaying to the user so that they can enter the hours right and here we can provide our input 30 and there you go however this doesn’t look nice here we actually want the user to get a prompt on the next line how do we do that as part of a string we can actually add a new line or newline character basically and that in programming is actually represented by backslash n and you see a special highlighting for that one now let’s execute and you see that my cursor is on the next line now and again let’s provide a value enter and program ended so we have now a more user-friendly way of asking program user for their input instead of just showing an empty prompt and we’re getting user input now we’re not doing anything with that user input right that input basically just finishes the program and that’s it we’re not doing any calculation for that input so how do we use the value that user enters here when input function gets executed we do that and this is a very important concept by assigning whatever result this function usage gives us which is in this case user input assigning that result to a variable so right now it’s basically executed and it’s just wasted right it just disappears so instead we want to save that value that entered input value in a variable so that we can access it later and we do that by let’s call it user input variable equals so just like we created variables here with variable name and a value right or even an expression right if we did a calculation here that will be basically a whole expression whole calculation the same way we can use values that function execution gives us to assign it to a variable so now what i’m going to do is i’m just going to print the user input so that we can see what value that user input variable has so let’s execute again it asks for our input let’s put 20 and print user input gives us 20. so user input variable value basically becomes whatever we provide as an input now that’s a new concept and it could be a little bit confusing so let’s see another example with our own function what would happen if we assigned value of this to a variable we get a warning as you see here in the editor which is one of the great things about ides that it basically gives you warnings when something is not correct and the warning says function doesn’t return anything so basically if we want to have some value as a result of function execution we have to return some value in the function and how we do that instead of printing the value right away we can actually return that value using return keyword again you see special highlighting here just like here because return is a special word that python understands that you want to basically give back a value this value right here as a result of using the function right so you could have some logic here doing the calculation whatever and then as the last line you can return that calculated value and now the warning is gone because we’re actually returning something from the function and when we return value from a function again we can assign it to a variable so that we can use that value whatever function returned by referencing the variable and one of the usages will be basically just to print it just like we did before like this let’s delete it temporarily and test our program and there you go you see that this function got executed with input 20 this text this display text basically was put together in the function and was returned or was given back as a result and we saved that this whole string basically this whole sentence in a variable called myvar and when we print that myvar we see that value printed out here and again if we enter some other value we would get different text and again that is actually a very important concept of giving back some results from a function execution and you saw in our examples that you can have a function that doesn’t return a value just print something on maybe does something else or function that returns some value you can have both types so back to our example of user input so now hopefully it makes sense that input function returns whatever value the user entered as a result and we can save it in a variable and then access it later again let’s get rid of this line and now let’s actually do the calculation on the user input number of days how do we calculate number of days very simple by calling our function that actually does that so we’re going to call our function to calculate the number of hours for an input and the parameter that we passed in is going to be whatever the user provided so instead of basically hard coding a value here ourselves we give it a value that user provided instead so the num of days will be the user input and now again because this function returns the whole string it doesn’t print it remember it just returns it so when i execute this and i provide in some value that’s to 200 you see that i don’t have any output here because we didn’t print anything we basically just returned the value here we didn’t do anything with it so the last piece missing here is to display the text the string that function returns so we save that return value first let’s do calculated value so we save this thing in calculated value variable and finally we can print it and now let’s execute it and let’s see what happens i’m going to type in 10 10 days and let’s see what we get now and you see we have this weird value here as a result of the calculation so what exactly happened so this part of calculation basically which represents this number didn’t do a proper calculation and the reason for that is because the input value that we get with inputs function is always treated as a string and not a number so basically at this place here number of days inputs 10 here is actually treated as a text and not a number and where this weird result comes from is basically number 10 printed out 24 times so instead of doing the actual calculation 10 times 24 10 is printed 24 times and that’s what happens when this is interpreted as a string so how do we make python see that number see that input value as a number as an integer and not a text or not as a string and it’s actually pretty easy to do on the next line the user inputs again we saw right here it is a string so we have to make it into a number and we’re going to do that using int and user input and that process of turning a value from one data type into another is called casting if you remember we already saw an example of it when we turned a number into a string in the string concatenation example again from the syntax you should already know that this is a function call so we’re calling a function called int again that python itself provides us with because we didn’t write that function and we’re passing in one parameter which is a string and we should get an integer from that string as a result and we can save that number into a variable and let’s call it user input number and now we have 10 as a number instead of as a string and instead of passing in that string user input we can now give our function number that it expects let’s save it and execute let’s put in 10 and there you go now the calculation is correct what i want to show you now is how this user input actually works without a code editor like pycharm so i’m gonna copy all this code and let’s go back to our terminal and in our test dot pi i’m going to paste in our code and save and let’s now actually see how the user input works when we execute it in a simple terminal window and as you see here we have the message first and the prompt is right here so we can enter a value let’s do 25 enter and we have a result 25 days are 600 hours great so our program is working it is converting the number of days to number of hours and accepts a user input now what happens if a user enters an invalid value here so for example instead of a positive value for number of days maybe they enter a negative value like -10 for example and obviously that input value doesn’t make any sense but we are still calculating and giving a value right and this is another important concept in programming generally that when we allow users to give our program some input value we also want to restrict them and basically validate that what they provided as input is a valid value for our program specifically one that it makes sense like in our case -10 program still does a calculation but it doesn’t really make sense and second it doesn’t crash our program right so now let’s see what happens if we enter some text here you see that the calculation didn’t happen because we basically crashed the program application using that invalid user input does make sense or an input that crashes our application because the calculation isn’t even possible and we want to avoid users basically either providing a nonsense value or a value that will crash our application so we need to validate user input and this is again important concept in program because whenever you allow user input you always have to validate it so in this part we’re going to learn concept called conditionals and we’re going to learn this concept with an example of validating a user input so where are we going to do the user input validation we can do it in our function right before we actually do the calculation we can first validate is it a positive number and not a negative one so user gives us their input we convert it to a number and then we pass that number to our function so negative 10 positive 10 that is a number basically will be passed on to our function and right here we can check whether this variable value here is a negative number or not how do we do that we do that using if else conditional statements so very simple and intuitive to understand we say if number of days is greater than 0 means it is a positive number then we want to do the calculation and return all of this but you see that we have a red line here so basically whenever we use if condition we have to have a proper indentation so all of this line basically goes indented for this line kind of the same way as we indented the whole function body inside the function whatever logic and whatever code is right here indented below the if condition will be executed if number of days is really greater than zero so let’s try that again i’m going to execute it let’s put a positive 10 you see 10 days are 240 hours got calculated now let’s put -10 as an input and you see none basically no output for us because this line didn’t actually get executed for -10 input value now what if we want to tell a user hey this was an invalid value and that’s why we didn’t do the calculation instead of just showing none we can do that by returning this feedback message or error message whenever this is not true so whenever number of days is not greater than zero we want to return something else right another message and we can do that using else and the same way as for if we have the indentation and whatever we write here will be executed if number of days is not greater than zero so here we are gonna return you entered a negative value so no conversion for you and here it’s time for another special term in programming that greater than sign is called a comparison operator and we have three of them we have greater than less than and equals and these are called comparison operators because they are used in an operation to compare two values and before in this course we learned arithmetic operations like plus minus divide multiply so again fancy words for simple concepts but these are the official terms for these so now if someone mentions them you will know what they’re talking about so now let’s execute the application and let’s provide -10 and you see that this line was printed as a feedback to the user so let’s go through the flow again user gives us their input in this case -10 we convert it to integer so now it’s -10 integer and we pass it on to our days to units function and these two units function basically has this if else statement that’s how it’s called in programming and our if else statement validates or checks whether this input is greater than zero if it is then the function will return this as a result so basically the calculation with a proper message else so basically if this is not the case then it will return basically just a feedback message for the user and note that else doesn’t have such a check here we don’t check num of days is less than zero and the reason for that is because it doesn’t check for less than zero because it basically just decides if this is not true else or in that case just do this so we don’t need additional check here now this segment right here where we’re doing the check is called a conditional so basically we’re providing our program a condition if this condition is correct then do something otherwise do something else and that conditional can be true or false if we enter 10 then this conditional will be true because it’s greater than 0 if we enter -10 then this conditional will be negative it’s not greater than 0 and those true and false values in programming actually are represented by its own data type which is called boolean and in order to show it to you that this conditional either gives true or false what i’m going to do is i’m going to print this conditional right before i do the check so for a positive number input this should print true and if it’s negative so it’s not greater than 0 this should print false so let’s test it out first i’m going to provide positive 10 and right here you see true because this condition is indeed true and note that this is not a string that’s why we don’t need the quotes here so we can basically just put in the whole expression in a print function and now let’s do the same with negative 10 and you see false and as i said true and false values belong to its own data type in programming which is called a boolean and again we can demonstrate that instead of printing it out we can save it into a variable let’s call it conditional check and in python there is a function called type which checks or prints out basically a type data type of a variable or a single value so if we pass it so this will give us data type of conditional check and obviously if you want to see that result we need to print it so print the whole thing so it doesn’t matter what we pass in this point and right here you see class boolean so this conditional check here which has a value of true or false is of type boolean now there are two things that i want to note here the first one is that you see that i am calling a function here which is type and then whatever that function type returns which is basically this output here we are printing it so we have two function calls that are basically nested and that is absolutely fine you can nest function calls another example of doing this nested function called would be for example right here instead of assigning these to a variable and then passing it here we can actually save us that step and in the days to units function call pass it as a value so this is a perfectly valid syntax and you can do that you can nest in the function calls and you would not need this additional step and you can do that as many times as you want it just looks cleaner when you have that syntax a little bit separated and not have two three four function calls nested so that’s one thing and another thing is we just saw a class boolean type here and let’s actually see the same output for string and number so just for the demonstration let’s actually see the type of string and integer let’s get rid of this for a second because we just want to test so we’re going to print the type of a string which says this should be a string type and execute and you see class string and now let’s provide an integer you see class int and let’s provide a float and there you go we have float so this is a very handy way of checking the type and we’re going to need that actually in a later example so back to our application and one note about booleans and conditionals is that you’re going to be using a lot of those in programming because they’re really the major or the core part of writing any kind of logic in programming so you’re going to need if else conditions and statements and booleans in your application so it is a very core concept and we’re going to be using a lot of them in our coming examples so let’s get rid of this code right here and one note before we move on here is that the negative numbers are not being calculated because of this condition now what about zero let’s actually try that out so i’m gonna enter zero which is actually also valued that doesn’t make sense because zero days input obviously will give zero of any units so enter and right here you see a feedback to user that says you entered a negative value so no conversion for you and the reason for that is because this condition here number of days checks greater than zero which means that negative numbers and zero will not match this condition so they will basically give you this feedback but our message says you entered a negative value right when we entered zero what if we wanted to have a specific message for a user if they enter zero and a specific one if they enter negative value right we want to differentiate between those two how can we do that in the if else statement in programming we can have multiple conditionals so basically we can have multiple ifs so how do we do that first we check number of days is greater than zero okay great now we want to check whether number of days is equal to zero and we can do that using another if here and in python the syntax for that is el if which basically is a combination of else and if so if this is not true then we want to check another condition number of days equals 0. now you know the equation sign generally is this one right here however when we’re checking whether something equals to something else in programming that equation check is represented with two equal signs and the reason is because one equal sign is already used to represent assigning a value to a variable so not to confuse those two actions in programming we have two equation signs when we want to check whether something equals a certain value and just like here we execute some logic whenever this condition is true so in our case we want to tell the user you entered a zero please enter a valid positive number so now again to go through this logic flow if the input value is a positive number then function will return the calculation and the message if it’s not a positive number then we will check additionally whether it’s zero if it’s not zero then this is a last condition basically then we know that it has to be a negative number right so let’s test this out let’s enter a positive number there you go let’s enter zero you entered zero please enter a valley positive number and let’s enter negative one and everything works perfectly note that you can have multiple alif’s between if and else statements and again note that el if has a condition just like if statement else does not have any condition so this is like the fallback so if everything previously stated all the previous conditions did not match so they were all false basically then this is the logic that will get executed in that case great so we have validated input value for users and we may feel pretty good about our program because it doesn’t calculate anything for values that don’t make any sense however we still have a problem what happens if a user enters a text instead of a number so basically anything that is not a number value doesn’t really matter basically some text if i enter you see that our program actually crashed and this is actually a user input that we want to protect our programs from because we don’t want to allow users to blow up our application right so let’s see what happened it actually says that we provided an invalid literal literal basically means the text itself or a number so basically a value that we entered for int function that’s the problem so this function call basically just blew up because in function expects a value which is a string representation of a number so basically ind expects something like this or something like this it doesn’t expect my text or some text so our application crashed on some text input now let’s see what happens if i provide a number but a float number instead of integer let’s enter 19.99 and enter and you see the same error this function basically returns an error because it cannot convert float into integer as well so we have a problem here that whenever user enters anything which is not an integer our program will blow up so how do we avoid that so basically before the int function gets executed with an invalid value we need to validate this whole thing and stop our program before that happens so we need the validation before int gets executed and we can do that right here right so before that line gets executed we’re gonna do a validation and one way we can do that is using our familiar if else statement so we can say if user input is digit so again from the syntax you know this is calling a function but note that instead of calling the function like this so basically just stand alone we have the syntax where we have the variable dot and then the function name so instead of passing this as a parameter right here in the function brackets we are passing it as a parameter again but using this syntax right so each digit function will execute for user input as a parameter and again in if we have conditions so this will be either true or false it’s a boolean and if user input is digit it’s a number basically so basically this will filter out input values that are text so basically they’re not numbers and if the input is digit then we want to execute this line and also the rest of our application like this and if it’s not true so if the user input is not a digit we don’t want to execute anything in our application we want to stop the execution and want to tell the user this was an invalid input value i’m not doing anything with my program so that it doesn’t crash so else if not digit we are telling the user your input is not a number don’t ruin my program so now let’s actually test it so i’m going to execute and write some text and there you go so user input is digit was evaluated to false so none of these got executed instead the else block was executed and it printed a message for our user so we basically avoided our application to crash with this check and if we try a proper number it works and if we enter 0 for example the application will get executed and we will get our message from here so our application is more or less protected and we’re not allowing for a invalid input number you say not a valid number now we know that in programming there are different types of numbers we have float numbers as well so let’s actually see what ease digit function really checks so let’s actually try to provide a float number instead of integer which is not a proper valid input for our program so i’m going to type in 19.99 and you see that each digit is false for a float number so we got the same your input is not a valid number output for float number as well which is perfect it’s exactly what we need and now let’s actually try to enter a negative number and let’s see if each digit function returns true or false i’m going to enter and you see that else block got executed because is digit was false for a negative number so basically this function filters out a lot of the bad input for us to protect our application from bad user input and that also means that we don’t need a check for negative values anymore and by the way in python you can actually have if statement without an else at the end this will work perfectly fine and this could be our application however note that in programming we don’t put this type of logic directly like this basically outside a function as a common and best practice we encapsulate most of the logic basically in functions so as a cleanup for our code we can take all this and put it into a function so right here i’m going to create a function and let’s call it validate and execute or something like this and all the logic that i copied will be just simply pasted in that function like this so now we have the logic nicely encapsulated in its own function but as you know when we create a function we have to call that function otherwise nothing happens so we’re gonna call it right here we don’t have parameters and we don’t have to provide a user input because user input is a global variable so our function has access to it let’s actually test it out and it works and let’s provide some bad input and it works too so that’s actually a proper way of writing code having every piece of logic in its own function with a proper description for the function now as a next step i want to show you also a concept or something that you will encounter very often in code which is nested if else statements and i’m going to show that example by cleaning up our program a little bit so as you see here we’re doing validation in two different places so we’re validating user input here but also inside these two units function itself so what we can do is we can put all the validation in one place in this validate and execute function and basically have all the validate logic in here and let the days to units function just do the calculation and not the validation and this way our functions and code will be a little bit cleaner and more logically built so after we validate that user input is digit we convert it into an integer so right here we have an integer value of the user input so we can actually check whether that integer value is greater than zero or equal to zero and we can do that right here without passing it on to the days to units function and just like this if conditional we’re gonna do user input number greater than zero if that’s the case we want the calculation to happen so both of these lines will get executed only if user input number is greater than zero and else in our case if it’s exactly zero we want to print a message to user you entered zero and remember we’ve got the negative numbers already covered using this condition here so that’s the one remaining i’m just going to copy that and paste it right here variable is called user input number so we’ll fix that and we’re going to print out that message so that means we don’t need any validation right here we can simply do the calculation so to go through this logical flow of if else or nested e-files statements we have the first if right here also note that indentations for these if else so basically they are on the same line here same position and the nested if else or in our case alif they’re also in the same position so again first that’s the big validation the first one is is the user input digit in the first place if not we basically shut down the program we print out a message to the user and that’s it if it is a digit then we need additional validation is that digit a positive number or is it a zero so we do that additional validation using a nested ifall statement and basically this line gets executed only if it is a valid number and if it’s a positive number and because of that we don’t need any additional validation once the these two units function gets cold and you probably already think and notice that nested if else statements are not the most beautiful thing in the world they are pretty ugly actually and especially we have multiple of them or multiple else ifs in between the function may actually end up looking pretty bad so it’s not recommended to have multiple levels of these nested if else statements in your code to basically just keep it clean but as i said you will encounter it a lot in programs in application code because sometimes you just have to write it like this thing i want to show you here is something called a try accept in python so right here as you see we’re validating user input right and then we’re executing this part of code only if that condition is true what if we had logic here where there were multiple places where something could go wrong let’s say a function execution could basically just blow up because of a wrong input or even as an example maybe this is digit doesn’t actually cover all the use cases so maybe there is a value that user can input that will still blow up our program so instead of checking each such possible scenario using if statements and then doing the actual calculation once all those things have been validated what we can do instead is basically tell python something like try executing this part of code here and if something goes wrong so if any line any function call or any logic execution fails we want to catch that error and we want to control what happens with that error ourselves programmatically and then catch logic will be accept and we’re going to specify what type of value we want to catch basically using this block and the name of that error type is actually what we saw in the output when we provided some text and a float which is value error so that’s the error that we want to catch basically so again we tell python you know what try to execute this block of code here and if one of those lines in that code results into a value error then instead of just crashing the program basically catch that error and print out a friendly message to a user so let’s actually try this out and note that try doesn’t have any validation like if statement so when i entered some text here int function will actually be called with some text and it will result in a value error and this block will then handle that error so i’m going to enter and and you see that your input is not a valid number message got printed and the same will work for a float number that also doesn’t convert to integer and for a proper integer value it will work fine and again difference between if else statement and using try except is that you can cover multiple such errors with this whole try except block right so you don’t have to do the validation specifically and that is especially useful for cases where you can’t really validate something using if condition right if there is a chance that you might miss something in that condition check so basically you just say you know what just try to execute with whatever value and if error happens then i still got it covered and an obvious difference between this if else is that here nothing actually crashes the program the program will still work is just a nonsense value with zero days right and as you see here we have specified an error type but with try except what can also do is you can basically say you know what i want to cover any type of air i don’t care if it’s value air or some other type of air let me handle any type of air in this case you can basically just leave it without a specific type you get a warning though that it’s too general however this would work and you will be covering all the air cases with it but we can go back to our value error and know that in many programming languages this is actually called a try catch so accept is actually pretty specific for python i personally think try catch makes more sense because you are catching any error that may happen right here and then basically handling it in the catch block so if you happen to hear or see try catch in other programming languages note that this is the same thing as try except in python one thing that we’re missing because we converted that if statement into try except is now we need to validate the negative numbers again because negative numbers will not cause an error in our application so they’re not covered by this except block here so let’s add back our previous else block and again if neither of these are true it means automatically would mean that it is a negative number so let’s print that message for a user enter negative number no conversion for you so now we got all the cases covered again so let’s try that out -10 and there you go now there is one minor problem with our application and that is we can only use it once so basically whenever we type in a value it either calculates it or gives us a message that we provided an invalid value then the program basically exits so if we want to do a calculation for another value then we have to restart the application provided value and then do the same so that’s not very convenient if we want to use that program to basically calculate a number of hours for many different values so basically we want to keep fitting it some different values for calculation because we don’t want to restart the application over and over again so how can we actually make the program continue after it’s calculated the first value so we want the program to basically just keep running and accepting our values so how do we do that and we can implement the logic using something called while loop concept of loops in programming is basically you do the same thing so the same logic gets executed multiple times in a loop and how many times that logic gets executed is basically defined in the condition of that loop and the condition could be it should run 10 times or condition could also be it should run until some specific event happens in the application and conditions you already know from if else statement conditions are basically logic that gives you either true or false so condition is checking some logic and then giving you a result which is either true or false so now the question is how many times do we want this application to run in our case let’s say we want to run indefinitely right until we actually stop it from here until we kill the program so it means the condition for that should always be true and for our application we’re going to use a while loop which is one type of a loop and very simple syntax while and while just like if actually takes a condition this is going to be the condition for the loop so basically we want to tell the while loop how many times it should run the logic coming after it and again you know our familiar indentation these two lines should execute in a loop over and over again with some condition right here so how many times do we want the program to execute in our specific case well we want the program to run indefinitely until we actually stop it from here right from our editor so that means that condition of the loop that decides whether the next lines should get executed or not in our case should always be true because if it’s false then the loop will stop right no execution anymore so how can we make sure it’s always true we just write true right here and you remember i told you that true and false in programming languages have their own data types well they are also reserved words even though this is just text representation basically you see the highlighting here just like for these other words because python knows this is a boolean value of true and note that again specifically for python we actually write true with capital t unlike in other programming languages so this will basically be just a string so python doesn’t know what to do with it but it recognizes true width capital t so we’re telling our loop our while loop the condition is always true so basically run these two lines indefinitely because the condition will never change it’s always going to be true and the syntax is probably already familiar to you we have the keyword just like if or try we can actually compare the syntax to the if statement so we have the while keyword here then we have the condition so this is the same type of condition as this one right here it’s just that with us is basically fixed true value here it could be true or it could be false based on the condition and then we have the colon and then we have the indentation for the next lines so all of these belong to the while loop so that’s basically it we can now execute the application and see that our program runs indefinitely so this is the first one let’s say we enter 10 awesome we have a result and then we have again the next execution where it’s asking for our input again and we can do -10 now it’s telling us we provide a negative value but we can enter the value again let’s enter some invalid value that should be handled by this value error block execute it’s not a valid number and application basically continues so again as you see if you have an application that should continue running and basically get user input over and over again you don’t want that application to be crashed at some point by some bad input you want to catch and handle every type of input so that your application continues to run and if we want to stop it we can basically just shut it off here and process finished now we can do one optimization in our program and this would be to allow users themselves to stop the application using some specific input value so for example when they type in exit for example the application should stop only for that specific word so it shouldn’t run anymore so how can we do that so basically instead of having a condition that is always true we want a condition that says if the user did not input word exit then continue running the program if user entered exit then basically just stop it right so we need to change our condition right here so here we want user input is not exit right so user input is not exit now we didn’t learn how to check for not equals something right we have check for equality so we check whether input number equals zero or if it’s greater than or smaller than however we didn’t learn how to check for not equals not equals in programming and this is not specific for python is expressed like this so instead of two equation signs we have an exclamation mark and equals and if we want to compare it to a string obviously we type that string in our case it’s exit so basically this condition tells our while loop while user input is not exit continue running the program so while this is true basically just keep moving on but if user enters exit this will not be true anymore it will be false so loop will basically break and application will end now you see that we have a warning on this user input that we’re using here and if i hover over it you see a message that says name user input can be undefined so it’s not always undefined but it can be and here i want to mention again that pycharm because it’s an intelligent editor can give you actually this warning when otherwise in a simple or normal code editor you probably wouldn’t get such a warning so again it helps you in avoiding some of the mistakes that you might accidentally make when writing code so basically it detects the errors or possible errors for you and tells you to fix it so again this kind of intelligent warnings and error messages can be a lot of help when programming an application and now let’s fix that warning so what’s that all about the problem is on the very very first run of this while loop user input variable itself will not exist why because we’re creating that user input variable on this line first so our application will basically complain because when our while loop runs for the first time it will not be able to find user input variable let’s actually try that and as you see user input is not defined so we need to create that user input variable before the first execution of the loop so right here we’re going to create user input so we’re going to create this user input variable before the while loops first run and it doesn’t really matter what the value of that user input variable will be because what matters is the variable exists so the value is basically just empty and as long as it’s not exit the loop will start running and our application will get executed so again to go through the flow of this we’re creating a user input variable then we’re making sure it’s not exit if it’s not this line will get executed so we get the input from the user that’s going to be our first input and then we call validate and execute function that basically does all the checks and execution so that’s going to be the first run of that loop on the second run of the loop the condition will get re-evaluated so now the user input is what the user provided so again python will check is the user input exit no cool let’s execute the program again user will have to enter another value and then that value will get re-evaluated so note that after each time that this block of code has run and executed every single value that user will give as an input will be evaluated over and over again in that condition and while user input is something else then exit it will run the program if it is exit then the loop will break so let’s actually test that so this is our first message and our first input let’s do 10 it got calculated let’s do minus again calculate it and we can do that over and over and over again and now let’s actually enter exit and let’s see what happens and as you see a process finished with exit code so our application actually stopped because this condition was not true anymore it was false because we entered exit so that’s how we can allow users to finish the application and two takeaways here one is a conditional in a loop and the second one is a negative equals check for values great so now we have our application that basically allows inputs multiple times and can be terminated with exit input now what if i wanted to calculate number of hours for several days but i didn’t want to basically just pass it on one after another because that’s just too much effort for me so let’s say i wanted to give it 10 different values but i don’t want to type it in 10 times right i want that application to basically do the whole calculation for all those 10 values but i just want to enter that list once instead of entering each value separately so in this part we’re going to learn another data type in python called list so till now we have learned several data types like strings for example as well as integers and float numbers and boolean true or false and list is just another data type and the syntax for list is using square brackets and inside the square brackets we have a list of elements and those elements can again be either strings numbers or boolean values in our case we want to provide our application with a list of number of days right so we’re going to have a list of integers like this and you can have as many values inside the list as you want and these are going to be comma separated and the syntax will look like this but again as i said you can have a list of strings list of booleans etc so as i mentioned we want to let user basically provide inputs as a list instead of those individual values one at a time so i’m going to copy this let’s clean this up and let’s actually see what happens if i just input that list as a value right here and enter you see program doesn’t recognize that as a valid number obviously because we have the check and causes a value error that’s why we get your input is not a valid number don’t ruin my program message right here so we want to change that and make our program actually accept that as a valid input so how do we actually implement it and let’s go through this logic theoretically first before we start implementing it what we need here is that we want to read this list and we want to do validation and execution for each value one at a time so that means that validate and execute function needs to be called for each value in that list right so basically this function for all this logic needs to be executed for each element now how do we get the individual elements of the list so you remember the definition of a loop loop is basically executing same function with the same logic multiple times and the number of times basically depends on the condition right here we have a condition for while loop and the condition for executing the same logic for each of those elements is going to be the number of elements in that list right so we want to execute the logic as many times as we have elements in the list and for that we have another type of loop called for loop and basically we want to execute validate and execute function using a for loop the syntax for for loop is a little bit different first of all we have four keyword just like for while then we have the element is a variable so we can call that number of days so this variable basically represents each of those elements in the list and then we have in which is again a keyword of python so for in basically puts together the for loop logic in python so python knows what we are trying to execute and finally we need the list that we are executing this loop on and our list is our user input and that’s our for loop however again you remember the indentation the logic that for loop executes needs to be indented so it should belong to for loop so now we can read that for loop statement as follows for each element which we call we decide to call number of days in a list called user input we want to execute this logic exactly what i said before so for each element in this user input list we want to execute validate and execute function we don’t have a condition written here like we did in while loop or if statement so the condition is basically implicit right the condition says however many elements there are in this list that many times that function or that block of code here will get executed so if i provide five elements you will be executed five times if i provide 10 elements it will be executed 10 times and that’s exactly what we want however there are still a couple of things we need to do for this application to work properly first of all validate and execute function still uses user input right here so instead we want it to use the individual values of the user input because now it’s going to be a list and not a number so this element we can actually call it num of days element this value should be used here instead right so we’re going to use that element instead of the whole user input list and paste it here so that fixes the first problem and the second one is as you know user input is always a string so even if we provide a list of these it is still going to be considered as a string so we need something similar to this right here so the list of numbers that are provided as input needs to be converted in at least in python and we can actually do that in a convenient way using user input dot split and split is a function that will take user input as a parameter and will give us a list data type so split function basically will return a list of all those input values and again note the syntax of executing the split function we’re not just calling a split function like this with user input as parameter instead we are basically calling it on user input and i’m going to explain more about this type of functions in python later but for now let’s actually execute this application and see what happens so first of all how am i going to provide a list to this application so that userinput.split can actually convert it into a proper list in python and the way i should provide the values are list of values with spaces between them so basically like that so why spaces how come it’s not a comma or something else the reason is because split function by default splits that provided list on spaces and then creates a list value out of them so that’s the default behavior of split however we can override that behavior and we can decide you know what we want the input to be a list of numbers that are comma separated instead of space separated so what we can do is right here we can do split on a comma so that’s what our split function here will do and now if i re-execute it and i can do commas now 40 55. so that’s going to be user input and split with comma should convert it into a list value in python so let’s execute it and as you see it worked fine we have a calculation for each of those values now let’s actually play around with this and let’s say we provide a list with some values and somewhere in between we decide to add a text and then maybe a float so let’s see what happens now and you see that for those two valid numbers the calculation was done properly and for the other two basically the validation kicked in and it says that these are invalid numbers however again our application ran without any problems and we can even provide another input so now let’s actually do 20 maybe a boolean even and a negative number execute and you see that for 20 the number of hours got calculated true is obviously not a valid number and minus 100 is a negative number so everything works perfect validations in place and we can provide a list here now and as a final optimization we can actually change this message here that says hey user enter number of days as a comma separated list and i will convert it to hours so now we can provide either just one value and it works fine or we can provide multiple values as a list and again if we want to see how that list actually looks like and check the type that it has in python let’s actually print it so first i’m gonna print type of user input called split and then i’m just gonna print that list itself so let’s execute and let’s provide some values and here you see this is the class list so basically the data type list and that’s how our list looks like so we have these square brackets here and each element inside as a string because we have the quotes here and later our application then transforms it or tries to transform it into an integer and you also see there are some additional spaces here because that’s how we entered the values so basically the split splits the values on comma so this space also becomes part of that element so to fix that leading space in each value we can basically just add a space here so it will split on comma and space and let’s test it out and there you go we have our values without the space before them so you saw an example of when we actually need to use list data types in this example we wanted to allow users to basically just input multiple values at once as a list but obviously this is just one of the use cases for a list and one of the specific examples because throughout the application you can create lists and you can use the elements of that list in another function so you can use it for multiple use cases and just to show you some basic syntax of how to create lists within your code inside your application so how to initiate it and then how to use that list i will show you the examples here so basically to create a list in your code you would use that syntax that i showed you earlier with square brackets and inside that you would have list of elements and this could be strings so it could be for example names of month let’s say like this and then we would have to assign it to a variable right again just like we did for strings or integers or other data types so we can call it my list and this will give us a list with three string values inside and once you have created a list you can then use it to read the values from the list right so basically to get the individual values elements out of that list so for example if we wanted to print out the first element of my list then we would access that using my list and then following syntax with again square brackets and then index number of the element which is starting from zero so this is the first element with index zero this is the element with index one index two and so on right so it could be confusing because it starts with zero not with one but that’s how the specific element of a list can be accessed right so if i wanted the march value here the third element then i would just type in index two and this is a syntax of getting elements from a list if i just want specific values and not each element one by one as we had in this example right so one way to use a list is to basically loop through it and get one element at a time and that’s why we don’t need to use index here because it gives us elements one after another or maybe we don’t want all the elements or to do something for each element we just want specific values from the list for different use cases in this case we can access them individually like this and in addition to accessing the values from a list or basically reading the values from release we can also add values to a list and we can do that by typing my list and then on the my list we’re going to do dot and use the append function right so append will basically take the next element or another value basically and add it to the list of elements already in the list right so let’s say we want to add the next month and now if i print my list we should actually see this here with april as a fourth element right so let’s execute and there you go so first we have march here printed out which is the third element right index two and then we have my list append that adds fourth month name into the list so after append this is how my list will look like and now again we can access the specific element for example if we wanted to access the newly edit element on index three so that’s going to be the fourth element and there you go we have the new element printed out and also an interesting note is what happens if we use an index here which is too high so basically pointing an element that doesn’t exist right so instead of three let’s say we have four here so this will point to the fifth element and since we only have four elements let’s actually see what’s gonna happen so i’m gonna execute this and there you go you see an error index error that says a list index out of range so every time you access or you try to access an element at an index that doesn’t exist you will get this list index out of range error and this is actually something that may happen pretty often when working with lists if you’re accessing the values like this so this is how you work with lists how you create them and access values in them as well as add some values however note that most of the time if you are using lists you’re going to be using them in a for loop because most of the time you would want to do something specific for each element in the list so this basically should give you an idea of syntax of lists and how to use them generally and also how to use them in combination with for loops here i want to take a few seconds to thank jetbrains the creators of the awesome pycharm and intellij editors for sponsoring this complete course besides all the great existing products they have they recently introduced space which is an all-in-one team collaboration platform covering software development project and team management and the great thing about space is that every single tool you would need in a company to collaborate and work together in a team is in one space so you have tools for chats blogs planning and creating tasks meetings but also software development tools like version control ci cd package repositories and much more so all these in one platform and in terms of productivity the great thing is you get all the notifications in one place like code review updates newly created issues new blog posts etc you get all of these in chats where you can react directly in place or add them to your to-do list automatically so i think the main value of space isn’t that it has all these tools but rather the fact that it integrates them in such an intelligent way that it improves the team communication and productivity overall now let’s go back to coding now at this point here i want to mention a pretty minor and simple detail but something that is also very important and useful in programming and that is comments so how do we write comments in python and why do we need or in which cases are comments actually useful one usage of comments is basically to give yourself some notes on your own code so basically if your code gets a little bit complicated and it’s not really clear what the logic or the function body is doing it could be because of bad programming but also because the function logic is just a little too complicated so you want to add some textual notes to that code so that you understand what’s going on there even when you look at that code days or maybe weeks after you wrote it so for example right here we may want to add some notes about what this part here is doing and comments in python are written with this character so for example i want to add a note here we want to do conversion only for positive integers and that’s basically my note that summarizes all that logic right here and it is not only useful for myself in case i forget what this complex logic actually does but also for your team members so if you’re working in a team and your code gets really complex and it’s difficult to keep an overview of different functions and variables and what all these things do you can basically add these comments as notes to your team members so they can also understand what you thought or what kind of logic actually you were thinking about when writing this code so comments is a way of communicating your thoughts and your logic on your code so that’s one use case for using comments and the second use case if you have a piece of code that you do not want to delete because it has some logic or it has some example that you want to keep as a reference but you don’t want that code to be executed so basically you can comment out code so that it still stays there but doesn’t get executed and the way to do that is just basically having this character before the line and also note the color of the comment in the editor is gray so it’s immediately visible that these are the comments and now these two lines will not get executed by the program they will be ignored but they are for your own reference in case you want to keep it there for example this could happen if you are unsure about the change and you want to delete that whole code from your application because you might actually need that eventually so you’re not sure about it so temporary comment the code before you permanently delete that so these are some of the use cases of comments now if you have multiple lines of code that you want to comment out or maybe hold text that you wrote as a note so for example you want to comment out all these four lines here obviously you don’t want to do this in front of every line so for multi-line comments you can actually use the following syntax which is three quotes at the beginning and at the end and again you see the highlighting is different here which basically is highlighting of a string however it is ignored by the program and it will not be executed as a best practice you shouldn’t have too many comments in your code because it will just add additional clutter and your code will look basically unclean so you should use them only when needed in this part i’m going to show you another data type in python called set so what is a set let’s start our application again and let’s say i provide here input values as a list let’s say 20 40 and 20 again so basically i have duplicate values in my list and when i execute it i see that the program got executed for each element and i have duplicate results because i passed in the same value twice now again users they can input any value they want either intentionally or accidentally this could be bad values or things that don’t make any sense so let’s say we want our program to behave in a way that if user provides the same values twice or three times we only want to calculate the number of hours for that value just once so basically for this input we want just those two lines and basically ignore the execution again for the same value and you probably already guessed that’s where set data type will help us so set is basically a list of elements but with unique values inside so list data type allows duplicate values the same value multiple times set does not allow duplicate values so how do we use set instead of a list and it’s actually very easy to convert an existing list into a set and we can do that using a function called set and basically the parameter of our set function will be the list so if this list here contains any duplicated values that will be basically just filtered out when we convert it into a set so that’s how it works and again for demonstration let’s actually print out how set value looks like so i’m going to print the list first so that we can compare then we’re gonna print out the set and let’s also print out the types and i don’t want to repeat this expression over and over again so what we can do even though this is just for demonstration we can actually extract it into a variable let’s say list of days like this and we can use it everywhere we need and this is a little bit cleaner because we don’t have to repeat the same expression over and over again and again let’s print out the type of list of days and then print out the type of a set of lists of days and again you see that nested function calls three times and this should give us some interesting value that we can compare lists and sets and just a small note here that whenever we have this nested function calls think of the execution from inside out so the first function that will get executed in this chain is actually the set right so it starts from the last function in that chain so set function will get executed and convert that list into a set then type function will get executed on that resulting set value and then print will get executed and print basically the result of the type so the order goes from innermost function to the outer functions so let’s save it and execute and now i’m going to again provide a list let’s say 10 and then 45 and 30 and 10 again and enter and first of all we see that 10 only got executed once and not twice and we can also see the first one is basically value of a list and you see at least here the second one is a set and you already notice the difference that list basically uses square brackets and set is represented using curly braces right and again it has value of 10 just once and again we have the data type of a list and a set so just to demonstrate that they are actually own separate data types and like we saw previously with lists we can also create sets as well as add an excess values from it so let’s see an example here for example if you want to create a set the syntax for that will look like this as we already saw again set can have strings or numbers or booleans as its elements let’s use the same example we use with lists so i’m gonna just basically type in names of the month here so let’s say we have again january february march and we’re going to assign that again to a variable so this will give us a set that we can create ourselves not just from the user input and now we can access the values the individual elements from the set and we can also add elements to the set however we cannot access the individual elements of the set like we did on lists right you remember on lists we use the syntax with square brackets and the index of the element in set we cannot actually do that instead we can only access the elements of a set in a loop so for example in a for loop we would write element in my set and then we can basically print that element so let’s execute and right here you see all the elements printed out and again as i mentioned with lists also previously most of the time when you’re working with lists or sets you’re gonna want to look through the elements because you probably would want to do some operation on individual elements or some of the elements right instead of just grabbing individual one or two values from that now how do we add elements to a set let’s see it as well we can add elements to my set using my set so the set itself the variable name and then if you do dot you see a bunch of built-in functions again set has its own built-in functions which are completely different from what list has and it has a function called ed and here we can basically add a new element again let’s do april and now we can print my set and execute and there you go so we have here individual elements that are printed out and we have the new list after we edit april now one thing you probably already noticed when working with the set like printing its elements or adding a new element it doesn’t work in the same sequence as with a list right so for list we basically had this january february march in this exact order and when we edit a new element basically it got added at the end right as a fourth element in set it’s not ordered it’s basically in a random order right so if i execute this again rerun you see the order changed here and here as well right and if i do it again there you go so this order and this order basically changes right so as you see working with sets is actually pretty different from working with lists so this means that set not having or not allowing duplicate values is basically just one of the differences between sets and lists and of course you’re probably wondering i can add elements i can access elements what about removing elements right from lists or sets and you can do that actually the same way for both sets and lists so for example if we want to remove an element from a set we can execute a built-in function called remove and remove basically takes a parameter which is the value itself so let’s say if we want to remove january from here then we’re going to pass the value to remove function and now if i print my set again after the remove gets executed and let’s run it and here you see the last print basically doesn’t have january inside and as i said it works the same for lists so let me demonstrate this as well so on my list which has its own set of built-in functions one of them is remove which in this case is called the same for both set and list and this remove built-in function also accepts the value of the element you want to remove and let’s print it again my list and execute there you go this is a set with the syntax with curly braces and this is a list which now doesn’t have january inside because we removed it and as you know lists can have duplicate values so if we have january again here so two times and we do remove january it will actually remove the first occurrence of that value so if i execute this you see the first one got removed and the last one or the second january value is still there so that’s how you work with sets basically and also how to remove elements from sets and lists so at this point i want to take time and review the functions that we have used from python itself so the functions that we ourselves didn’t actually write and the functions that python basically makes available for us to use are called built-in functions so till now we have used function print which basically just takes some input this could be a string this could be a variable this could be a number doesn’t really matter and basically just prints it in the output console right in the terminal we also saw input function that basically takes user input again we can provide a parameter which will be a message or leave it empty we also in the last example so an example of set function which basically takes a list and converts it into a set and another example is int again takes a string as a parameter and converts it into integer and all of these are built-in functions because python provides them to us so that we can use it in our code and in python there are a lot of very useful built-in functions for different purposes and as i mentioned most of these functions basically accept a parameter and then do something with that parameter that input that we provide that function and give us an output again print basically provides something here and gives us the output in the output window here in input we can provide some message that will again print an input here and the rest of them are giving value inside the code without displaying anything so in set we can provide a list and the same way a parameter here which is logical because the purpose of a function usually is to take some input like this as a parameter do something with that input and give us an output from that parameter and we have created our own functions that also take some input and give back some output like this and in addition to built-in functions that are called like this and our own functions we have also used third type of functions which is called directly on a value right and this is an example of that so basically directly on a value this could be a variable but also the string representation of that itself so if i had a string like that so basically directly on that value call a function like this and these are also built-in functions because python makes them available to us other than the syntax there is one major difference between these type of functions that are called directly like that and the functions that are called on the value itself and the main difference is that each data type has its own set of functions that can be executed like this so again let’s take example of a string and if i do dot here you see the ide pycharm basically gives me a list of all the functions again built-in functions in python but functions that i can execute on a string value and again you see split is digit this is the one that we used in one of our previous examples that basically checks if that string is a representation of a digit or just a regular string and as you see lots of different functions so all of these are provided by python to do different stuff like turn the string literal to uppercase or replace a letter for example in that string and so on but the main point here is that those functions are only for string but as i said each data type has its own list of functions that can be called on that data type so for a demonstration let’s take a list and if i do dot here again you see a list of functions that i can execute specifically on list values and there are lots of things that you can do with lists like add elements to it remove elements from it sort the list copy and so on so that’s basically a major difference between these type of functions and functions that can be executed on specific data type values but the concept is the same here you also have a function that gets a parameter an input and gives you an output and the parameter for this type of functions is actually the value that we are calling that function on so this string here 2 3 is going to be parameter of the split and in addition to that we can also provide additional parameters for example for split you saw here that we were able to add a comma space to basically tell the split function on which character to split that text so that was function comparisons in a nutshell in this part we’re going to learn a new data type in python called a dictionary and we’re going to do that by modifying our application and modifying how users can actually input the values now our program currently takes the number of days and turns it into a number of hours what if we wanted to make our program a little bit more advanced a little fancier and basically allow users to also decide what units it should be converted to so user gives us the number of days and tells us whether to convert it into hours or minutes so instead of the whole list now we’re going to get just number of days and the conversion units and this change may be a little bit complex in terms of syntax so i will try to explain everything step by step so the first thing we need to do is adjust how we get input from the user so now we want the user to be able to give us the number of days and units in one input so first of all i’m going to adjust the text here enter a number of days and conversion unit now there are a lot of different ways we can allow a user to do that but what we want to do is something like this as an input so basically number of days colon and minutes or number of days and hours again this is our own decision we decide how the user input should look like but this should be a nice way of providing both of those values basically colon separated so instead of a list we’re going to have a single input with two values that are separated by a colon so on the next line i’m going to change this split here into a column and this will give us user input this whole value split into two values as a list this is going to be day and days and unit so least with these two values and let’s actually get rid of this for loop because we’re not iterating through a list of numbers anymore and to begin with let’s just print out the output or the result of days and unit variable so i’m gonna refresh and let’s do two hours and enter and this is what we get so basically splitting this string on column will give us a list with elements 20 and hours and note that 20 is still a string right because that’s how we get the input and now from those two values we’re going to create a value of a data type called dictionary so in python we have another data type called the dictionary which basically looks like this so you have curly braces just like we had for a set and inside we have key value pairs so we don’t have just single elements like this but rather we have key value pairs so key in our case is days and the value of that key in our case would be 20. and then comma separated another value would be unit and a string hours so basically this is the syntax of a dictionary and obviously the difference between a list and a dictionary is that we have descriptions for each of our values represented as key value pairs so we want to create this construct right here from those two values and since this is a data type we can create a value and assign it to a variable of that data type so let’s call it days and unit dictionary equals and obviously we don’t want those values to be hard coded here we want to get it from the list now how do we access an element of a list how do we grab the first value which is 20 out of that list and to do that there is a syntax to access the elements in the list the list name and then you have square brackets and index of the element which if you remember you already learned in the section of lists so again days of unit list is this one right here and with index 0 we are accessing the first element index 1 is the second element and so on and index is basically just location this is location 0 location 1 and so on so this will give us the first value and obviously the second value is going to be with the same syntax with index one and let’s actually print that one out as well so that we see the results restart the application let’s do 20 hours so again this is our list 20 hours as two separate values and this is a dictionary that we created using those two values so we have key value pairs basically and the same way for minutes we would end up with a dictionary that looks like this so now we have these two pieces of information in one variable and now we can give that variable to our function so that it does the validation first of all of the number and calculation based on the units so on the next line we’re going to call our validate and execute function and as you see we have this red line here because something is wrong first of all we don’t have this variable called num of days element anymore because we deleted the for loop instead we have days and unit dictionary and here we are validating the integer value of the input number and the same way we need to validate this input number here as well so now the question is how do we access a specific value in this case the value of days here in a dictionary because we have to validate this value as well because i might as well have entered text instead of this number so the way to access values inside a dictionary is again using the square brackets just like we did for list but instead of an index index 0 or index 1 we don’t need to use an index because we actually have a key so instead of index we’re going to use the key like days or unit and this will give us value of 40 which will then be converted into an integer and then validated right here so again i’m gonna copy this for comparison so to access an element of a list let’s say my list here and let’s do 20 30 doesn’t matter in order to access the elements of that list we can do that using an index so this will basically print number 30. again if we had other elements here we can do index 2 so that will print out 100 and let’s actually check that and remember to comment out a multi-line code we can use three quotes at the beginning and at the end let’s refresh and there you go 100 was printed let’s do the same with the dictionary so we have a dictionary days like this and to access an element inside that dictionary we use the square brackets and instead of the index like here on the list we use the key itself and again i’m going to print this and there you go you see value 20 and i can also access unit value and if i execute it i see hours and so on and i can add any number of key value pairs in my dictionary as i want so for example i can add a message here all good and i can access that message like this so this is how you create a dictionary and that’s how you access the values in a list or in a dictionary so let’s clean this up comment in our code again like this and get back to our code so basically again this is how we access the number of days in our dictionary and in our days to units function we need both of those values and we can pass in those values separately so we already have a user input number from the dictionary and the second value would be the unit from the dictionary however we have to add that second parameter to our function so let’s do that unit let’s call it conversion unit so now we are passing both of these values to our function so we have the user input number here which is already converted into an integer and the second one which is the conversion unit and now we can finish the logic in this function here right now we are using this hard-coded calculation to units which is 24 and number of units which is hard-coded hours so first of all i’m going to remove those two we don’t need them anymore because we get those values from the user and now we have to substitute those two so here we’re going to check if the conversion unit is hours equals hours then we’re going to return calculation with hours it’s going to be 24 and conversion unit here we can also hard code hours here because we know it’s hours else if so if the conversion unit is minutes then we can return calculation for minutes and a text like this and it could also be that the conversion unit that was provided is none of those or maybe some invalid text and in this case we’re gonna add final validation so if it’s neither hours nor minutes then we’re just gonna say you know what unsupported unit so basically we don’t do conversions other than those two so we just tell the user that’s an unsupported unit and now if we execute our program and enter value there you go we have our output and same way if we do 90 days to hours we have our calculation in hours so that’s how dictionaries work we can do one final thing here and as usual print out the type of our dictionary and there you go you see class of type dictionary here which is another data type and at this point we can actually summarize all the data types that we have learned so far so let’s give us some space here so first one was string so basically a message or some output like this that’s our string then we have integers example of that we saw already days then we have float numbers which for example can be used for price or weight of a product etc we also have learned boolean data types when we check some kind of condition whether if it’s true or not so for example is it a valid number or is the user input exit we also learned a data type of lists so for example usage list of days like this including duplicate values and list data type can be used for strings as well not only for numbers so for example we can have list of month like january doesn’t really matter we also learned a data type called set and set basically is very similar to list but it doesn’t allow duplicate values and its syntax is with curly braces so the same way we can have numbers or strings or booleans or any other data types inside a set and the last one that we learned was a dictionary and let’s take our own example day in unit and dictionary is basically a collection of key value pairs and the syntax is written like this so why do we need all these different data types well depending on the use case or what exactly you are trying to achieve in the program you’re gonna need a different data type to achieve exactly that so each data type has its own specific purpose and throughout these days to units calculator i try to demonstrate the purpose of each data type and when we need to use them so these are all the data types that we learned these are also most of the data types available in python and the main ones that you’re going to be working with so this should give you a good foundational knowledge about data types in python and also note that most of these data types you will also encounter in any other programming languages because as i said these are the core data types and most of the programming languages actually support these data types as well till now we have been writing all our code in one single file so basically we have a project with just one python file and we’re writing all the logic inside that file however you can imagine that if you’re writing a little bit more complex applications that have much more complex logic so they end up having lots of functions obviously you’re gonna end up with a python file that has hundreds of lines of code maybe thousands of lines of code and it’s not very practical to manage all this logic and all this code in just one file so instead you need to structure your code and divide your logic between multiple different python files and you do that with modules to give an example imagine a web application that has basically many features like facebook for example obviously you can put all the facebook logic in one single python file right you will have a structure of facebook project with subfolders in your project which all contain multiple python files so you would have maybe packages for each feature and each such feature has a lot of functionalities so they will be all grouped then again in multiple python files right so you would end up with a project with a hierarchy of folders and lots of lots of python files inside now the question is if i have multiple python files in my project how do i connect them together so for example if i have another file here and let’s call it helper dot py and if i have some logic here basically functions defined here how do i use them or how do i reference them in another file and the way it works in python is using the concept called modules so a module is basically a python file that contains functions or variables that you can use in another python file so basically any python file that you have in your project both of these in this case are modules and you can reference one module from another so basically the idea is that you can structure your application your program using modules so you can make your project modular so in this part we’re going to create our own module in helper file and we’re going to reference that in main dot python and let’s say in main.python i only want the code that basically starts the program right all the functions all the logic i kind of want it hidden away and grouped together in a separate file so what we’re going to do is copy this entire thing so both of these functions basically and paste it in here so now you already see a couple of red lines here because now the reference is obviously broken right so main.python obviously doesn’t know anything about validate and execute function right it says unresolved reference and the same way face to unit dictionary is unresolved for helper because it doesn’t know anything about main.python and the variables defined right here so the first thing we need to do is we need to tell main note python file where to find this validate and execute function right we have defined it in helper python so that’s what we need to define how we do that is using something called an import statement so we basically import this whole helper.pi module inside main.python and we do that very simply using import helper right helper is the name of the file and therefore name of the module and right now it’s grey because we’re not using it and the way to use it is helper dot and the function name and you see the red line disappeared so again what we did is we told main.python there is a helper module in this project and please import this whole module and all the functions that this module has and make it available in main.pi and then once we have that helper module we can reference any functions if we had any variables using module name dot function so this has to be the name and if i hover over it you see that pycharm actually displays the whole path to that helper.pi file and now note that here we still have redline because this is a variable which is defined in main dot pi but a helper module doesn’t know anything about it and that’s an important distinction here because we imported helper module inside main so helper modules functions are available here but not the other way so in order to make this dictionary available invalidate and execute function we would need to pass it in as a variable like this and this will work now now note that in main.python we actually only need this validate and execute function we don’t need the days to units function because this function is only used by validate and execute function so that means that we don’t need to import the whole entire module inside main.pi we actually only need the validated execute function and this is a small example but if you had a module with 20 30 functions and you just needed one of them you wouldn’t need to import the whole module just for that one function so what you could do is you can pick and choose which specific functions you want to make available inside another file or another module and you can do that very easily using the following syntax we say from helper that’s the module again import and the name of the function like this and now because we are accessing and importing that specific function we don’t need to use module name anymore we have that function available directly so we can delete the module reference here and we have that function available like this so again instead of having entire helper module with all of its functions and other stuff we only have one specific function available here so that means we wouldn’t be able to use these two units for example now we saw an example of a module that has just functions right however module can have many other stuff for example variables and you can make those variables also available for another program and that’s an example here i’m going to create a variable called user input message and this is our user input message and we can actually put it into a variable instead of having it defined like that so i’m going to copy it and paste it here so now we have the user input in a variable in another file again how do we access it in main dot pi in this statement at the top we can actually import several things from a module right now we are importing a function we can also import our variable and we can do that also very easily like this and we can use that user input message here so basically if you have again 20 functions and variables from a module and you just need maybe five of them you can import them individually like this just basically just list the names of functions and variables what you can also do is import all this is what this asterisk sign represents so we’re basically importing everything from the helper module again this is kind of a waste if you just need a couple of functions and variables from that module and not the entire thing however with this syntax you can import everything and now you may be wondering what is a difference between importing everything from the module and importing the whole module because in both cases you have everything in the module available the difference is in the syntax because note that if we use this from import statement you don’t need to use name of the module every time you’re accessing something defined in that module right so we don’t need to do helper dot function name or helper dot variable name whereas if we imported the module like this you see we have red lines because we would need to do helper dot or module name dot whenever we use something from the module now this could be a matter of taste so basically which one you want to use i personally think that this is the most efficient and also cleaner way of using specific functions variables etc defined in a module and as a side note the things that are defined in a module that you can use basically in another file are called definitions so all these those three elements here are definitions of a module and you can use any of those definitions in a file where you import that module what you can also do when importing a module is you can rename that module basically to whatever you want so if the name of the module is too long or you just want to use a different name you can do as and then basically write a name whatever you want like h for example and then obviously you need to use that new name everywhere you access functions or variables of that module so basically how you import a module and whether you rename it is a matter of taste basically how you want to do that in your code however i think that importing specific elements from a module like this is most efficient and also cleanest way to do that so we saw how to create our own module and use it in another file so basically if you had hundred python files here with each one of them having their own functions and variables you can cross reference them from each other using the import statement very easily now in addition to creating your own modules we can actually use modules that python itself already includes so just like we used some functions that python gives us out of the box like inputs or ins so basically all of those the same way python also gives us modules for different scenarios so that we don’t have to write this logic ourselves and there are a lot of useful modules that python actually includes for example math module for mathematical operations its own module for working with dates or date times module for working with specific files and so on so basically for many different use cases python already gives you ready modules and these modules will then contain multiple functions and variables for that specific use case again if we take an example of a date so if you have an application that works with dates and times you have this module from a python that gives you a bunch of useful functions for working with dates and again this means you don’t have to write this logic yourself but rather use the existing one so to give you some examples of modules that python provides us with for example if you want to work with operating system there is an os module so we can print out we can get the name of the os for example and i’m going to comment all this out and run and you see the name of the os another useful module python offers is logging so if you want to use logging in your application the logging module gives you different functions to log an error message or warning etc as well as basically just configure how the login will look like again to see an example again it may look a little bit complex here but essentially just using the name of the module and then functions that it gives you obviously you need to know the functions and you need to know how to use them and you can get that information from documentation or if you’re using pycharm it actually gives you all the information about these functions and the module if you just hover on it so you don’t even need to google or check out the documentation and basically we’re creating a logger and we’re logging an error message so if i execute this now and here you see the output of the logger error happened in the app and logging in application is actually a very important feature so that’s why logging module is available by default in python any use case in our application would be right here if an error happened for example instead of using a print basically just log and error so these were just some basic examples but as i said python comes with lots of very useful modules that you can use in your applications for different use cases and that of course makes your work easier because you can just use the logic instead of having to write it yourself in the modules that are part of python so that you can import them like this directly are called built-in modules we learned about built-in functions so these are the functions that python makes available to us directly and there are built-in modules that we get from python and by the way if you’re wondering where this module actually comes from so where is the physical location on our machine or where this module files actually leave if you’re using pycharm you can actually hover over it and hold down a control key or if you’re a mac command key and click inside you see the file opens up which is the module the logging module since i said module is basically just a python file that has multiple functions variables etc available and you see right here on this top line the whole path for that python file so that’s the location of that module file locally on my computer and inside this python file basically you again have python code and if we look for get logger function here like this right here you will find the definition of that function right so somebody implemented this function and called it get logger and this is basically the logic all the things that get executed behind the scenes and you as a user of python basically can use the name of the function and write your own programs with it and let’s also look for error and there you go we have error function as well right here and obviously this is a more complex code here than what we write but just to give you an idea that this is actually a file on your machine that comes with the python version that you install locally and all the functions are defined already there by python developers and you can just use them like this without worrying about how the logic is actually implemented and another interesting thing is if i click here in this python 3.9 like this logging is basically one module that we used and here you will see the list of the complete list of all the built-in modules that you get from python so some of them are folders like logging for example email and bunch of other stuff and the operating system module for example that we used is a python file then you can find right here so these are the built-in modules so now that we know what built-in modules are and how to use them let’s actually see a realistic example and also write a little more interesting application using built-in module so what i’m going to do is in my python project i’m going to create a new file and i’m going to call this time to deadline dot pi y and we’re going to write an application that basically accepts a user input of a goal and a date like a deadline date and then we’re going to print out back to the user how much time it is remaining till that deadline and that deadline will be a date right some date in the future so that means that we’re going to be working with dates and in order to work with dates we are going to need python’s built-in module that allows us to call functions and do some processing and stuff on date values and that module is called date time so import date time so let’s have that import statement right there and we’re going to use it in our program so the first thing we want to do is let the user give us an input about their goal and a date or deadline for that goal so let’s do that first we already know how to ask for user input with a message so we’re gonna say enter your goal with a deadline separated by colon and we also know this already basically what we want to do is user to be able to enter their goal like learn python column and a date and let’s say again this is totally up to us to decide we’re the ones basically setting the rules here so let’s say we want the date to be entered in following format day month and a full year like this so that’s the format that we’re looking for and this is how user should input the value otherwise with a different format it’s not going to work so we’re going to save that input value into a variable let’s call it user input so we have the user input let’s do the split again on a colon remember we have this whole thing as a string as one string so we want to split it into two parts so we have the goal here and the deadline and this will give us a list with those two values and let’s call it input list and now from that list we can actually extract or get those individual values using a list syntax so accessing the elements from a list which is what we learned already using an index right so we have input list index 0 which is going to give us learn python and let’s save it as a goal variable and let’s create another variable which is going to be date let’s call it deadline and this will be the second value in our list now let’s actually print this out print this whole list out and now note that we are actually in a different file we’re not in the main.pi anymore and we don’t want to execute main python file instead we want to execute this one right here we basically just want to ignore everything else in this project so how do i go from main to this file execution very easy in this editor just to right click and you see here run time till deadline and i’m going to execute this everything else is ignored in the project we are basically just working on this one right here so enter your goal with the deadline separated by colon let’s do that i’m going to do pi learn python colon and then let’s enter some date and enter and this is the output so we basically split that into two values and put it in a list right here and very important to note here that both of these elements in this list are strings because again user input is always interpreted as strings so this was a string and it was split into two strings which are learn python and this date here however we don’t want date or deadline as a string we want deadline as a date and exactly for that functionality we need this date time module because we don’t want to implement it ourselves we want python to give us a ready function from a module that will basically just let us convert this string into a date value and converting string to date is just one example usage of date time module but you can use this module to work with dates generally like creating new dates formatting the dates updating the value etc and we’re gonna see some of those examples in this section now if you’re learning this type of thing alone you don’t have me basically teaching you and giving you an example the way you would do that is you would basically research and maybe google how this is done in python and you would basically see some examples of using this date time and what the name of this function is and how to use that as well as each module has its own documentation page where you can look up the syntax and usage examples because obviously you’re not going to know how to do that by yourself so the way we convert a string into a date using this date time module is on this datetime module if i type in dot i will see a list of all the definitions that daytime module gives me right so i have date daytime time etc the one that we need is date time because the function that we need for conversion is inside that definition and don’t be confused here because we have date time twice here the first one is a module and the second one is a definition in that module and we can actually check that as well so if i jump into this date time module and inside that if i look for date time again so right here you see this date time definition and on that daytime definition we have now functions that we can use and as you see this is not a function or variable it says class here which is another concept in programming we’re gonna see later so just for now think about this as a container of functions and variables inside that module and that’s why we have to access it like this and then on that daytime definition this class we now have functions that we can use to do the conversion so the function we need is called str so string p time and this function will take a string representation of a date and we’ll convert it into a date format so our string representation is deadline and we need to pass in the second parameter because remember i said we basically decided that the date should be entered like this with points and a full year here and as you know there are lots of different formats and types for dates right depending on a country or a language or even within that language we basically have multiple different formats right we have formats like this or we could also have a shorter version of the ear etc so we need to define here the format that we want python or this method here to use when converting this string into a date again because there are so many different formats available so what we have here is a day then we have a dot then we have a month again a dot and then we have an ear so this is kind of a main structure of a format however formats for dates have their own specific syntax and this is actually for all programming languages so what we need to do is put this percentage sign in front of every letter so again we have day month year and there is one more thing about this format this format right here matches this date however we want the full date not just the last two and the format for that would be a capital y again this is something that you would look up in the documentation of the module instead of knowing it by heart but just know that this type of formats are used when working with dates and this is not specific to python you will actually see something very similar in all the other different programming languages and that will do exactly what we want it will take this date here and give us a proper date format from it let’s actually test this so i’m going to print this first and i’m also going to print a type a data type of that value so let’s execute i’m actually going to copy that so i don’t have to retype it over and over again and enter and here you see we printed first of all the date not a string and now this looks like a proper date and not a string anymore note the change in the format plus we have these zeros here which represent hours minutes and seconds we didn’t set any of those so these are all zero and we have the date time type again note date time for a module name and date time of the class name so this is the type of our converted date and the reason why we needed to convert that string into a date is because we want to calculate how many days or how many hours are remaining until the deadline from now starting from today and to do that calculation we need to have date type because we can’t do that on a string great so now we have our deadline represented as a date so let’s actually assign this to a variable it’s a deadline date like this and remove this and now we need to do a calculation how many days from now till the deadline we already have the deadline we need now again now is or today is also a date and since we have this module date time we can also assume that this module will give us some function to tell us the date of today and if i do date time again daytime class and today you see that we have this function available and this will basically give us the date of today so depending obviously when you execute this program it will give you always the current date so let’s print it today for me it’s 7th of february so if i execute it now i’m going to enter this and today is 7th of february for me so if i execute this let’s actually comment this out here i have the date for today which is 7th of february plus the exact time it is now but we don’t care about the hours and minutes and seconds we just care about the day so that means we already have deadline and we have today let’s also add it to a variable like this and now we can actually do the calculation calculation is super easy we just say deadline date minus today date and this will actually give us the difference between or time difference between today and the deadline date in the future again let’s actually try this out and you see that so this is 12th of august for me today is 7th of february so the program calculated that there are 185 days until the time plus how many hours minutes seconds and milliseconds so that was a pretty easy calculation now what we want to do is tell the user some kind of message and we want the message to be dear user the time remaining until the deadline for your goal whatever the goal was is this so let’s actually put that text and message together and bring it back to the user so first i’m going to save it into a variable let’s call it time till and the message dear user time remaining for your goal and here we want to print what the goal actually is and you remember how we format a string when we want to use a variable we put an f here and in curly braces now we can use variables or numbers or some other expressions which are not string so first of all we’re printing back the goal so time remaining for your goal whatever goal they entered is time till and let’s execute our program and let’s give it some other value like this and enter and here we have our message dear user time remaining for your goal learn python is 132 days and this many hours minutes etc now let’s say we don’t care about this whole thing here we just want to know how many days are remaining so how do we get rid of this part here again very easy and the time till if i do dot here i get a list of suggestions for functions or variables that i have available and one of them is days as you see here so if i click here and save and i’m going to reuse these inputs because i don’t want to type and as you see we got rid of this whole thing here and we just have days and let’s actually write days and there you go we have a cleaner output now for our user and finally what if the deadline was just a couple of days in the future and the user wanted to know how many hours are remaining till that deadline we can do that by getting rid of these days and again type in dot and we have something called total seconds here which gives us the time different in total seconds and now we can reverse engineer and calculate the number of hours from this total seconds which is pretty easy like this calculate minutes and then calculate hours and i’m gonna execute this again and here you see the number of hours with a decimal precision so we have 4450 hours point some fraction number here again we want to get rid of this extra stuff and as you see from the syntax it is actually a float number with a dot here so what we could do is basically convert this whole thing this float number into an integer so convert this whole thing into an integer using int function and we need this whole calculation here inside the int function and let’s execute it again learn python and let’s choose a date which is near and there you go we have a whole number 57 again cleaner output and as a code optimization we could take this whole thing out into a variable and call it hours till to make our code a little bit cleaner so now we have the whole program that takes user input and basically prints back to them how many hours are remaining till the deadline for their goal and for this program we used a date time module a built-in date time module from python and we also learned a new data type which is date time and as we learned from the module section we can actually optimize the import of the module because obviously we’re just using the date time definition and nothing else from that module so what we could do is from date time module import date time definition which is a class in this case so now you don’t need to use the module name so let’s get rid of those and this could make the code cleaner as well as make the import more efficient because we’re not importing the whole module even though we just need one definition from there when you install python it comes with a set of modules that are built in into python however there are many more modules for other different use cases like web development or data science and machine learning etc that are not part of that installation and these are basically external modules not built-in modules that you have to install as you need and this makes sense because the built-in modules are the ones that most of python programs will probably need and depending on what specifically you are doing with your program whether you are developing a web application or creating some machine learning program you can then add and install them as you need and there are hundreds of such external modules for python out there and obviously it wouldn’t be practical to have them all on your laptop when you’re just gonna use maybe a handful of them right now if i need to install an additional module for example django for web development where do i find these modules and how do i install them python modules actually live in a module repository where you can find them and that module repository is called pipey so if i look for pipey right here you see the python package index if i click inside you can search for any module that you want to add or install additionally for your application and here you see this word package everywhere instead of a module so what is a package or what is the difference between package and a module to give you a simple comparison module is basically a python file like this one right here that has a name of that file right so we have an ssl module or the one that we used earlier we have this os module right so module is one python file that contains all these functions and variables that you can use package is a collection of modules so if we scroll up and logging is actually one our example so these are actually packages and again let’s go to logging so package basically contains multiple python files and use it in the same way you basically import the functions and definitions from the module and as you see clearly the difference is that package is more structured so for example the code is not available in just one single python file but it’s divided like this in our case we have two python files and package always has this init python file and this file basically differentiates a normal folder like we have right here with bunch of python files from an actual package with python files so that’s the difference between modules and packages and many external modules basically that we want to use in our projects are actually packages so basically package is a good way to define some hierarchy and structure for your modules and kind of group them together so that’s why you see package here as a name instead of module so now that we know the difference let’s actually search for a package for our project so for example if i type here django you see django packages that we can use from here we also have numpy and so on however in programming when working with and using these external packages a typical example would be where you need to implement some logic for example you want to write a program that basically talks to aws maybe and you don’t know exactly the name of that package but you know what you’re looking for so in this case instead of the exact name you would actually type in here in the search projects box a description of what you’re looking for so let’s say we’re looking for an aws api package right something that will allow us to connect to the aws api and as you see here we get a list of different packages for that to choose from so basically pipey is a repository or storage for all of those modules and packages and people can also publish their own libraries like individual developers for example they can publish their own packages and modules there and make it available for other programmers to use and that’s one reason why large community is so great for a programming language because then you can make use of all these modules and packages that others in the community have developed so for any kind of functionality you need in your application you could imagine that there is a module or package that helps you do exactly that now let’s say i need a django package for my web application so first i find the package and now i can actually check some of the documentation for that specific package so if i click inside i see some description for the project as well as documentation and some other links now the question is how do i actually install this package locally so that i can use it in my project in python we install packages using a package manager tool called peep and right here on top below the package name you actually see a command peep install django so this is actually a command that will install that package locally on my laptop so we install packages in python using this pip command so what is this command or where does it come from pip is a package manager for python and if you know any other programming language basically the concept is the same every programming language has its own package manager tool for javascript it’s npm for java it’s maven or gradle and for python it is pip and one of the main tasks or usages of a package manager tool is to install external packages or libraries or also called dependencies for your project so if python needs this django package basically it’s the job of the package manager to install that package and make available for python now where did this command come from do we have pip command available well in python version 3 actually pip is packaged inside the python so when we install the python we actually installed pip as well so basically we’re going to copy this command peep install django and we’re going to execute it actually from the terminal of pycharm so in pycharm editor we have this integrated terminal so this is actually pretty much the same terminal as you have outside like this so we are going to execute this pip install command directly in this pycharm terminal so i’m going to copy it here and do peep install django and you see it is downloading and successfully installed django 3.1.6 and we can actually see that package from our editor directly if i expand these external libraries and site packages and scroll a bit down here i have django 316 version installed so i see that the package is now available in my project and to also test it in the code i can do import and django and you see that pycharm actually recognize that i have django packaged locally so it gives me that package as a suggestion so that will basically import the whole django package so we can now use it in our application here you see pycharm actually noticed you are using or want to use django web framework as i mentioned in the beginning the pycharm professional edition has special support for different python web frameworks supporting you with syntax highlighting suggestions database integration and so on so again if you want to try it out for free for three months just use my code in the video description in the same way as we install the package we can also uninstall packages using pip and let’s also actually demonstrate that pip uninstall django and let’s confirm that successfully uninstalled django now if in the site packages i click inside you see that django packages are gone so this site packages folder got updated django was removed and you also see that in the code editor now i have this red line under django because pycharm cannot find a module called django and also if i do this obviously it won’t give me any auto suggestion for that so that’s how you can use peep to install packages and also to uninstall packages for your application now here i want to show you another cool alternative to installing and uninstalling packages directly in the pycharm ide and this is actually a feature in the latest pycharm release and for this i need to switch to an early access pycharm version so you see here it says pycharm eap early access to show you the feature however when you watch the tutorial it probably will already be included in the latest official pycharm version so you should have that already so instead of us basically finding this package in pipey and then executing peep install commands right here what you can do is down here you have another tab called python packages so if we click inside this is a place where you have everything that you need to know about the package the package search and all these features basically in one place so for example in order to install django we can just search for django right here and you see that when i type in the first couple of letters i already get suggestions so this is a list of all the packages that start with this name that are actually available in pipi so let’s type in django and we see that right here and on the right you see the documentation of the package that you would actually see in pipey ui so you have that in place as well and in addition to that what they added is the documentation link so this is actually the package how-to guide and the full documentation with examples etc so very convenient way to basically get all the information about the package search the package and then to install the package we can choose the version here so either you can leave the latest or basically select the specific version and then once you have selected that you can just click install and here you see installing package and there you go so now in installed view here so we just had pip and setup tools these two things installed and right here we have now django in the installed packages list and again while you’re now using the installed package or library in your code and basically you want to look up some examples or you want to check some documentation right you go back to the package click inside and you have link to documentation and the package information as well and also just by looking at this list you know which versions of which packages you have installed so i think it’s really cool way to manage all your packages to install packages and for example if you want to uninstall packages from your project then again just clicking to that specific package right here you can just delete it and it will be removed from your application like this and no django anymore here so a very cool addition to pycharm because this will be very convenient to work with the packages so now i will switch back to my other editor again and continue from there so basically i have just cleaned up my python project we have this main.pi which is empty and we’re gonna write an application that will read a spreadsheet file from our local file system it will read some information from that spreadsheet file and do something with that data and this could be a very useful use case if you’re working with lots of files and you want to do some data processing in those files and you don’t want to do that manually by automating or writing a program in python that basically can do anything in a file or across multiple files so let’s see exactly what we are going to be doing with this program so first of all we’re going to have an input file a spreadsheet file that we’re going to be working with and that spreadsheet will look like this it’s called inventory that’s how it’s going to look like so basically this file simulates something that many companies would have and employees of that company would be working with so we have this list of product numbers inventory for each product price for the product and a supplier so this could be an example file from a company that is basically dealing with selling or buying products so what we’re going to do is we’re going to read the information from this file and we’re going to do something with that information first we’re going to write logic that calculates how many products we have per supplier so we have three supplier companies here and per supplier we’re gonna calculate number of products from that specific company and as a result we’re gonna list the company so all three companies with their respective number of products then we’re going to write another logic that lists inventory products that have inventory which is less than 10 so basically those ones the third exercise is going to be to list each company with their respective total inventory value and finally in the last exercise we will calculate the inventory value for each product so product count times price and we’re going to write that value to an additional column in the spreadsheet and after that we’re going to save that updated spreadsheet file programmatically using python so we’re gonna see how to update a file and then save it programmatically in python if any of these sounds a little bit too complicated for you then just bear with me i’m gonna explain everything step by step and it’s gonna become much clearer when we actually start writing the logic so the first thing what i’m gonna do is i’m gonna take this file that i have in the downloads folder and i’m actually gonna move that into my project so i’m gonna copy that and i’m gonna drop it in here so that we have the file right in our project and so we can basically just read it easily and okay and here is our inventory file so that’s taken care of so obviously what we want to do now is read that file so basically let our python program read the contents of that file right here because we want to write some logic based on the values that are in this inventory file right we want to calculate stuff we want to list some stuff and so on so basically we want to work with these values and in order to do that we need to read all of these values into our program so that we have them available so how do we do that now there is actually a built-in module in python that allows you to work with files generally right it’s not specific for a spreadsheet or for any other file type it’s for different types of files generally however there is an external package that allows you to work with spreadsheets specifically and the obvious advantage is that that external module that allows you to work with spreadsheets or was created to work with spreadsheets specifically has much more functions and is much easier to use if you are working with spreadsheets compared to this built-in file module so that’s one of the cases where you may have multiple ways of actually implementing some functionality for application and then you have to make this decision of maybe finding a better package or better module which is available externally that will make it easier for you to implement that functionality so that’s what we’re gonna do for our project we’re going to choose the package that is actually made for working with spreadsheets we’re going to use that one and it’s called open pi xl and if i search for it this is the package that we’re looking for and if i click inside basically we have some information about this package so here we see a description let’s actually make this bigger description library to read write excel files with all these formats so this is the library that we’re going to be using in the same way as we did before we’re going to copy that command and execute it from pycharms integrated terminal so from here i’m gonna execute this pip command and install our module and as you see successfully installed open pi xl and this is the version of the module that we installed and in external libraries site packages you should be able to see our open pi excel package and now because the package is available locally i can do import and open pi excel again i get a suggestion from pycharm because the module is there and now we are able to use that package for our application and one small note here if you’re wondering why there are some packages with basically a dot inside and some without these are the packages that we install python packages and we know that because there’s this init python file inside and the ones without the dot they’re just folders with bunch of files inside but they’re not python packages so to say and inside some of those packages we see other packages as well with their own init file so basically hierarchy of multiple packages and at this point i’m going to say that the word library basically describes package that includes multiple other packages so basically which has a hierarchy of packages so we have module which is basically just one python file that we can use in our project then we have package which is a hierarchy of multiple modules with an init python file inside and then we have library which is basically multiple packages together in a hierarchy just like we see right here so note the difference so you don’t get confused when you see library package and module especially if used interchangeably great so now we have our module in place so let’s use it now to read our spreadsheet file and again you basically have to know the function names to do that if you don’t you can do dot and get suggestions and load workbook is actually the function that we need in order to read our spreadsheet file so i’m going to choose this function and obviously we need to tell this function which file it should read so as a parameter we’re going to say please load inventory file and we even get a suggestion because we have this inventory file here and there you go now this function will load the workbook and all its contents and later we obviously want to do something with that content so in order to be able to do that we need to save it first as a variable and let’s actually call it inventory file like this and this will give us the file contents now let’s actually open that file again and let’s see exactly what we need so we can have multiple such sheets basically per file so we need to tell the program which one it should use exactly so for example if this was called a product list you would use that name but we’re gonna go with sheet one so we’re gonna use that name basically and we’re gonna grab that using following syntax and you remember this syntax probably from using a dictionary so this will give us this one specific sheet and all the information inside and we can also save that into a variable so let’s actually call that product list so now we have read the whole file then we have read this specific sheet of that file and now we have all this information in that variable so now we can read any of those values and do calculations etc using that variable so let’s get to our first task and the first task is basically to calculate how many products we have per supplier and then list the names of the suppliers with that respective number of products so let’s go back and do that so the results what we want to get is basically products or number of products per supplier right that’s basically what we want to get as a result so we’re going to create that variable and we’re going to set it to an empty dictionary so by the end our program should give us something like this a dictionary where the name of the company is the key and the value is basically product count for that company and since we have three suppliers or three companies we’re gonna end up with a dictionary with three key value pairs per company so we’re starting with an empty dictionary for products per supplier and now let’s see how we can programmatically calculate this first of all what we need is we need to go through each of these lines basically so we have these rows so we need to go through each and every row in order in sequence and we need to get or check a supplier name for that row and you remember whenever we execute a logic on multiple values over and over again so basically same logic or same function gets executed for multiple different values for a number of times that’s basically a use case for a loop right so we’re looping through those rows and we’re doing the same thing per row which is getting the name of the supplier now as you also remember loops have conditions right we need to tell the loop how many times it should execute that specific logic and if we check our file here how many times we want to execute the logic the answer is as many times as the number of products so if we scroll down we have 74 products so we need to do that 74 times for each product so basically as many times as the number of product and obviously we want this program to work for any spreadsheet file right with any number of products so we need to calculate or we need to read that value also from the file so basically we need to read how many products are on this list so let’s see how we can do that first of all we’re using for loop to execute the logic for specific number of times and if you remember from for loop syntax four then we have the specific item so what is an item in our case our item is a row right product row is going to be an item of iteration so looping basically so we can call our item products row and then comes in and now we need that condition how many times and again this should be generic so we need to calculate or we need to read the number of lines here number of rows here from the file and the way we can read that is remember we have all the information we need in that one specific variable which is product list and that variable has the value for number of rows which is called max row now how do i know that max row attribute is available for product list i basically just looked it up on the documentation of the module and as i previously also mentioned whenever you’re using a module this module will have a documentation so if you need some functionality if you need some values you can basically just search inside the documentation which functions and variables are available to get the functionality or values that you need and we can actually test it we can print it out like this and as you see here 75 so basically max row will always give us the number of lines or number of rows in that specific sheet so we know how many times to iterate now whenever we’re providing a specific number in a for loop like 75 for example in this case we need to put that number in a range like this so we can’t just say 70 or in this case max row now why do we need a range here and why is number just not enough because the for loop is for iterating over a list and the range will create a list of numbers to iterate through in our case range of 75 will create a list of numbers or sequence of numbers from 0 to 74. and with that we’re going to have a valid for loop where for each item in this list of numbers some logic will be executed so that’s why we need a range here and now there’s one more thing that we need to fix we go back to our spreadsheet you see that the first row so this is going to be the first row basically does not actually include the product information it just includes the titles for each column right so we actually do not want to read this line we want to skip it and we want to start from the second row so instead of starting for loop from the first row we want to start it from the second row and in order to tell python to start at row 2 in the range function we’re going to pass first parameter 2. so basically this will give us a new range of numbers starting from 2 instead of starting from 0. and since we’re using those numbers in the range as an index for the rows the first number is going to be 2 so we’re going to start iterating from the second row so this will be the start point and this will be the end point so basically from here to the end now there are two things specific to a range that you should be aware of first of all when we do not provide the start index basically the start number in the range by default it’s actually zero so it’s not one but it’s zero and obviously we don’t have a line zero here so if we executed it with the default one we would get an error so that’s one thing to consider that range actually by default starts at 0 and not 1. but for us it doesn’t matter because we’re skipping the first one anyways and we’re starting from line 2 because our spreadsheet doesn’t have line 0 obviously another specific of the range is that the second value here basically the last number of execution in the loop in our case this is going to be 75 because we have 75 lines and we printed that out here that number is actually exclusive it’s not inclusive that means that the range will execute from line 2 to 75 exclusive so basically till here this line will not be included in the loop again that’s a specification of the range which we need to fix and basically want to tell you know what we want that iteration including the last number as well including that max row and a simple fix for that is going to be to do plus one here so basically whatever the max row is we want to include that one as well so we want to add one to it so now we have a range starting from two and ending in 76 exclusive so obviously the 76th line will not be red and this will now give us a range that we need and now that we have condition for the loop and we have set how many times it should execute let’s actually execute the logic itself so what is the first information we need from that product row for each row we basically need the supplier name so that we can increment or start counting how many products this supplier has so we need this one two three fourth column and the value in that fourth column for each and every row right let’s go back to editor how do we get a value in the cell you have to imagine when we iterate we have one row per iteration so right here we actually have this product row which is just one row and we have four columns here and we want value in this specific cell and we can get it using first of all product list because again we have all the information here so in this list we need a cell right we need a value of a cell so that’s the name of the function and the cell basically takes two parameters again product list contains the whole sheet here so the whole list with all the rows and columns and we can get a specific cell value so whatever we are doesn’t really matter from that variable by providing two values the row number and the column number that’s it so row nine column one basically will be this specific value row five column four will be this specific value so for each iteration we’re gonna do exactly that so for our case the supplier is always column four and the row is dynamic because we are iterating and therefore we’re going to use whatever row we’re at at the current iteration so that’s the first parameter and column 4 as i said and this will give us the supplier name for each and every row so we can grab that value like this and this is going to be supplier name so we can save it in a variable as a next step we’re going to start building how many products each supplier has we’re going to start building a dictionary with the name of the supplier and then how many products they have so we’re going to be building this dictionary here so this is a reminder now for what i said previously that you don’t need knowledge of math in programming rather you need logical thinking right so you’re going to get tasks like this where you have to basically logically decide how you are going to do a certain task and think all this through right so programming is more about logic rather than pure calculation or math which is actually more interesting and cooler and that’s exactly what we’re going to need in this example we’re going to need some logical thinking to basically build this application so bear with me on this one the first thing we need to check here so think about this iteration on the first time and second time the first time the list or the dictionary is actually empty so we want to add the first supplier to the list right away right so we’re gonna grab that and the syntax for adding a new entry in a dictionary is like this where we have a key and a value here so basically what we want to end up with is supplier name like a company and number of products for that supplier that’s the dictionary that we want to end up with then it’s going to be bbb company and so on so the very first supplier goes directly into the list and we’re going to need the name of that supplier we don’t know what it’s going to be so name as a key and value is going to be 1 at the beginning right this is the very first iteration so after the first it iteration we’re gonna have the first company name supplier name and count one for that on the second loop second iteration basically if the next line is a different supplier like here for example then a new entry will be added because we have a new key now with count one right so now we’re gonna have company a with one product company b with one product now what happens when on the next iteration we get company a again right what we want to happen is company a the product count to increase to two right because now we found another product that is supplied by the same company however with this land we are actually overriding and setting it back to one so how do we make sure that number of products gets incremented instead of always setting it to one what we’re going to do is before we execute this line we’re going to check is it a new supplier or an existing one because that makes a difference so how do we know if it’s a new one or an existing one we can look that name up in the dictionary if we have already edited that name in the dictionary then it’s going to be there and we can do that very easily again with the syntax if supplier name in the dictionary it’s actually very readable syntax that says is the supplier already added to the list or is it a new one so if this is true again remember if conditional so if this is true statement if the supplier name is already there then it is an existing one so we need to increment the product number instead of setting it to one so instead of assigning a new value we want to grab that value the existing one and basically add one to it right just increment by one so getting a value from a dictionary you probably remember the syntax already using the key and we can save it into a variable let’s call it current number of products like this remember we’re using a key in order to get the value and the key is the supplier name value is the product count so this will give us the current number of products on the first iteration this will be one or after the first iteration we’re going to have one product for that specific supplier and if we already have that supplier in the dictionary we want to increment the number of products for that specific supplier by one because we just found another product from that supplier so we want this value to now be plus one right so current number of products plus one so that’s the new value that we want for the existing for this current supplier and how do we assign it back to the dictionary again we grab that and assign it so as you see taking the value from the dictionary has the same syntax as setting that value in the dictionary in fact we could actually use a shortcut here so instead of current numproducts we could just take that value and add plus to it and then set it back as a new value and this will basically just give us a one-liner for the logic depends on the taste whether this looks nice or not or whether it’s better to have a new variable and increment the value like this let’s actually leave it like this so this logic will take care of adding a product count every time we find another product for the same supplier however now we have to decide what happens when it’s a new supplier so if this condition is false if the supplier name is not on the list and this is going to be the case on the very first iteration as well because the dictionary is basically empty so there are no supplier names and for that case else we’re going to do what we had before which is just setting that number to one right this is going to be the first value so this will do two things basically it will create a new entry in this dictionary for this new supplier and it will set the product count number to one for that new supplier and that’s it that’s actually our logic and let’s actually try this out and print it out so right here i’m gonna print adding a new supplier and this is going to happen three times because we have three suppliers so we can safely print it because just gonna happen three times there is one more thing we need to fix here and that is getting the value from the cell so if we actually execute this now let’s comment this out and actually print out what the supplier name here is let’s actually get rid of this line we don’t need this and run the program you see here we have cell information so it’s not actually the the value the name of the supplier but it’s just the object cell and the reason for that is because we’re accessing a cell but we’re not actually extracting or getting the value out of it and we can do that using this value attribute on that complete object again something that you can look up in the documentation of this open pi xl module so now let’s run it again and now we have the actual values of that cell and this will take care of that small problem and now we are ready to execute our program and after the for loop actually let’s print out the dictionary because we want to see the results of the dictionary that we are building here and i’m going to execute it now and there you go first of all we have three times adding a new supplier because we have three suppliers and this is the resulting dictionary and it looks actually very good first we have company a because this was the first on the list and we have number of products that were counted for that company then we have the second one with number of products and the third one so it looks like our program did exactly what we wanted so that takes care of the first exercise now i want to note here one small thing which is an alternative syntax for getting values from a dictionary which is actually a more recommended way of doing it which is instead of having these brackets here to have a get method right to use a get function with the key name so now you see the difference between those two so this is setting the value of that key again remember key is this one here and this is the value so we are accessing the value of the dictionary using that key and get function is actually another way of grabbing this value out of a dictionary using the key name again if i execute this i should see the same result after the first exercise basically we see from which company from which supplier we have the most product or the highest number of products now in the second exercise we’re going to calculate the total inventory value per supplier meaning in our list for each product we have number of units for the product and the price so basically for each supplier we want to calculate how much is the total value of inventory of their products of all their products and again as a result we want to create a dictionary that basically tells us that value per company let’s go ahead and do that so this was calculation calculation for number of products per supplier and here we’re going to give us some space and do calculation total value per supplier or total value of inventory per supplier that’s what we want to calculate so just like we did before we’re going to create a new dictionary now and we’re going to call it appropriately total value per supplier and start with an empty dictionary again for starting in an easy way let’s consider the first very first iteration for the first supplier how are we going to calculate for the first supplier for the first product so i’m going to take this new dictionary and with our familiar syntax i’m gonna do supplier name so that’s gonna be our key and the value of the very first iteration for the first product is going to be inventory times price so for the first product we’re going to calculate how much or how many of the product items we have and number of price right that will give us value of the total inventory for that one specific product and that means we need those two values right now we’re just getting the value of the supplier so we need inventory i’m actually going to copy this so we need cell for product row and column inventory is on column two and value so whatever the product row is going to be so for each product basically for each row we need always the second column so all these values here and then we need price which going to be product list cell and we are looking for the third column for every row number three and value so now we have inventory and price per product and the way to calculate value is basically inventory that’s the number of product items times price very easy that will give us the first value for the first supplier now again the same way if we are getting a new supplier so basically in the next iteration if it’s a new supplier then this line will get executed and everything is fine however if it’s an existing supplier that we already have in the dictionary then we have to add to that previous value right instead of setting a new one so we’re going to do very similar logic as we did here so we have the supplier name we’re checking is it a new supplier or an old one an existing one this time in our new dictionary and if it is we’re gonna grab that old or existing value again using this get syntax here existing value now is hundred we want to add to that hundred right so we’re gonna grab that value this is going to be current total value and then we’re going to add to that current total value the inventory value for the current product and assign it back to our dictionary now our variable names a little bit long so the code kind of looks a bit cluttered but it’s easy to read and descriptive so you can also go for shorter variable names to have a cleaner code again matter of taste i usually name the variables something descriptive something that basically really differentiates or says what the value is about and that basically takes care of existing suppliers or the suppliers that we already have in the dictionary else we do this and this is complaining about too many blank lines so let’s fix that and that’s basically our logic again to go through it once for new suppliers again this is going to happen three times because we have three suppliers we are basically setting the total inventory price or inventory value for that specific product because remember we are iterating through products and then every time a new product iteration happens for the same supplier we basically just add an inventory price or total value for that specific product for what we already have in the dictionary for that specific supplier so now let’s again print out our dictionary let’s actually print both values so the first dictionary is this one right here supplier and number of products second one is going to be supplier and total value of all the products they have in the inventory with us execute and there you go we have both dictionaries printed here and here you see for each company we have the value in price basically right here the value for the total inventory of all the products they have on this list and we see that value per supplier and the values are decimal numbers with cent precision so 95 cents 47 cents because the prices are obviously like this as well and if you’re wondering this comma here is actually a german format for number precision so this is going to be actually equivalent to english dot and we don’t have to worry about this actually because python reads it and interprets it correctly so no problem with different language formats so that takes care of our second calculation now the third logic we’re going to write is basically printing out all the products that have inventory less than 10 like this ones here for example so the logic for that is actually going to be pretty easy what we need as a result is again a dictionary let’s call it products which have inventory under 10 like this and the value in the dictionary should be the product number which we have in the first column and the inventory count so let’s get rid of these print statements and let’s do calculation or we can do logic products with inventory less than 10. so basically as i said for each product which has inventory under 10 we want to print out or we want to save in a dictionary the product number and the inventory count so we have the inventory count already the value from the cell but we don’t have the product number we’re not accessing it so let’s actually do that product number and we already know how this works this is going to be the first column right this one here and this gives us product number and now in our dictionary products under 10 we want to add value like this product number and it’s going to be set to value of the inventory like this however we don’t want it for every product we wanted only for products with inventory less than 10 and that’s going to be an easy if conditional here if inventory again remember this logic all this logic happens for each product row right so all these get executed for each of these rows so basically we have inventory number on each iteration for each specific product and that’s why we can just say if inventory is less than 10 so if the value on that specific row is less than 10 we want to add that product the current product that we are iterating on on the list and set the value of inventory as well again we have some complaining here because of the lines and this will be the logic basically and a use case for this type of calculation would be if we find products that have inventory which are less than 10 means we need to reorder them right because they’re going to get out of stock soon and now at the end let’s print the list of all the products that have inventory less than 10. so i’m going to execute it and here we have the product number and inventory count so we have three products basically which have inventory less than 10 and let’s actually check that product number 25 right here which has inventory of seven and product number 30 inventory of six and the third one as well now you’re probably wondering why we have this dot zero here because by default those values are interpreted as float numbers and not integers if we wanted to we can actually fix that using the integer function in both cases like this let’s execute it again and we have the integers and not floats and finally as a last exercise what we’re going to do is we’re going to actually add some value inside that spreadsheet till now we have been reading the values and doing some calculations and just printing the result on the terminal as the last exercise we’re actually going to create a new column here for every row and we’re going to calculate basically the total price of inventory right the number of units times the price and we’re going to basically set the value for each product inventory multiplied by price so how do we add a column or how do we make changes to a file it’s actually pretty easy the same way as we were grabbing the value from this file and basically reading the values we can add values to it and add columns and rows etc so to add a fifth column we’re gonna do product list cell product row this is going to be the number of the row and a column number so the same way we accessed the cells for all other values we can basically access the cell on column five which has an empty value right so we’re not actually creating a new column we’re just grabbing a value of a column five which happens to be empty and we are overriding that value and we could do the same actually for any other columns here right we can overwrite all these values if we wanted to so that’s basically what we’re doing so we’re grabbing that cell and we can now save it into a variable let’s actually call it inventory price so now that cell is saved into that variable so we can reference it and note here that i didn’t add dot value at the end because if we want to update the cell we need the whole cell object right so that we can actually set a value on that so how do we set a value for that specific cell so again note that this is iteration so for each product row the value will be set so how do we set the cell value i’m just going to grab this variable here inventory price which is representing the cell in column five for each iteration and right here at the end because this is our last exercise let’s write this is a logic or basically add value for total inventory price and the way we set the value in a cell is dot value equals and the calculation for that is actually very easy we already did it here inventory times the price for that specific product and that’s it so we’re using that dot value here in order to set the value instead of grabbing the value and that will actually update and add this calculation a result of the calculation on each line on this column but note that this will only change the value in a temporary file but it’s not going to save anything right so what we want to do at the end if we want this change to persist to actually be saved we want to explicitly save the file so for example if i manually did something here added some value i would need to save it here as well right so that’s exactly what we need to do here but programmatically using python so how do we save a file using python again this package or this module that we use here also gives us a function that we can use to save the file and since we’re doing an operation on a file and not a sheet here we’re going to grab that variable in file and here at the end we’re going to call a save function on it and this will save the file changes however we’re not overriding the same file the existing inventory file we’re creating a new one and because of that we need to provide a name of the new file that is going to be created with the save function and we’re going to call that file let’s say inventory with total value and extension the same extension as we have here so this line will now save the changes and create a new file from the original one which has these values generated basically so now that we are done with the fourth exercise let’s actually print out everything that we’ve done so far i’m gonna take all those values so this is going to be execution of all our logic printing these three dictionaries here and then updating the spreadsheet file and saving it into a new file so with this let’s actually execute our program and see what happened first of all we have all those three dictionaries listed here or printed here with the values and if we pull this aside here you see a new file got generated with the name inventory with total value and if we open this file we should see that for each row a new column was generated and filled with values which is calculated for each product’s inventory and price so that’s basically our project that’s how you work with files in python specifically with spreadsheet files and as i said at the beginning this could be actually very useful automation logic when you’re working at a company where there are lots of excel files or spreadsheet files that employees have to work with and manually update stuff inside in this part we’re going to learn the concept of objects and classes in python and generally object oriented let’s consider an example of an application with lots of users for example linkedin right we have users and each user will have some information for example email address name of the user password maybe a current job title work experience a set of skills and so on right so each user will have all this information but obviously the actual values the actual information will be different for each user in addition to that users are able to do something with their own information right so for example a user can change their password change their current job title add a new skill and again basically do stuff with their own personal information and our program will be able to handle this user information plus user changing their information right so this will be user data and in order to do something so to perform some action we would have functions for that right so all of these will actually be functions however as i mentioned every user will have their own data and whenever a new user basically registers for an application all these data should be gathered for that new user and saved in the application so basically that means that in our program we need some way to define kind of a blueprint for a user for all the data user information and user behavior right things that the user can do in the application because if we have thousand users in our application obviously we can’t write the same logic and same variables thousand times right we want to have a blueprint once and then we can use the blueprint for all those thousand users and that blueprint for a user is called a class and the specific implementation of that blueprint is called an object so think of this like a blueprint of a building right you can have a blueprint once which is like a general description of building with doors and windows and everything that every single building has and then the specific implementation of that blueprint will be the actual built ready buildings right so that’s the same concept we’re going to create a class blueprint for a user and the user class blueprint will define what information a user has and what actions user can perform in the application and object then will contain the actual information like this information right here for each specific user so let’s clean all these up and let’s now actually create class user so let’s create a new file in our project and let’s actually call it user dot pi so this is going to be our user class and inside that i’m going to paste in this piece of code that basically will represent data for the user and some behavior these pieces of data are also called attributes for that class so now let’s turn all of these into a class so first of all we create a class using class special work and you also see the syntax highlighting and we’re going to call that user and you know the syntax already for functions um etc with indentation so this is going to be where our class definition goes now note here the capital letter for u for user and lowercase user in the python file name so a standard convention is that we call classes with a capital letter and the file names are written in lowercase letters and now all of these should actually go inside that indentation right like this now we said that class is a blueprint for specific objects and blueprint cannot actually have specific values right so all these needs to be removed so in the blueprint we don’t have any specific values we just have the attributes so basically we say this user will have an email name password and current job title the actual values of those attributes will be then set when we create an object from the blueprint however we need a function that will actually take those specific values and assign them to an object which is created from the blueprint and we’re gonna create that function right here in the class and that function actually is called init with underscore or two underscores at the beginning and at the end a couple of notes here first of all you see the syntax highlighting just changed to this different color second note is that these functions that start with underscore in python are special functions so python basically gives them some special meaning so it knows exactly what this init function is and we also have to call it init we can’t just call it whatever we want and final note is that this init function in python is something called a constructor again we have a blueprint and we’re constructing objects from the blueprint and this init function the constructive function will help us construct objects from that user class and now for a function syntax you know that we use these brackets right and when i start writing the bracket you see that self got automatically created as the parameter here and the reason is as i mentioned python knows what the init function is and that it’s a constructor so it knows that it needs this self as a parameter again self is also a special word in python it has a special meaning and it actually refers to this class here right this entire class if i hover over it you see self points to the user class and it will basically just help us access and reference all the attributes and functions within that class so it’s for special usage within that user class and we’re going to see examples of how to use that in a second now you can think of those attributes as variables within the class because they belong to the class right they describe basically what attributes or what characteristics this class has and in order to define that these variables belong to the class we need to use self here so and you see again syntax highlighting changed and the red line disappeared so basically we are defining that email name password and current job title belong to this class using this self keyword and now the last thing remaining in this constructor again remember constructor is to construct new objects so whenever a new object is created the specific values will be assigned to all these four variables right and those values those specific values will be passed into the constructor as parameters so email name password and current job title those four values must be provided to the constructor whenever we’re creating a new object note that these names here could be different from this these are not the same these are just parameters and using these parameter values we are going to basically set the variables or attributes of the class like this and the warning is gone as well again as i mentioned this could be something else we could call it user email so it doesn’t actually have to be the same it’s just for convenience so this function will construct an object with parameters that we provide when we actually create it and we’re going to see how to create an object later this is just the definition as remember when you define a function nothing actually happens until you call or you use that function so right here we’re just defining that function so that we can use it later so constructor logic is done now we have these two functions that any user in our application can do right any user can change their password or change their job title and logically when change password happens by user basically user provides a new password in order to override the old one so the flow will be following the object will be created for the specific user so the initial data for that object will be provided so we’ll have the user email name password and current job title and later at some point user may decide to change their password and their current job title and that means the initial data will be changed and that means that we’re actually changing the attributes self.password with a new password right so logic will be like this now we have red lines here why because we need this self as a parameter first of all we also have that as um note right here so just like here we need to actually pass that self as a parameter that’s just how it is because we need to access attributes of that class in that function and new password will be new password variable will be the new password basically that user wants to set so this will change the initial password with the new one and the same way in change.title we have self as a first parameter we always need it in all the functions because otherwise we cannot access the attributes in the class and new job title so now let’s review this class that we created first of all we have this class keyword here with a capital letter for user you already know the syntax with colon and then indentation so this all of these inside this indentation is class body so part of the class logic first we have this init constructor that sets the initial values of that class attributes whenever we create a specific object for that class right so this happens only when we construct a new object and then on that constructed object we can change password we can change job title and note that right now we have nothing basically hard coded we have no specific values here right everything is just parameterized and also this is just a definition for class and its functions nothing will actually happen when we execute this because we’re not creating any user objects so if i right click here and execute this run user you see that nothing happened because the class definition was created but we’re not doing anything with that class definition we’re not creating new users so now let’s actually go ahead and do that in the same file in user.py i would actually use that class blueprint to construct a new user object and creating an object from a class is actually very simple we just write name of the class and parentheses this is actually the same syntax as calling the function with parameters and the parameters that we need to give that class are these four values here and note that calling this user class function basically in the background we’ll call init function right so the constructor will be called whenever we write this syntax with class name and parentheses and this init constructor as you see expects four parameters so we have to provide all those parameters right here in the parenthesis so let’s actually provide them let’s do user email like this my username and password and a current job title again very similar to calling a function and this will actually construct a new object from the user class which has these four attributes with values that we just provided here and has these two functions that we can use to either change a password or change job title one note here is that functions that belong to a class are actually called methods so there’s a special name for functions which are part of a class so we can refer to them as methods so user object basically gives us two methods that we can use now again if we execute this program now we will not see anything even though user will be created because we’re not printing anything to the console we’re not doing anything so let’s do that run user nothing happens because we need to print a message or some kind of information so what i’m going to do now is inside that class i’m going to create a function or a method as we learned now that basically prints back some user information right prints me the name email and current job title because we don’t want to display password so let’s give us some space here and let’s create a function called get user info so that we can see something and again as soon as i typed in these first parentheses self got generated because we need self in every function within the class and in the function body we’re gonna print user information so let’s say user and name of the user which we can access using self remember all the attributes that the object has can be accessed with this special word here so self dot name so user whatever the user’s name is currently works as a and now we need the job description or job title and you can contact them at and now we can use the email so this message will be printed for the user again because this will be used for any user of our application the message these parts will be the same but each user will have their own different name different job title and different email address so all of these are and written as variables because we don’t know these values up front so now we can actually use this function or method to print out information of a specific user so how do we use or how do we call that function of the user we first save it into a variable app user one or nana doesn’t really matter let’s call it app user one so it’s generic so how do we use that function to print out the information about the user if i do app user one and dot you see that i have the attributes here the four attributes that our user object has or user class and we have these three methods of the class get user infor change job title and change password so using get info we can call this function and if i execute this right here you see user nanogenasia currently works as a devops engineer you can contact them at this email and now let’s say we want to change job title of that user we do that in the same way app user one dot change job title and we’re gonna provide the job title parameter note that even though you see two parameters here on that function this first parameter is passed in automatically so we don’t have to basically pass that self right it’s already done automatically we just have to worry about these parameters so new job title is let’s say devops trainer and now we can call that user info method again and execute and you see first message printed here before we change the job title now it’s devops trainer so that’s how we can create a new object from a class and we can use methods of that object by first saving that object into a variable and then calling that function on that variable and obviously now this is just one user but if we had another one user two that’s actually clean this up we can create a new user with different values like this they have their own email own name own password and on job title and again we can create that user and basically just use the methods defined in the class and in two different cases or for two different users obviously the user info will be different so let’s execute this and right here you see the user information for both users and obviously if you have an application like linkedin you don’t have two users or a thousand users you probably have millions of users and having a user definition once and reusing it every time a new user gets created or basically existing users do something in application is only possible when using classes and objects instead of just having all these logic non-structured throughout the code and again in this type of applications you would not have four attributes and three methods you will have probably hundreds of attributes and hundreds of such methods now as you see here we have created this user.pi file for user class but we’re also creating these objects in the same file which actually doesn’t make sense because the file should be only for defining the class right so all of this logic actually needs to move out from here and this should be just only for class definition so in the application again using an example of linkedin we would have class user and then we would have a class post right whenever someone posts something each post will have their own attributes like the actual message or text in that post the author who wrote the post how many likes it has etc as well as specific functions right for example changing the post commenting on the post etc so you will have separate file for each such class right in the application and then you would have one file somewhere else this could be a main dot pi where you would actually use all those different classes and create objects from those classes and that means that logic that we wrote here constructing a user object and then calling some functions on that will actually happen in another file in our case let’s use main.pi and now let’s see how we’re going to do that i’m going to paste in the code that i copied from there and as soon as i paste in you see those red lines so basically main.pi says that it cannot find a reference to user so this file doesn’t know anything about the user class so how do we fix that or how do we make this user class available in another file and if you remember when we needed to use modules or basically functions variables whatever from other files in python we use import to basically import those functions and make them available here or import the whole module to make its functions and variables available here and the same way we can import classes from another file import user and note here that i’m using the name of the file user lowercase and not the class name with capital user right so we are importing that file so now we can use anything that is defined in that file and one of them is class called user and the way we can access that class now is using the name of module and not the class user itself and this is basically exactly the same concept as we saw before because we are importing a module called user remember every python file that has functions or variables or classes inside is a module so we are importing a module and once we have that module imported now we can use and access functions variables or classes of that module and we can do that by copying the name of the module dot and there you go in the same way here so exactly the same concept whether this is a function or a class doesn’t matter we use it the same way remember when we use the date time module with the syntax datetime.daytime and that was an example of using a class from a module now user.user may look a little bit weird so we can use our familiar import statement where instead of importing the whole module we can pick and choose and import specific definitions or specific elements of that module in our case we just have one element which is the class so we’re going to say from user module import user class and now we don’t need the module name anymore because we imported the class itself and now if we execute main dot p y let’s do it again here we have the same result for two of our users and again as i said in applications you will have multiple classes that are connected to each other so for example if we have a post here post blueprint basically whenever a new post gets created with some specific values like the actual message and creation date time etc it will also have an author and that author will actually be one of those user objects right so you will have some functions here that actually reference the post and we can also see that in action let’s actually create a post class let’s give it just two attributes to keep it simple so we need a constructor here in it and we’re gonna pass in message and author right this is gonna be the user who wrote it and you know the drill already and let’s create another function which displays a post with its respective author so let’s do get post info again we have self here and let’s print post written by and the author name so this is going to be our simple post class and user is able to create new posts so we have the blueprint for a post and the same way we can create that post inside the main dot pi so first let’s import the post class and then here we’re going to create a new post in pycharm you get this nice display of parameters that function or class basically expects so we have message and author let’s do some message or post and as a second parameter we have the author and we can use the name of a user so let’s do app user to dot name and this will create an object also called instance in programming special instance of that post class and then we can print the information of that post first assign it to a variable let’s say it’s a new post and on a new post we’re gonna call get post info let’s actually run this application now and see the result and here we have our post message that gets printed by this get post info method in the post class and at the beginning i mentioned object oriented programming which basically means that when you’re writing your code with objects and classes like this to create blueprints and then use those blueprints for specific instances that’s called object-oriented programming and also an interesting note here is that in python almost everything is actually an object for example the data types like string integer list set etc when we printed them out we saw class of string or class of list so these data types are also classes in python and this int or sdr for string functions we called where actually the constructor we called to create a string or integer object and the constructor of int for example took a string representation of a number and in its init function and constructed an integer out of it now for us in terms of using these data types and variables etc it doesn’t actually matter but it’s just an interesting thing to know about how this whole thing works in python in this part we’re going to learn how to use python to talk to external applications in our case we’re going to use gitlab and then application and just note here that communication between two applications in our case our python application and a gitlab application usually happens using a common protocol like http so basically our python application will send an http request to gitlab application and from the gitlab application it will get an http response for that request so just know that http is just a protocol that these two applications can communicate with over the internet i have a couple of projects on gitlab so we’re gonna write a very simple python application that basically goes to gitlab and asks for the list of projects for my user and then just prints it here in our run window and the concept of one application talking to another is basically done using something called api requests so the remote application in this case gitlab has an api so these are functions basically that gitlab makes available for other applications to call and we’re going to call those functions from our python application in order to get the list of projects for my user and that communication or python basically asking for this information is going to be an api request or api call and what we get in response from this gitlab api is going to be api response so let’s go ahead and do that in python in order to make those external requests to remote applications we’re going to need a module called requests this is a generic module that you can use for any external application and as i mentioned at the beginning the communication happens using http protocol between two applications and as you see here also in the module description it says an http library which allows you to send http requests and then receive http responses from another application and that’s exactly what we’re going to be doing and this request module is not part of python so we’re going to install it using pip again remember that we’re using pip that actually comes packaged with the pycharm so in the terminal window of my ide of pycharm i’m going to execute peep install requests successfully installed request this is the version of that module and if i expand this external library’s site packages i’m going to see the requests package in the list great so once we have the module available locally we can import that module in our file and this requests module now has or package actually has functions variables and objects that we can use to talk to these remote applications like gitlab as i said gitlab is just one example you can talk to any remote application that has an api and we can not only do requests for getting the existing information but we can also make requests to change something in that remote application so for example i can write a python application that will actually create a new project on my gitlab account but to keep the demo simple we’re just going to be fetching information from gitlab so how do we make requests to an api of an application with this requests module we get a function called get and get takes one main parameter which is url so basically we need to tell python where to find that remote application or again in our case where to find gitlab to talk to it so we need the url of gitlab and where do you find this url information of a remote application you can basically google that every application has their own documentation where you can see the urls so for example for gitlab i actually googled it so if i do gitlab api documentation like this let’s make it bigger so you have basically description for the api and what type of information you can get from gitlab and also what kind of things you can create in gitlab and you see an example api here that basically just lists all the projects however we want to list projects of one specific user in this case i want to list my own projects and in this documentation i found this list user project section where i have an example of how to use projects for a specific user so we have slash users and the user id so that’s going to be my gitlab user id and projects so basically the url will now look like this first we’re gonna have this base url so that’s basically https gitlab.com api v4 and all the things that we want to do is going to be at this base api and after that we can basically depending on what exactly we want to do we can choose one specific action and again going back this is the action we want to execute on this base url so from gitlab we want projects that belong to user and right here i’m going to add my own gitlab user id so if you have a github account you should add your own user id here and that’s going to be an api url for user projects and this will actually give us some kind of response so requests.get will make that request to gitlab and it will return some kind of response and we can save that response into a variable so let’s call this variable response because that’s what it is and on the next line let’s actually print and see what’s in that response let’s run our application and right here you see we have an object response with a code here 200 is a code for a successful request but we’re not seeing the actual contents right we want to see the projects with their details and in order to get that we’re gonna do dot and text and let’s actually execute this now and now you see these square brackets which means it is a list because we have a list of projects and this whole bunch of information about projects there and you also see curly braces so this is a list of dictionaries and each dictionary holds information of one specific project now if i actually print the type of that response text like this see that it is a string so even though we see the format is actually a list of dictionaries we’re getting a string because we’re accessing text attribute now there is actually another attribute which will give us the same thing but as an actual list of dictionaries instead of string and this will be actually a better way to get that information because then we can work on it so we can look through it and get the individual elements and access the values so what i’m gonna do now instead of dot text i’m gonna use json json is a standard format that all programming languages understand and usually when two applications communicate with each other which are written in different languages and with different technologies with json they have a common format for communication and this requests module basically gives us this json function to read the json format that gitlab sent us so json function will read the json response from gitlab and turn it into one of the python data types so i’m going to execute this now and now you see that response.json actually gave us list data type instead of string so again for demonstration since this is a list i’m going to access the first element of that list and print that out and right here you see that is actually the first element just the first one from the list and that element is a dictionary as you see so all these just to give you an idea of what we’re getting back from that gitlab api and what we can do with that response or how we can actually work with that response so i’m gonna clean all this up and we saw that response.json gives us exactly what we want and that is a list of my projects so let’s call this variable my projects and now what i want to do with this is i want to print out in our window for each project project name and project url so basically the repository url for that project so i don’t want to have any other values like id or description or whatever other stuff i have in this dictionary i just want name and project url for every single project and i want that information printed out in this window so how do we do that we have a list so we’re gonna loop through that list to access each element inside that list so you remember we have for loop to loop through or iterate through a list and give us access to each element one at a time so here i’m going to write for loop and if you remember the syntax of for loop we have four and then a variable which will represent the single element in that list and in this case it’s going to be a project a single project and then we have in list so for project in my projects do something so for every project element in this my projects list we want to print out the name and the url so right here i will do print and let’s do our formatted string here and let’s start writing our message let’s do project name and the project name will be this one right here now how do we actually access the name of the project in each project element as you see here these project elements are actually dictionaries and how do we access a value in a dictionary using the name of the dictionary in this case our variable project so this whole thing is going to be saved into a variable called project and then on that variable on the dictionary we’re going to pass in the name of the key which is name now i’ve been using double quotes throughout our project and for a syntax for dictionaries as well like this right however here we have a small problem which is we have double quotes inside the double quotes but as you remember for string representation we can actually use single quotes as well as double quotes and this is one of the really important use cases for why we can actually use both single and double quotes for a string and that is if we have a string inside another string like right here we can actually use that interchangeably so that we don’t have this problem here so now as you see back to normal everything works because now python knows okay this is another string which we’re using inside this string so we can use these interchangeably as we want so this could be single quotes and this could be double quotes wouldn’t really matter but that’s a really good use case why we need both types of quotes so we have the project name now we need a project url and let’s see where the project url is in our dictionary this is one element one dictionary right so i’m gonna scroll it to the left and we have web url this is what we could use or we could also use http url to repo let’s go with the web url so again this is a key inside the dictionary so we can access the value so this is actually the value we need and we can access that using the dictionary name projects and the key name which is web url and this is actually project not projects and this code will now print name and url for each project so let’s actually execute our program and as you see we have project name and project url for each project we can make the output a little bit cleaner let’s do a new line here and a new line here so we can separate the projects from each other and run again and there you go this looks a little bit cleaner for each project we have a name and a url so if i click inside i’ll go directly to this project so that’s basically a very simple example of how to use requests module to talk to external applications or external urls and then do something with the response that we get from that external application by first converting that into an actual data type that we’re getting using json function so in our case it was a list and that’s why json function actually converted it into a list if the response was a dictionary instead of at least then json would convert it into a dictionary and then we can do something with that response value congratulations you made it till the end i hope you learned a lot and got some valuable knowledge from this course if you like the course please leave a thumbs up on this video on my channel i actually cover lots of different devops topics like docker ci cd terraform and more so be sure to check out my tutorials if you’re learning python to become a devops engineer i actually have a complete devops bootcamp with all the technologies you need to learn as a devops engineer which also includes a module for automation with python with several cool demo projects to automate some common devops tasks like application and server monitoring cloud automation tasks with aws jenkins etc so if you’re interested check out more info in the description also happy to connect with you on social media so i would love to see you there with that said thank you for watching and see you in the next video

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Harvard CS50’s Artificial Intelligence with Python – Full University Course

    Harvard CS50’s Artificial Intelligence with Python – Full University Course

    This source explains how AI can be used for problem-solving, moving from explicit instructions to learning from data. It introduces supervised learning, where AI learns to map inputs to outputs using labeled datasets, covering classification tasks and nearest neighbor algorithms. The source also discusses linear regression, support vector machines, and techniques like perceptron learning. It transitions to reinforcement learning, where AI learns through rewards and punishments in an environment, and touches on unsupervised learning with clustering techniques like k-means. Finally, the document explores neural networks, detailing their structure, training via gradient descent and backpropagation, and their applications in various AI problems.

    Propositional Logic, Model Checking, and Beyond: A Comprehensive Study Guide

    I. Review of Key Concepts

    • Propositional Logic: A system for representing logical statements and reasoning about their truth values.
    • Propositional Symbols: Variables representing simple statements that can be either true or false (e.g., P, Q, R).
    • Logical Connectives: Symbols used to combine propositional symbols into more complex statements:
    • and (∧): Both statements must be true for the combined statement to be true.
    • or (∨): At least one statement must be true for the combined statement to be true.
    • not (¬): Reverses the truth value of a statement.
    • implies (→): If the first statement is true, then the second statement must also be true.
    • biconditional (↔): Both statements have the same truth value (both true or both false).
    • Knowledge Base (KB): A set of sentences representing facts known about the world.
    • Query (α): A question about the world that we want to answer using the KB.
    • Entailment (KB ⊨ α): The relationship between the KB and a query, meaning that the KB logically implies the query; whenever the KB is true, the query must also be true.
    • Model: An assignment of truth values (true or false) to all propositional symbols in the language. Represents a possible world or state.
    • Model Checking: An algorithm for determining entailment by enumerating all possible models and checking if, in every model where the KB is true, the query is also true.
    • Inference Algorithm: A procedure to derive new sentences from existing ones in the KB.
    • Inference Rules: Logical equivalences used to manipulate and simplify logical expressions (e.g., implication elimination, De Morgan’s laws, distributive law).
    • Soundness: An inference algorithm is sound if it only derives conclusions that are entailed by the KB.
    • Completeness: An inference algorithm is complete if it can derive all conclusions that are entailed by the KB.
    • Conjunctive Normal Form (CNF): A logical sentence expressed as a conjunction (AND) of clauses, where each clause is a disjunction (OR) of literals.
    • Clause: A disjunction of literals (e.g., P or not Q or R).
    • Literal: A propositional symbol or its negation (e.g., P, not Q).
    • Resolution: An inference rule that combines two clauses containing complementary literals to produce a new clause.
    • Factoring: Removing duplicate literals within a clause.
    • Empty Clause: The result of resolving two contradictory clauses, representing a contradiction (always false).
    • Inference by Resolution: An algorithm for proving entailment by converting the KB and the negation of the query to CNF, and then repeatedly applying the resolution rule until the empty clause is derived.
    • Joint Probability Distribution: A table showing the probabilities of all possible combinations of values for a set of random variables.
    • Inclusion-Exclusion Formula: A formula for calculating the probability of A or B: P(A or B) = P(A) + P(B) – P(A and B).
    • Marginalization: Calculating the probability of a variable by summing over all possible values of other variables: P(A) = Σ P(A and B).
    • Conditioning: Expressing the probability of A in terms of the conditional probability of A given B and the probability of B: P(A) = P(A|B) * P(B) + P(A|¬B) * P(¬B).
    • Conditional Probability: The probability of event A occurring given that event B has already occurred, denoted P(A|B).
    • Random Variable: A variable whose value is a numerical outcome of a random phenomenon.
    • Heuristic Function: An estimate of the “goodness” of a state (e.g., the distance to the goal).
    • Local Search: A class of optimization algorithms that start with an initial state and iteratively improve it by moving to neighboring states.
    • Hill Climbing: A local search algorithm that repeatedly moves to the neighbor with the highest value.
    • Steepest Ascent Hill Climbing: Chooses the best neighbor among all neighbors in each iteration.
    • Stochastic Hill Climbing: Chooses a neighbor randomly from the neighbors that are better than the current state.
    • First Choice Hill Climbing: Chooses the first neighbor with a higher value and moves there.
    • Random Restart Hill Climbing: Runs hill climbing multiple times with different initial states and returns the best result.
    • Local Beam Search: Keeps track of k best states and expands all of them in each iteration.
    • Local Maximum/Minimum: A state that is better than all its neighbors but not the best state overall.
    • Simulated Annealing: A local search algorithm that sometimes accepts worse neighbors with a probability that decreases over time (temperature).
    • Temperature (in Simulated Annealing): A parameter that controls the probability of accepting worse neighbors; high temperature means higher probability, and low temperature means lower probability.
    • Delta E (ΔE): The difference in value (or cost) between the current state and a neighboring state.
    • Traveling Salesman Problem (TSP): Finding the shortest possible route that visits every city and returns to the origin city.
    • NP-Complete Problems: A class of problems for which no known polynomial-time algorithm exists.
    • Linear Programming: A mathematical technique for optimizing a linear objective function subject to linear equality and inequality constraints.
    • Objective Function: A mathematical expression to be minimized or maximized in linear programming.
    • Constraints: Restrictions or limitations on the values of variables in linear programming.
    • Constraint Satisfaction Problem (CSP): A problem where the goal is to find values for a set of variables that satisfy a set of constraints.
    • Variables (in CSP): Entities with associated domains of possible values.
    • Domains (in CSP): The set of possible values that can be assigned to a variable.
    • Constraints (in CSP): Restrictions on the values that variables can take, specifying allowable combinations of values.
    • Unary Constraint: A constraint involving only one variable.
    • Binary Constraint: A constraint involving two variables.
    • Node Consistency: Ensuring that all values in a variable’s domain satisfy the variable’s unary constraints.
    • Arc Consistency: Ensuring that for every value in a variable’s domain, there exists a consistent value in the domain of each of its neighboring variables.
    • AC3: A common algorithm for enforcing arc consistency.
    • Backtracking Search: A recursive algorithm that explores possible solutions by trying different values for variables and backtracking when a constraint is violated.
    • Minimum Remaining Values (MRV) Heuristic: A variable selection strategy that chooses the variable with the fewest remaining legal values.
    • Degree Heuristic: A variable selection strategy that chooses the variable involved in the largest number of constraints on other unassigned variables.
    • Least Constraining Value Heuristic: A value selection strategy that chooses the value that rules out the fewest choices for neighboring variables in the constraint graph.
    • Supervised Machine Learning: A type of machine learning where an algorithm learns from labeled data to make predictions or classifications.
    • Inputs (x): The features or attributes used by a machine learning model to make predictions.
    • Outputs (y): The target variables or labels that a machine learning model is trained to predict.
    • Hypothesis Function (h): A mathematical function that maps inputs to outputs.
    • Weights (w): Parameters in a machine learning model that determine the importance of each input feature.
    • Learning Rate (α): A parameter that controls the step size during training.
    • Threshold Function: A function that outputs one value if the input is above a threshold and another value if the input is below the threshold.
    • Logistic Regression: A statistical method for binary classification using a logistic function to model the probability of a certain class or event.
    • Soft Threshold: A function that smoothly transitions between two values, allowing for outputs between 0 and 1.
    • Dot Product: A mathematical operation that multiplies corresponding elements of two vectors and sums the results.
    • Gradient Descent: An iterative optimization algorithm for finding the minimum of a function.
    • Stochastic Gradient Descent: An optimization algorithm that updates the parameters of a machine learning model using the gradient computed from a single randomly chosen data point.
    • Mini-Batch Gradient Descent: An optimization algorithm that updates the parameters of a machine learning model using the gradient computed from a small batch of data points.
    • Neural Networks: A type of machine learning model inspired by the structure of the human brain, consisting of interconnected nodes (neurons) organized in layers.
    • Activation Function: A function applied to the output of a neuron in a neural network to introduce non-linearity.
    • Layers (in Neural Networks): A level of nodes that receive input from other nodes and pass their output to additional nodes.
    • Natural Language Processing (NLP): The branch of AI that deals with the interaction between computers and human language.
    • Syntax: The set of rules that govern the structure of sentences in a language.
    • Semantics: The meaning of words, phrases, and sentences in a language.
    • Formal Grammar: A set of rules for generating sentences in a language.
    • Context-Free Grammar: A type of formal grammar where rules consist of a single non-terminal symbol on the left-hand side.
    • Terminal Symbol: A symbol that represents a word in a language.
    • Non-Terminal Symbol: A symbol that represents a phrase or category of words in a language.
    • Rewriting Rules: Rules that specify how non-terminal symbols can be replaced by other symbols.
    • Noun Phrase: A phrase that functions as a noun.
    • Verb Phrase: A phrase that functions as a verb.
    • Natural Language Toolkit (NLTK): A Python library for NLP.
    • Parsing: The process of analyzing a sentence according to the rules of a grammar.
    • Syntax Tree: A hierarchical representation of the structure of a sentence.
    • Statistical NLP: An approach to NLP that uses statistical models learned from data.
    • n-gram: A contiguous sequence of n items from a sample of text.
    • Markov Chain: A sequence of events where the probability of each event depends only on the previous event.
    • Tokenization: The process of splitting a sequence of characters into pieces (tokens).
    • Text Classification: The task of assigning a category label to a text.
    • Sentiment Analysis: Determining the emotional tone or attitude expressed in a piece of text.
    • Bag-of-Words Model: A text representation that represents a document as the counts of its words, disregarding grammar and word order.
    • Term Frequency (TF): The number of times a term appears in a document.
    • Inverse Document Frequency (IDF): A measure of how rare a term is across a collection of documents.
    • TF-IDF: A weight used in information retrieval and text mining that reflects how important a word is to a document in a corpus.
    • Stop Words: Common words that are often removed from text before processing.
    • Word Embeddings: Vector representations of words that capture semantic relationships.
    • One-Hot Representation: A vector representation where each word is represented by a vector with a 1 in the corresponding index and 0s elsewhere.
    • Distributed Representation: A vector representation where the meaning of a word is distributed across multiple values.
    • Word2Vec: A model for learning word embeddings.

    II. Short Answer Quiz

    1. Explain the difference between soundness and completeness in the context of inference algorithms. Soundness means that any conclusion drawn by the algorithm is actually entailed by the knowledge base. Completeness means that the algorithm is capable of deriving every conclusion that is entailed by the knowledge base.
    2. Describe the process of converting a logical sentence into Conjunctive Normal Form (CNF). The process involves eliminating bi-conditionals and implications, moving negations inward using De Morgan’s laws, and using the distributive law to get a conjunction of clauses where each clause is a disjunction of literals.
    3. What is the purpose of using the resolution inference rule in propositional logic? The resolution rule is used to derive new clauses from existing ones, aiming to ultimately derive the empty clause, which indicates a contradiction and proves entailment.
    4. Explain the marginalization rule and provide a simple example. Marginalization calculates the probability of a variable by summing over all possible values of other variables. For example, if you want to know the probability that someone likes ice cream, you would take the probability of them liking ice cream and liking chocolate times the probability that they like chocolate.
    5. What is the key idea behind local search algorithms? Local search algorithms start with an initial state and iteratively improve it by moving to neighboring states, based on some evaluation function, without necessarily keeping track of the path taken to reach the solution.
    6. Describe how simulated annealing helps to avoid local optima. Simulated annealing accepts worse neighbors with a probability that decreases over time, allowing the algorithm to escape local optima early in the search and converge towards a global optimum later.
    7. In linear programming, what are the roles of the objective function and constraints? The objective function is what we want to minimize or maximize, while constraints are limitations on the values of variables that must be satisfied.
    8. What is the purpose of enforcing arc consistency in a constraint satisfaction problem (CSP)? Enforcing arc consistency reduces the domains of variables by removing values that cannot be part of any solution due to binary constraints, making the search for a solution more efficient.
    9. Explain the difference between a one-hot representation and a distributed representation in NLP. A one-hot representation represents a word as a vector with a 1 in the corresponding index and 0s elsewhere, while a distributed representation distributes the meaning of a word across multiple values in a vector.
    10. How do word embedding models like Word2Vec capture semantic relationships between words? Word2Vec captures semantic relationships by training a model to predict the context words surrounding a given word in a large corpus, resulting in vector representations where similar words are located close to each other in vector space.

    III. Essay Questions

    1. Compare and contrast model checking and inference by resolution as methods for determining entailment in propositional logic. Discuss the advantages and disadvantages of each approach.
    2. Explain how local search algorithms can be applied to solve optimization problems. Discuss the challenges of local optima and describe techniques, such as simulated annealing, for overcoming these challenges.
    3. Describe the general framework of a constraint satisfaction problem (CSP). Discuss the role of variable and value selection heuristics in improving the efficiency of backtracking search for solving CSPs.
    4. Explain the process of training a machine learning model for sentiment analysis. Discuss the different text representation techniques, such as bag-of-words and TF-IDF, and the role of word embeddings.
    5. Describe the key concepts in Natural Language Processing (NLP), including syntax and semantics. Discuss how NLP techniques are used to understand and generate natural language.

    IV. Glossary of Key Terms

    • Activation Function: A function applied to the output of a neuron in a neural network to introduce non-linearity, enabling the network to learn complex patterns.
    • Arc Consistency: A constraint satisfaction technique ensuring that for every value in a variable’s domain, there exists a consistent value in the domain of each of its neighboring variables based on the problem constraints.
    • Backtracking Search: A recursive algorithm that explores possible solutions by trying different values for variables and backtracking when a constraint is violated, allowing the algorithm to systematically search the solution space.
    • Bag-of-Words Model: A text representation in NLP that represents a document as the counts of its words, disregarding grammar and word order, which helps quantify the content of texts for analysis.
    • Clause: In logic, it is the statement that combines different literals with “or” relationship.
    • Complete: An inference algorithm that can derive all conclusions entailed by the KB.
    • Conditioning: A probability rule that expresses the probability of one event in terms of its conditional probability, and this rule is used to find the probabilities that are unknown with the information given.
    • Conjunctive Normal Form (CNF): A standardized logical sentence expressed as a conjunction (AND) of clauses, where each clause is a disjunction (OR) of literals, simplifying logical deductions.
    • Constraints: Limitation to the conditions of the variables in linear programing or constraint satisfaction problems.
    • Context-Free Grammar: A type of formal grammar where rules consist of a single non-terminal symbol on the left-hand side, used to define the syntax of programming languages.
    • Delta E (ΔE): The difference in value between the current state and its neighboring states.
    • Distributed Representation: It describes the meaning of the representation of a word distributing over multiple values in vector which is the idea behind the word embedding technique.
    • Domain: The set of possible values that can be assigned to a variable.
    • Entailment (KB ⊨ α): KB logically implies that α; whenever KB is true, so does α, which is the relationship that is important when the machine needs to find if the conclusion is correct or not.
    • Formal Grammar: A set of rules for generating sentences in a language, and those rules are applied in order to find what it is that is trying to be said in language analysis.
    • Heuristic Function: It estimates the ‘goodness’ of a state (e.g., the distance to the goal), which will let machine learning models take efficient and near perfect results.
    • Hill Climbing: This iterative optimization algorithm is characterized by continuously searching to find better solution while moving to a better neighbor and also have the highest value.
    • Hypothesis Function (h): This function maps inputs to outputs and can be used to learn and predict.
    • Inclusion-Exclusion Formula: Used to find the P(A or B), in which it finds the P(A), P(B), P(A and B), and finds P(A)+P(B)-P(A and B) in result.
    • Inference Algorithm: A procedure to derive new sentences from existing ones in the KB.
    • Joint Probability Distribution: A table showing the probabilities of all possible combinations of values for a set of random variables.
    • Knowledge Base (KB): A set of sentences representing facts known about the world.
    • Layers (in Neural Networks): A level of nodes that receive input from other nodes and pass their output to additional nodes.
    • Learning Rate (α): It controls the step size during the machine learning algorithm.
    • Linear Programming: A mathematical technique for optimizing a linear objective function subject to linear equality and inequality constraints.
    • Literal: A propositional symbol or its negation (e.g., P, not Q) that describes the condition of a statement.
    • Local Maximum/Minimum: A state that is better than all its neighbors but not the best state overall.
    • Local Search: A class of optimization algorithms that start with an initial state and iteratively improve it by moving to neighboring states.
    • Logistic Regression: A statistical method for binary classification using a logistic function to model the probability of a certain class or event.
    • Marginalization: Calculating the probability of a variable by summing over all possible values of other variables: P(A) = Σ P(A and B).
    • Markov Chain: A sequence of events where the probability of each event depends only on the previous event, allowing modeling of sequences over time.
    • Model: An assignment of truth values (true or false) to all propositional symbols in the language that represents the state.
    • Model Checking: An algorithm for determining entailment by enumerating all possible models and checking if, in every model where the KB is true, the query is also true.
    • n-gram: A contiguous sequence of n items from a sample of text that helps in analyzing languages and predicting text.
    • Natural Language Processing (NLP): The field of AI that is related to the understanding of human language.
    • Noun Phrase: A phrase that functions as a noun to use for language parsing.
    • NP-Complete Problems: A class of problems for which no known polynomial-time algorithm exists.
    • Objective Function: An mathematical function to be minimized or maximized in linear programming.
    • One-Hot Representation: A vector representation where each word is represented by a vector with a 1 in the corresponding index and 0s elsewhere.
    • Parsing: This process of taking a sentence and analyzing it according to grammar rules in NLP.
    • Propositional Logic: A system for representing logical statements and reasoning about their truth values.
    • Query (α): The question that we want to answer using the KB.
    • Random Variable: A variable whose value is a numerical outcome of a random phenomenon.
    • Rewriting Rules: Rules that specify how non-terminal symbols can be replaced by other symbols.
    • Semantics: the meaning of words, phrases, and sentences in a language, which helps with extracting the insights and understanding of language.
    • Simulated Annealing: A local search algorithm that sometimes accepts worse neighbors with a probability that decreases over time (temperature).
    • Soft Threshold: A function that smoothly transitions between two values, allowing for outputs between 0 and 1.
    • Soundness: An inference algorithm is sound if it only derives conclusions that are entailed by the KB.
    • Statistical NLP: An approach to NLP that uses statistical models learned from data.
    • Steepest Ascent Hill Climbing: Chooses the best neighbor among all neighbors in each iteration.
    • Stop Words: Common words that are often removed from text before processing.
    • Syntax: The set of rules that govern the structure of sentences in a language.
    • Syntax Tree: A hierarchical representation of the structure of a sentence, used to know how a structure looks with a graphical approach.
    • Temperature (in Simulated Annealing): A parameter that controls the probability of accepting worse neighbors; high temperature means higher probability, and low temperature means lower probability.
    • Tokenization: The process of splitting a sequence of characters into pieces (tokens), which allows for language parsing and to read for machines.
    • Traveling Salesman Problem (TSP): Finding the shortest possible route that visits every city and returns to the origin city.
    • Unary Constraint: A constraint involving only one variable.
    • Verb Phrase: A phrase that functions as a verb to be analyzed in parsing.
    • Weights (w): Parameters in a machine learning model that determine the importance of each input feature, letting it know the emphasis on each feature.
    • Word Embeddings: Vector representations of words that capture semantic relationships.
    • Word2Vec: A model for learning word embeddings by knowing what words mean, learning and classifying similar words.

    AI: Reasoning, Search, NLP, and Learning Techniques

    Here’s a briefing document summarizing the main themes and ideas from the provided sources.

    Briefing Document: Artificial Intelligence – Reasoning, Search, and Natural Language Processing

    Overview:

    The sources cover several fundamental concepts in Artificial Intelligence (AI), including logical reasoning, search algorithms, probabilistic reasoning, and natural language processing (NLP). They explore techniques for representing knowledge, drawing inferences, solving problems through search, handling uncertainty, and enabling computers to understand and generate human language.

    I. Logical Reasoning and Inference:

    • Entailment and Inference Algorithms: The core idea is that AI systems should be able to determine if a knowledge base (KB) entails a query (alpha). This means: “Given some query about the world…the question we want to ask…is does KB, our knowledge base, entail alpha? In other words, using only the information we know inside of our knowledge base…can we conclude that this sentence alpha is true?”
    • Model Checking: This is a basic inference algorithm. It involves enumerating all possible models (assignments of truth values to variables) and checking if, in every model where the knowledge base is true, the query (alpha) is also true. “If we wanted to determine if our knowledge base entails some query alpha, then we are going to enumerate all possible models…And if in every model where our knowledge base is true, alpha is also true, then we know that the knowledge base entails alpha.”
    • Inference Rules: These are logical transformations used to derive new knowledge from existing knowledge. Examples include:
    • Implication Elimination: alpha implies beta can be transformed into not alpha or beta. “This is a way to translate if-then statements into or statements… if I have the implication, alpha implies beta, that I can draw the conclusion that either not alpha or beta”
    • Biconditional Elimination: a if and only if b becomes a implies b and b implies a.
    • De Morgan’s Laws: These laws relate ANDs and ORs through negation. not (alpha and beta) is equivalent to not alpha or not beta. And not (alpha or beta) is equivalent to not alpha and not beta. “If it is not true that alpha and beta, well, then either not alpha or not beta… if you have a negation in front of an and expression, you move the negation inwards, so to speak…and then flip the and into an or.”
    • Distributive Law: alpha and (beta or gamma) is equivalent to (alpha and beta) or (alpha and gamma).
    • Conjunctive Normal Form (CNF): A standard form for logical sentences where it is represented as a conjunction (AND) of clauses, where each clause is a disjunction (OR) of literals (propositional symbols or their negations). “A conjunctive normal form sentence is a logical sentence that is a conjunction of clauses…a conjunction of clauses means it is an and of individual clauses, each of which has ors in it.”
    • Resolution: An inference rule that applies to clauses in CNF. If you have P or Q and not P or R, you can resolve them to get Q or R. This involves dealing with factoring (removing duplicate literals) and the empty clause (representing a contradiction). “…if I have two clauses where there’s something that conflicts or something complementary between those two clauses, I can resolve them to get a new clause, to draw a new conclusion.”
    • Inference by Resolution: To prove that a knowledge base entails a query (alpha), we assume not alpha and try to derive a contradiction (the empty clause) using resolution. “We want to prove that our knowledge base entails some query alpha…we’re going to try to prove that if we know the knowledge and not alpha, that that would be a contradiction…To determine if our knowledge base entails some query alpha, we’re going to convert knowledge base and not alpha to conjunctive normal form”

    II. Search Algorithms:

    • Search Problems: Defined by an initial state, actions, a transition model, a goal test, and a path cost function.
    • Local Search: Algorithms that operate on a single current state and move to neighbors. They don’t care about the path to the solution.
    • Hill Climbing: A simple local search algorithm that repeatedly moves to the neighbor with the highest value (or lowest cost). It suffers from problems with local maxima/minima. “Generally, what hill climbing is going to do is it’s going to consider the neighbors of that state…and pick the highest one I can…continually looking at all of my neighbors and picking the highest neighbor…until I get to a point…where I consider both of my neighbors and both of my neighbors have a lower value than I do.”
    • Variations: Steepest ascent, stochastic, first choice, random restart, local beam search.
    • Simulated Annealing: A local search algorithm that sometimes accepts worse moves to escape local optima. The probability of accepting a worse move depends on the “temperature” and the difference in cost (delta E). “whereas before, we never, ever wanted to take a move that made our situation worse, now we sometimes want to make a move that is actually going to make our situation worse…And so how do we do that? How do we decide to sometimes accept some state that might actually be worse? Well, we’re going to accept a worse state with some probability.”
    • Linear Programming: A family of problems where the goal is to minimize a cost function subject to linear constraints. “the goal of linear programming is to minimize a cost function…subject to particular constraints, subjects to equations that are of the form like this of some sequence of variables is less than a bound or is equal to some particular value”

    III. Constraint Satisfaction Problems (CSPs):

    • Definition: Problems defined by variables, domains (possible values for each variable), and constraints.
    • Node Consistency: Ensuring that all values in a variable’s domain satisfy the unary constraints (constraints involving only that variable). “…we can pick any of these values in the domain. And there won’t be a unary constraint that is violated as a result of it.”
    • Arc Consistency: Ensuring that all values in a variable’s domain satisfy the binary constraints (constraints involving two variables). “In order to make some variable x arc consistent with respect to some other variable y, we need to remove any element from x’s domain to make sure that every choice for x, every choice in x’s domain, has a possible choice for y.”
    • AC3: An algorithm for enforcing arc consistency across an entire CSP. It maintains a queue of arcs and revises domains to ensure consistency. “AC3 takes a constraint satisfaction problem. And it enforces our consistency across the entire problem…It’s going to basically maintain a queue or basically just a line of all of the arcs that it needs to make consistent.”
    • Backtracking Search: A depth-first search algorithm for solving CSPs. It assigns values to variables one at a time, backtracking when a constraint is violated.
    • Minimum Remaining Values (MRV): A heuristic for variable selection that chooses the variable with the fewest remaining legal values in its domain. “Select the variable that has the fewest legal values remaining in its domain…In the example of the classes and the exam slots, you would prefer to choose the class that can only meet on one possible day.”
    • Degree Heuristic: A heuristic used to select what the best variable will be. “The general approach is that in cases of ties, where two or more of the classes each can only have one possible day of the exam left, we want to choose the one that is involved in the most constraints, the one that we expect to potentially have the bigger impact on the overall problem”
    • Least Constraining Value: A heuristic for value selection that chooses the value that rules out the fewest choices for neighboring variables. “Loop over the values in the domain that we haven’t yet tried and pick the value that rules out the fewest values from the neighboring variables.”

    IV. Probabilistic Reasoning:

    • Joint Probability Distribution: A table showing the probabilities of all possible combinations of values for a set of random variables.
    • Inclusion-Exclusion Principle: Used to calculate the probability of A or B: P(A or B) = P(A) + P(B) – P(A and B). Deals with the problem of overcounting when calculating probabilities.
    • Marginalization: A rule used to calculate the probability of a variable by summing over all possible values of other variables. “I need to sum up not just over B and not B, but for all of the possible values that the other random variable could take on…I’m going to sum up over j, where j is going to range over all of the possible values that y can take on. Well, let’s look at the probability that x equals xi and y equals yj.”
    • Conditioning: Similar to marginalization, but uses conditional probabilities instead of joint probabilities.

    V. Supervised Learning:

    • Hypothesis Function: A function that maps inputs to outputs. In supervised learning the input consists of a set of labeled data points, each with multiple features and one associated value, or ‘label’. The job of supervised learning is to ‘learn’ a model that correctly maps an input consisting of a data point with multiple features to a corresponding output.
    • Weights: Parameters of the hypothesis function that determine the importance of different input features. “We’ll generally call that number a weight for how important should these variables be in trying to determine the answer.”
    • Threshold Function: A function that outputs one category if the weighted sum of inputs is above a threshold and another category otherwise. “If we do all this math, is it greater than or equal to 0? If so, we might categorize that data point as a rainy day. And otherwise, we might say, no rain.”
    • Logistic Regression: Uses a logistic function (sigmoid) instead of a hard threshold, allowing for probabilistic outputs between 0 and 1. “Instead of using this hard threshold type of function, we can use instead a logistic function…And as a result, the possible output values are no longer just 0 and 1…But you can actually get any real numbered value between 0 and 1.”
    • Gradient Descent: An iterative optimization algorithm used to find the optimal weights for a model by repeatedly updating the weights in the direction of the negative gradient of the cost function. “And we can use gradient descent to train a neural network, that gradient descent is going to tell us how to adjust the weights to try and lower that overall cost on all the data points.”
    • Stochastic Gradient Descent: Updates the weights based on a single randomly chosen data point at each iteration.
    • Mini-Batch Gradient Descent: Updates the weights based on a small batch of data points at each iteration.
    • Neural Networks: A network of interconnected nodes (neurons) organized in layers. Each connection has a weight. Neural networks take an input and ‘learn’ to modify the weight of each connection to accurately map an input to an output. A simple neural network consists of an input layer and an output layer, while more complex neural networks consist of several hidden layers between input and output. “we create a network of nodes…and if we want, we can connect all of these nodes together such that every node in the first layer is connected to every node in the second layer…And each of these edges has a weight associated with it.”
    • Activation Function: A function applied to the output of each node in a neural network to introduce non-linearity. “You take the inputs, you multiply them by the weights, and then you typically are going to transform that value a little bit using what’s called an activation function.”
    • Multi-Class Classification: A classification problem with more than two categories. Can be handled using neural networks with multiple output nodes, each representing the probability of belonging to a particular class.

    VI. Natural Language Processing (NLP):

    • Syntax: The structure of language.
    • Semantics: The meaning of language. “While syntax is all about the structure of language, semantics is about the meaning of language. It’s not enough for a computer just to know that a sentence is well-structured if it doesn’t know what that sentence means.”
    • Formal Grammar: A system of rules for generating sentences in a language.
    • Context-Free Grammar (CFG): A type of formal grammar that defines rules for rewriting non-terminal symbols into terminal symbols (words) or other non-terminal symbols. “a context-free grammar is some system of rules for generating sentences in a language…We’re going to give the computer some rules that we know about language and have the computer use those rules to make sense of the structure of language.”
    • NLTK (Natural Language Toolkit): A Python library for NLP tasks.
    • N-grams: Contiguous sequences of n items (characters or words) from a sample of text.
    • Tokenization: The process of splitting a sequence of characters into pieces, such as words.
    • Markov Chain: A sequence of values where one value can be predicted based on the preceding values. Can be used for language generation. “Recall that a Markov chain is some sequence of values where we can predict one value based on the values that came before it…we can use that to predict what word might come next in a sequence of words.”
    • Text Classification: The problem of assigning a category or label to a piece of text.
    • Sentiment Analysis: A specific text classification task that involves determining the sentiment (positive, negative, neutral) of a piece of text.
    • Bag of Words: A representation of text as a collection of words, disregarding grammar and word order, but keeping track of word frequencies. “With the bag of words representation, I’m just going to keep track of the count of every single word, which I’m going to call features.”
    • TF-IDF (Term Frequency-Inverse Document Frequency): A weighting scheme that assigns higher weights to words that are frequent in a document but rare in the overall corpus.
    • One-Hot Representation: A vector representation of a word where one element is 1 and all other elements are 0. “Each of these words now has a distinct vector representation. And this is what we often call a one-hot representation, a representation of the meaning of a word as a vector with a single 1 and all of the rest of the values are 0.”
    • Distributed Representation: A vector representation of a word where the meaning is distributed across multiple values, ideally in such a way that similar words have similar vector representations.
    • Word Embeddings: Distributed representations of words that capture semantic relationships.
    • Word2Vec: A model for generating word embeddings based on the context in which words appear. “we’re going to define the meaning of a word based on the words that appear around it, the context words around it…we’re going to say is because the words breakfast and lunch and dinner appear in a similar context, that they must have a similar meaning.”

    This briefing document provides a high-level overview of the concepts covered in the sources. It highlights key definitions, algorithms, and techniques used in AI.

    NLP, ML, and Problem Solving: FAQ

    Natural Language Processing, Machine Learning and Problem Solving: FAQ

    1. What is the core concept of “entailment” in the context of knowledge bases and inference algorithms, and how does model checking help determine entailment?

    Entailment refers to whether a knowledge base (KB) logically implies a query (alpha). In other words, can you conclude that alpha is true solely based on the information within the KB? Model checking is an algorithm that answers this by enumerating all possible models (assignments of true/false to propositional symbols). If, in every model where the KB is true, alpha is also true, then the KB entails alpha. Essentially, it exhaustively checks if alpha must be true whenever the KB is true.

    2. Explain the model checking algorithm, including how it enumerates models and determines if a knowledge base entails a query.

    The model checking algorithm involves the following steps:

    1. Enumerate all possible models: List every possible combination of truth values (true or false) for all propositional symbols in the knowledge base and query.
    2. Evaluate the knowledge base in each model: Determine if the knowledge base (KB) is true or false in each of the enumerated models.
    3. Check the query in models where the KB is true: For every model where the KB is true, check if the query (alpha) is also true.
    • Determine entailment:If alpha is true in every model where the KB is true, then the KB entails alpha.
    • If there exists at least one model where the KB is true but alpha is false, then the KB does not entail alpha.

    3. What are inference rules in propositional logic, and give examples of implication elimination, biconditional elimination, and De Morgan’s laws?

    Inference rules are logical equivalences that allow you to transform logical sentences into different, but logically equivalent, forms. This is useful for drawing new conclusions from existing knowledge. Here are some examples:

    • Implication Elimination: alpha implies beta is equivalent to not alpha or beta. This replaces an implication with an OR statement.
    • Biconditional Elimination: alpha if and only if beta is equivalent to (alpha implies beta) and (beta implies alpha). This breaks down a biconditional into two implications.
    • De Morgan’s Laws:not (alpha and beta) is equivalent to not alpha or not beta. The negation of a conjunction is the disjunction of the negations.
    • not (alpha or beta) is equivalent to not alpha and not beta. The negation of a disjunction is the conjunction of the negations.

    4. Describe the conjunctive normal form (CNF) and explain the steps to convert a logical formula into CNF.

    Conjunctive Normal Form (CNF) is a standard logical format where a sentence is represented as a conjunction (AND) of clauses, and each clause is a disjunction (OR) of literals. A literal is either a propositional symbol or its negation. The steps to convert a formula to CNF are:

    1. Eliminate Biconditionals: Replace all alpha <-> beta with (alpha -> beta) ^ (beta -> alpha).
    2. Eliminate Implications: Replace all alpha -> beta with ~alpha v beta.
    3. Move Negations Inwards: Use De Morgan’s laws to move negations inward, so they apply only to literals (e.g., ~ (alpha ^ beta) becomes ~alpha v ~beta).
    4. Distribute ORs over ANDs: Use the distributive law to transform the expression into a conjunction of clauses (e.g., alpha v (beta ^ gamma) becomes (alpha v beta) ^ (alpha v gamma)).

    5. Explain the resolution inference rule and the resolution algorithm for proving entailment. What is “inference by resolution,” and how does the empty clause relate to contradiction?

    The resolution inference rule states that if you have two clauses, alpha OR beta and ~alpha OR gamma, you can infer beta OR gamma. It essentially eliminates a complementary pair of literals (alpha and ~alpha) and combines the remaining literals into a new clause. “Inference by resolution” uses this rule repeatedly to derive new clauses.

    The resolution algorithm for proving entailment involves:

    1. Negate the query: To prove KB entails alpha, assume ~alpha.
    2. Convert to CNF: Convert KB AND ~alpha into CNF.
    3. Resolution Loop: Repeatedly apply the resolution rule to pairs of clauses in the CNF formula. Add any new clauses generated back into the set of clauses. If factoring is needed, remove any duplicate literals in resulting clause.
    4. Check for Empty Clause: If, at any point, you derive the “empty clause” (a clause with no literals, representing “false”), this means you’ve found a contradiction.
    5. Determine Entailment: If you derive the empty clause, then KB entails alpha (because KB AND ~alpha leads to a contradiction, so it must be the case that if KB is true, then alpha must be true). If you can no longer derive new clauses and haven’t found the empty clause, then KB does not entail alpha.

    The empty clause signifies a contradiction because it represents a situation where both P and NOT P are true, which is impossible. Finding the empty clause through resolution proves that the initial assumption (the negated query) was inconsistent with the knowledge base.

    6. Explain the inclusion-exclusion principle and the marginalization rule in probability theory, providing examples of their application.

    • Inclusion-Exclusion Principle: This principle calculates the probability of A OR B. The formula is: P(A or B) = P(A) + P(B) – P(A and B). It is used to correct for over counting when calculating P(A or B).
    • Example: The probability of rolling a 6 on a red die (A) OR a 6 on a blue die (B). If you just add P(A) + P(B), you’re double-counting the case where both dice show 6. Subtracting P(A and B) (the probability of both dice showing 6) corrects for this.
    • Marginalization Rule: This rule allows you to calculate the probability of one variable (A) by summing over all possible values of another variable (B). The formula is: P(A) = Σ P(A and B).
    • Example: Probability of it being cloudy (A), given the joint distribution of cloudiness and raininess (B). We calculate P(cloudy) by summing P(cloudy and rainy) + P(cloudy and not rainy). We consider all possible cases that take place, and then look at the probability that the probability of A happens in each of the cases. This is useful for finding an individual (unconditional) probability from a joint probability distribution.

    7. Describe the hill climbing algorithm, including its pseudocode, and discuss its limitations (local optima). Also explain variations like stochastic hill climbing and random restart hill climbing.

    The hill climbing algorithm is a local search technique used to find a maximum (or minimum) of a function. Its pseudocode is as follows:

    1. Start with a current state (often random).
    2. Loop: a. Find the neighbor of the current state with the highest (or lowest) value. b. If the neighbor is better than the current state, move to the neighbor ( current = neighbor). c. If the neighbor is not better, terminate and return the current state.

    A major limitation of hill climbing is that it can get stuck in local optima: points that are better than their immediate neighbors but not the best overall solution.

    Variations:

    • Stochastic Hill Climbing: Randomly choose a neighbor with a better value, rather than always picking the best neighbor. This can help escape plateaus (areas of the search space with relatively equal value), but not always a local optimum.
    • Random Restart Hill Climbing: Run the hill climbing algorithm multiple times from different random starting states. Keep track of the best solution found across all runs. This increases the chance of finding the global optimum by exploring different regions of the search space.

    8. Explain the simulated annealing algorithm and how it can potentially escape local optima compared to simple hill climbing.

    Simulated Annealing is a metaheuristic optimization algorithm that can be used for finding the global minimum of a function that may possess several local minima. Simulated Annealing works by first randomly picking a state. Then the algorithm calculates the cost of the state and then makes a neighbor of the state to calculate that cost as well. If the neighbor cost is better, than the new current state becomes the new neighbor. However, simulated annealing adds a twist. Even if the neighbor cost is not better than the current state, you still have a probability of setting the current state to the new worse neighbor to try and dislodge yourself.

    This probability is based on a temperature. At the beginning, the temperature is high so there is a better probability to dislodge yourself and explore the search space even if it may lead to worse results at first. As the algorithm iterates, the temperature starts to go down, so it slowly starts to look for better neighbors instead of just exploring and dislodging.

    Simulated Annealing is thus better than simple hill climbing because simple hill climbing never goes to a state that may lead to worse results, so as a result gets stuck in local optima as described in the hill climbing algorithm, which SA doesn’t suffer from.

    Supervised Learning: Classification, Regression, and Evaluation

    Supervised learning is a type of machine learning where a computer is given access to a dataset of input-output pairs and learns a function that maps inputs to outputs. The computer uses the data to train its model and understand the relationships between inputs and outputs. The goal is for the AI to learn to predict outputs based on new input data.

    Key aspects of supervised learning:

    • Input-output pairs: The computer is provided with a dataset where each data point consists of an input and a corresponding desired output.
    • Function mapping: The goal is to find a function that accurately maps inputs to outputs, allowing the computer to make predictions on new, unseen data.
    • Training: The computer uses the provided data to train its model, adjusting its internal parameters to minimize the difference between its predictions and the actual outputs.

    Classification and regression are two common tasks within supervised learning.

    • Classification: Aims to map inputs into discrete categories. An example would be classifying a banknote as authentic or counterfeit based on its features.
    • Regression: Aims to predict continuous output values. For example, predicting sales based on advertising spending.

    Implementation and evaluation

    • Libraries such as Scikit-learn in Python provide tools to implement supervised learning algorithms.
    • The data is typically split into training and testing sets. The model is trained on the training set and evaluated on the testing set to assess its ability to generalize to new data.
    • Holdout cross-validation splits the data into training and testing sets. The training set trains the machine learning model. The testing set tests how well the machine learning model performs.
    • K-fold cross-validation divides data into k different sets and runs k different experiments.

    Machine Learning: Algorithms, Techniques, and Applications

    Machine learning involves enabling computers to learn from data and experiences without explicit instructions. Instead of programming a computer with explicit rules, machine learning allows the computer to learn patterns from data and improve its performance on a specific task.

    Key aspects of machine learning:

    • Learning from Data: Machine learning algorithms use data to identify patterns, make predictions, and improve decision-making.
    • Algorithms and Techniques: Machine learning encompasses a wide range of algorithms and techniques that enable computers to learn from data.
    • Pattern Recognition: Machine learning algorithms identify underlying patterns and relationships within data.

    Machine learning comes in different forms, including supervised learning, reinforcement learning and unsupervised learning.

    • Supervised learning involves training a model on a labeled dataset consisting of input-output pairs, enabling the model to learn a function that maps inputs to outputs.
    • Reinforcement learning involves training an agent to make decisions in an environment to maximize a reward signal.
    • Unsupervised learning involves discovering patterns and relationships in unlabeled data without explicit guidance. Clustering is a task preformed in unsupervised learning that involves organizing a set of objects into distinct clusters or groups of similar objects.

    Neural networks are a popular tool in machine learning inspired by the structure of the human brain and can be very effective at certain tasks. A neural network is a mathematical model for learning inspired by biological neural networks. Artificial neural networks can model mathematical functions and learn network parameters.

    TensorFlow is a library that can be used for creating neural networks, modeling them, and running them on sample data.

    Machine learning has a wide variety of applications including: recognizing faces in photos, playing games, understanding human language, spam detection, search and optimization problems, and more.

    Neural Networks: Models, Training, and Applications

    Neural networks are a popular tool in modern machine learning that draw inspiration from the way human brains learn and reason. They are a type of model that is effective at learning from some set of input data to figure out how to calculate some function from inputs to outputs.

    Key aspects of neural networks:

    • Mathematical Model: A neural network is a mathematical model for learning inspired by biological neural networks.
    • Units: Instead of biological neurons, neural networks use units inside of the network. The units can be represented like nodes in a graph.
    • Layers: Neural networks are composed of multiple layers of interconnected nodes or units, including an input layer, one or more hidden layers, and an output layer.
    • Weights: Connections between units are defined by weights. The weights determine how signals are passed between connected nodes.
    • Activation Functions: Activation functions introduce non-linearity into the network, allowing it to learn complex patterns and relationships in the data.
    • Backpropagation: Backpropagation is a key algorithm that makes training multi-layered neural networks possible. The backpropagation algorithm is used to adjust the weights in the network during training to minimize the difference between predicted and actual outputs.
    • Versatility: Neural networks are versatile tools applicable to a number of domains.

    There are different types of neural networks, each designed for specific tasks:

    • Feed-forward neural networks have connections that only move in one direction. The inputs pass through hidden layers and ultimately produce an output.
    • Convolutional neural networks (CNNs) are designed for processing grid-like data, such as images. CNNs apply convolutional layers and pooling layers to extract features from images.
    • Recurrent neural networks (RNNs) are designed for processing sequential data, such as text or time series. RNNs have connections that loop back into themselves, allowing them to maintain a hidden state that captures information about the sequence. Long short-term memory (LSTM) neural network is a popular type of RNN.

    Training Neural Networks:

    • Gradient descent is a technique used to train neural networks by minimizing a loss function. Gradient descent involves iteratively adjusting the weights of the network based on the gradient of the loss function with respect to the weights.
    • Stochastic gradient descent randomly chooses one data point at a time to calculate the gradient based on, instead of calculating it based on all of the data points.
    • Mini-batch gradient descent divides the data set up into small batches, groups of data points, to calculate the gradient based on.
    • Overfitting occurs when a neural network is too complex and fits the training data too closely, resulting in poor generalization to new data.
    • Dropout is a technique used to combat overfitting by randomly removing units from the neural network during training.

    TensorFlow is a library that can be used for creating neural networks, modeling them, and running them on sample data.

    Understanding Gradient Descent in Neural Networks

    Gradient descent is an algorithm inspired by calculus for minimizing loss when training a neural network. In the context of neural networks, “loss” refers to how poorly a hypothesis function models data.

    Key aspects of gradient descent:

    • Loss Function: Gradient descent aims to minimize a loss function, which quantifies how poorly the neural network performs.
    • Gradient Calculation: The algorithm calculates the gradient of the loss function with respect to the network’s weights. The gradient indicates the direction in which the weights should be adjusted to reduce the loss.
    • Weight Update: The weights are updated by taking a small step in the direction opposite to the gradient. The size of this step can vary and is chosen when training the neural network.
    • Iterative Process: This process is repeated iteratively, adjusting the weights little by little based on the data points, with the aim of converging towards a good solution.

    There are variations to the standard gradient descent algorithm:

    • Stochastic Gradient Descent: Instead of looking at all data points at once, stochastic gradient descent randomly chooses one data point at a time to calculate the gradient. This provides a less accurate gradient estimate but is faster to compute.
    • Mini-Batch Gradient Descent: This approach is a middle ground between standard and stochastic gradient descent, where the data set is divided into small batches and the gradient is calculated based on these batches.

    Understanding Neural Network Hidden Layers

    Hidden layers are intermediate layers of artificial neurons or units within a neural network between the input layer and the output layer.

    Here’s more about hidden layers and how they contribute to neural network functionality:

    • Structure and Function In a neural network, the input layer receives the initial data, and the output layer produces the final result. The hidden layers lie in between, performing complex transformations on the input data to help the network learn non-linear relationships.
    • Nodes and Connections Each hidden layer contains a certain number of nodes or units, each connected to the nodes in the preceding and following layers. The connections between nodes have weights, which are adjusted during training to optimize the network’s performance.
    • Activation Each unit calculates its output value based on a linear combination of all the inputs. The advantage of layering like this gives an ability to model more complex functions.

    Backpropagation: One of the challenges of neural networks is training neural networks that have hidden layers inside of them. The input data provides values for all of the inputs, and what the value of the output should be. However, the input data does not provide what the values for all of the nodes in the hidden layer should be. The key algorithm that makes training the hidden layers of neural networks possible is called backpropagation.

    Deep Neural Networks: Neural networks that contain multiple hidden layers are called deep neural networks. The presence of multiple hidden layers allows the network to model more complex functions. Each layer can learn different features of the input, and these features can be combined to produce the desired output. However, complex networks are at greater risk of overfitting.

    Dropout: Dropout is a technique that can combat overfitting in neural networks. It involves temporarily removing units from the network during training to prevent over-reliance on any single node.

    Harvard CS50’s Artificial Intelligence with Python – Full University Course

    The Original Text

    This course from Harvard University explores the concepts and algorithms at the foundation of modern artificial intelligence, diving into the ideas that give rise to technologies like game-playing engines, handwriting recognition, and machine translation. You’ll gain exposure to the theory behind graph search algorithms, classification, optimization, reinforcement learning, and other topics in artificial intelligence and machine learning. Brian Yu teaches this course. Hello, world. This is CS50, and this is an introduction to artificial intelligence with Python with CS50’s own Brian Yu. This course picks up where CS50 itself leaves off and explores the concepts and algorithms at the foundation of modern AI. We’ll start with a look at how AI can search for solutions to problems, whether those problems are learning how to play a game or trying to find driving directions to a destination. We’ll then look at how AI can represent information, both knowledge that our AI is certain about, but also information and events about which our AI might be uncertain, learning how to represent that information, but more importantly, how to use that information to draw inferences and new conclusions as well. We’ll explore how AI can solve various types of optimization problems, trying to maximize profits or minimize costs or satisfy some other constraints before turning our attention to the fast-growing field of machine learning, where we won’t tell our AI exactly how to solve a problem, but instead, give our AI access to data and experiences so that our AI can learn on its own how to perform these tasks. In particular, we’ll look at neural networks, one of the most popular tools in modern machine learning, inspired by the way that human brains learn and reason as well before finally taking a look at the world of natural language processing so that it’s not just us humans learning to learn how artificial intelligence is able to speak, but also AI learning how to understand and interpret human language as well. We’ll explore these ideas and algorithms, and along the way, give you the opportunity to build your own AI programs to implement all of this and more. This is CS50. All right. Welcome, everyone, to an introduction to artificial intelligence with Python. My name is Brian Yu, and in this class, we’ll explore some of the ideas and techniques and algorithms that are at the foundation of artificial intelligence. Now, artificial intelligence covers a wide variety of types of techniques. Anytime you see a computer do something that appears to be intelligent or rational in some way, like recognizing someone’s face in a photo, or being able to play a game better than people can, or being able to understand human language when we talk to our phones and they understand what we mean and are able to respond back to us, these are all examples of AI, or artificial intelligence. And in this class, we’ll explore some of the ideas that make that AI possible. So we’ll begin our conversations with search, the problem of we have an AI, and we would like the AI to be able to search for solutions to some kind of problem, no matter what that problem might be. Whether it’s trying to get driving directions from point A to point B, or trying to figure out how to play a game, given a tic-tac-toe game, for example, figuring out what move it ought to make. After that, we’ll take a look at knowledge. Ideally, we want our AI to be able to know information, to be able to represent that information, and more importantly, to be able to draw inferences from that information, to be able to use the information it knows and draw additional conclusions. So we’ll talk about how AI can be programmed in order to do just that. Then we’ll explore the topic of uncertainty, talking about ideas of what happens if a computer isn’t sure about a fact, but maybe is only sure with a certain probability. So we’ll talk about some of the ideas behind probability, and how computers can begin to deal with uncertain events in order to be a little bit more intelligent in that sense as well. After that, we’ll turn our attention to optimization, problems of when the computer is trying to optimize for some sort of goal, especially in a situation where there might be multiple ways that a computer might solve a problem, but we’re looking for a better way, or potentially the best way, if that’s at all possible. Then we’ll take a look at machine learning, or learning more generally, and looking at how, when we have access to data, our computers can be programmed to be quite intelligent by learning from data and learning from experience, being able to perform a task better and better based on greater access to data. So your email, for example, where your email inbox somehow knows which of your emails are good emails and which of your emails are spam. These are all examples of computers being able to learn from past experiences and past data. We’ll take a look, too, at how computers are able to draw inspiration from human intelligence, looking at the structure of the human brain, and how neural networks can be a computer analog to that sort of idea, and how, by taking advantage of a certain type of structure of a computer program, we can write neural networks that are able to perform tasks very, very effectively. And then finally, we’ll turn our attention to language, not programming languages, but human languages that we speak every day. And taking a look at the challenges that come about as a computer tries to understand natural language, and how it is some of the natural language processing that occurs in modern artificial intelligence can actually work. But today, we’ll begin our conversation with search, this problem of trying to figure out what to do when we have some sort of situation that the computer is in, some sort of environment that an agent is in, so to speak, and we would like for that agent to be able to somehow look for a solution to that problem. Now, these problems can come in any number of different types of formats. One example, for instance, might be something like this classic 15 puzzle with the sliding tiles that you might have seen. Where you’re trying to slide the tiles in order to make sure that all the numbers line up in order. This is an example of what you might call a search problem. The 15 puzzle begins in an initially mixed up state, and we need some way of finding moves to make in order to return the puzzle to its solved state. But there are similar problems that you can frame in other ways. Trying to find your way through a maze, for example, is another example of a search problem. You begin in one place, you have some goal of where you’re trying to get to, and you need to figure out the correct sequence of actions that will take you from that initial state to the goal. And while this is a little bit abstract, any time we talk about maze solving in this class, you can translate it to something a little more real world. Something like driving directions. If you ever wonder how Google Maps is able to figure out what is the best way for you to get from point A to point B, and what turns to make at what time, depending on traffic, for example, it’s often some sort of search algorithm. You have an AI that is trying to get from an initial position to some sort of goal by taking some sequence of actions. So we’ll start our conversations today by thinking about these types of search problems and what goes in to solving a search problem like this in order for an AI to be able to find a good solution. In order to do so, though, we’re going to need to introduce a little bit of terminology, some of which I’ve already used. But the first term we’ll need to think about is an agent. An agent is just some entity that perceives its environment. It somehow is able to perceive the things around it and act on that environment in some way. So in the case of the driving directions, your agent might be some representation of a car that is trying to figure out what actions to take in order to arrive at a destination. In the case of the 15 puzzle with the sliding tiles, the agent might be the AI or the person that is trying to solve that puzzle to try and figure out what tiles to move in order to get to that solution. Next, we introduce the idea of a state. A state is just some configuration of the agent in its environment. So in the 15 puzzle, for example, any state might be any one of these three, for example. A state is just some configuration of the tiles. And each of these states is different and is going to require a slightly different solution. A different sequence of actions will be needed in each one of these in order to get from this initial state to the goal, which is where we’re trying to get. So the initial state, then, what is that? The initial state is just the state where the agent begins. It is one such state where we’re going to start from. And this is going to be the starting point for our search algorithm, so to speak. We’re going to begin with this initial state and then start to reason about it, to think about what actions might we apply to that initial state in order to figure out how to get from the beginning to the end, from the initial position to whatever our goal happens to be. And how do we make our way from that initial position to the goal? Well, ultimately, it’s via taking actions. Actions are just choices that we can make in any given state. And in AI, we’re always going to try to formalize these ideas a little bit more precisely, such that we could program them a little bit more mathematically, so to speak. So this will be a recurring theme. And we can more precisely define actions as a function. We’re going to effectively define a function called actions that takes an input, s, where s is going to be some state that exists inside of our environment. And actions of s is going to take the state as input and return as output the set of all actions that can be executed in that state. And so it’s possible that some actions are only valid in certain states and not in other states. And we’ll see examples of that soon, too. So in the case of the 15 puzzle, for example, there are generally going to be four possible actions that we can do most of the time. We can slide a tile to the right, slide a tile to the left, slide a tile up, or slide a tile down, for example. And those are going to be the actions that are available to us. So somehow our AI, our program, needs some encoding of the state, which is often going to be in some numerical format, and some encoding of these actions. But it also needs some encoding of the relationship between these things. How do the states and actions relate to one another? And in order to do that, we’ll introduce to our AI a transition model, which will be a description of what state we get after we perform some available action in some other state. And again, we can be a little bit more precise about this, define this transition model a little bit more formally, again, as a function. The function is going to be a function called result that this time takes two inputs. Input number one is s, some state. And input number two is a, some action. And the output of this function result is it is going to give us the state that we get after we perform action a in state s. So let’s take a look at an example to see more precisely what this actually means. Here is an example of a state, of the 15 puzzle, for example. And here is an example of an action, sliding a tile to the right. What happens if we pass these as inputs to the result function? Again, the result function takes this board, this state, as its first input. And it takes an action as a second input. And of course, here, I’m describing things visually so that you can see visually what the state is and what the action is. In a computer, you might represent one of these actions as just some number that represents the action. Or if you’re familiar with enums that allow you to enumerate multiple possibilities, it might be something like that. And this state might just be represented as an array or two-dimensional array of all of these numbers that exist. But here, we’re going to show it visually just so you can see it. But when we take this state and this action, pass it into the result function, the output is a new state. The state we get after we take a tile and slide it to the right, and this is the state we get as a result. If we had a different action and a different state, for example, and pass that into the result function, we’d get a different answer altogether. So the result function needs to take care of figuring out how to take a state and take an action and get what results. And this is going to be our transition model that describes how it is that states and actions are related to each other. If we take this transition model and think about it more generally and across the entire problem, we can form what we might call a state space. The set of all of the states we can get from the initial state via any sequence of actions, by taking 0 or 1 or 2 or more actions in addition to that, so we could draw a diagram that looks something like this, where every state is represented here by a game board, and there are arrows that connect every state to every other state we can get to from that state. And the state space is much larger than what you see just here. This is just a sample of what the state space might actually look like. And in general, across many search problems, whether they’re this particular 15 puzzle or driving directions or something else, the state space is going to look something like this. We have individual states and arrows that are connecting them. And oftentimes, just for simplicity, we’ll simplify our representation of this entire thing as a graph, some sequence of nodes and edges that connect nodes. But you can think of this more abstract representation as the exact same idea. Each of these little circles or nodes is going to represent one of the states inside of our problem. And the arrows here represent the actions that we can take in any particular state, taking us from one particular state to another state, for example. All right. So now we have this idea of nodes that are representing these states, actions that can take us from one state to another, and a transition model that defines what happens after we take a particular action. So the next step we need to figure out is how we know when the AI is done solving the problem. The AI needs some way to know when it gets to the goal that it’s found the goal. So the next thing we’ll need to encode into our artificial intelligence is a goal test, some way to determine whether a given state is a goal state. In the case of something like driving directions, it might be pretty easy. If you’re in a state that corresponds to whatever the user typed in as their intended destination, well, then you know you’re in a goal state. In the 15 puzzle, it might be checking the numbers to make sure they’re all in ascending order. But the AI needs some way to encode whether or not any state they happen to be in is a goal. And some problems might have one goal, like a maze where you have one initial position and one ending position, and that’s the goal. In other more complex problems, you might imagine that there are multiple possible goals. That there are multiple ways to solve a problem, and we might not care which one the computer finds, as long as it does find a particular goal. However, sometimes the computer doesn’t just care about finding a goal, but finding a goal well, or one with a low cost. And it’s for that reason that the last piece of terminology that we’ll use to define these search problems is something called a path cost. You might imagine that in the case of driving directions, it would be pretty annoying if I said I wanted directions from point A to point B, and the route that Google Maps gave me was a long route with lots of detours that were unnecessary that took longer than it should have for me to get to that destination. And it’s for that reason that when we’re formulating search problems, we’ll often give every path some sort of numerical cost, some number telling us how expensive it is to take this particular option, and then tell our AI that instead of just finding a solution, some way of getting from the initial state to the goal, we’d really like to find one that minimizes this path cost. That is, less expensive, or takes less time, or minimizes some other numerical value. We can represent this graphically if we take a look at this graph again, and imagine that each of these arrows, each of these actions that we can take from one state to another state, has some sort of number associated with it. That number being the path cost of this particular action, where some of the costs for any particular action might be more expensive than the cost for some other action, for example. Although this will only happen in some sorts of problems. In other problems, we can simplify the diagram and just assume that the cost of any particular action is the same. And this is probably the case in something like the 15 puzzle, for example, where it doesn’t really make a difference whether I’m moving right or moving left. The only thing that matters is the total number of steps that I have to take to get from point A to point B. And each of those steps is of equal cost. We can just assume it’s of some constant cost like one. And so this now forms the basis for what we might consider to be a search problem. A search problem has some sort of initial state, some place where we begin, some sort of action that we can take or multiple actions that we can take in any given state. And it has a transition model. Some way of defining what happens when we go from one state and take one action, what state do we end up with as a result. In addition to that, we need some goal test to know whether or not we’ve reached a goal. And then we need a path cost function that tells us for any particular path, by following some sequence of actions, how expensive is that path. What does its cost in terms of money or time or some other resource that we are trying to minimize our usage of. And the goal ultimately is to find a solution. Where a solution in this case is just some sequence of actions that will take us from the initial state to the goal state. And ideally, we’d like to find not just any solution but the optimal solution, which is a solution that has the lowest path cost among all of the possible solutions. And in some cases, there might be multiple optimal solutions. But an optimal solution just means that there is no way that we could have done better in terms of finding that solution. So now we’ve defined the problem. And now we need to begin to figure out how it is that we’re going to solve this kind of search problem. And in order to do so, you’ll probably imagine that our computer is going to need to represent a whole bunch of data about this particular problem. We need to represent data about where we are in the problem. And we might need to be considering multiple different options at once. And oftentimes, when we’re trying to package a whole bunch of data related to a state together, we’ll do so using a data structure that we’re going to call a node. A node is a data structure that is just going to keep track of a variety of different values. And specifically, in the case of a search problem, it’s going to keep track of these four values in particular. Every node is going to keep track of a state, the state we’re currently on. And every node is also going to keep track of a parent. A parent being the state before us or the node that we used in order to get to this current state. And this is going to be relevant because eventually, once we reach the goal node, once we get to the end, we want to know what sequence of actions we use in order to get to that goal. And the way we’ll know that is by looking at these parents to keep track of what led us to the goal and what led us to that state and what led us to the state before that, so on and so forth, backtracking our way to the beginning so that we know the entire sequence of actions we needed in order to get from the beginning to the end. The node is also going to keep track of what action we took in order to get from the parent to the current state. And the node is also going to keep track of a path cost. In other words, it’s going to keep track of the number that represents how long it took to get from the initial state to the state that we currently happen to be at. And we’ll see why this is relevant as we start to talk about some of the optimizations that we can make in terms of these search problems more generally. So this is the data structure that we’re going to use in order to solve the problem. And now let’s talk about the approach. How might we actually begin to solve the problem? Well, as you might imagine, what we’re going to do is we’re going to start at one particular state, and we’re just going to explore from there. The intuition is that from a given state, we have multiple options that we could take, and we’re going to explore those options. And once we explore those options, we’ll find that more options than that are going to make themselves available. And we’re going to consider all of the available options to be stored inside of a single data structure that we’ll call the frontier. The frontier is going to represent all of the things that we could explore next that we haven’t yet explored or visited. So in our approach, we’re going to begin the search algorithm by starting with a frontier that just contains one state. The frontier is going to contain the initial state, because at the beginning, that’s the only state we know about. That is the only state that exists. And then our search algorithm is effectively going to follow a loop. We’re going to repeat some process again and again and again. The first thing we’re going to do is if the frontier is empty, then there’s no solution. And we can report that there is no way to get to the goal. And that’s certainly possible. There are certain types of problems that an AI might try to explore and realize that there is no way to solve that problem. And that’s useful information for humans to know as well. So if ever the frontier is empty, that means there’s nothing left to explore. And we haven’t yet found a solution, so there is no solution. There’s nothing left to explore. Otherwise, what we’ll do is we’ll remove a node from the frontier. So right now at the beginning, the frontier just contains one node representing the initial state. But over time, the frontier might grow. It might contain multiple states. And so here, we’re just going to remove a single node from that frontier. If that node happens to be a goal, then we found a solution. So we remove a node from the frontier and ask ourselves, is this the goal? And we do that by applying the goal test that we talked about earlier, asking if we’re at the destination. Or asking if all the numbers of the 15 puzzle happen to be in order. So if the node contains the goal, we found a solution. Great. We’re done. And otherwise, what we’ll need to do is we’ll need to expand the node. And this is a term of art in artificial intelligence. To expand the node just means to look at all of the neighbors of that node. In other words, consider all of the possible actions that I could take from the state that this node is representing and what nodes could I get to from there. We’re going to take all of those nodes, the next nodes that I can get to from this current one I’m looking at, and add those to the frontier. And then we’ll repeat this process. So at a very high level, the idea is we start with a frontier that contains the initial state. And we’re constantly removing a node from the frontier, looking at where we can get to next and adding those nodes to the frontier, repeating this process over and over until either we remove a node from the frontier and it contains a goal, meaning we’ve solved the problem, or we run into a situation where the frontier is empty, at which point we’re left with no solution. So let’s actually try and take the pseudocode, put it into practice by taking a look at an example of a sample search problem. So right here, I have a sample graph. A is connected to B via this action. B is connected to nodes C and D. C is connected to E. D is connected to F. And what I’d like to do is have my AI find a path from A to E. We want to get from this initial state to this goal state. So how are we going to do that? Well, we’re going to start with a frontier that contains the initial state. This is going to represent our frontier. So our frontier initially will just contain A, that initial state where we’re going to begin. And now we’ll repeat this process. If the frontier is empty, no solution. That’s not a problem, because the frontier is not empty. So we’ll remove a node from the frontier as the one to consider next. There’s only one node in the frontier. So we’ll go ahead and remove it from the frontier. But now A, this initial node, this is the node we’re currently considering. We follow the next step. We ask ourselves, is this node the goal? No, it’s not. A is not the goal. E is the goal. So we don’t return the solution. So instead, we go to this last step, expand the node, and add the resulting nodes to the frontier. What does that mean? Well, it means take this state A and consider where we could get to next. And after A, what we could get to next is only B. So that’s what we get when we expand A. We find B. And we add B to the frontier. And now B is in the frontier. And we repeat the process again. We say, all right, the frontier is not empty. So let’s remove B from the frontier. B is now the node that we’re considering. We ask ourselves, is B the goal? No, it’s not. So we go ahead and expand B and add its resulting nodes to the frontier. What happens when we expand B? In other words, what nodes can we get to from B? Well, we can get to C and D. So we’ll go ahead and add C and D from the frontier. And now we have two nodes in the frontier, C and D. And we repeat the process again. We remove a node from the frontier. For now, I’ll do so arbitrarily just by picking C. We’ll see why later, how choosing which node you remove from the frontier is actually quite an important part of the algorithm. But for now, I’ll arbitrarily remove C, say it’s not the goal. So we’ll add E, the next one, to the frontier. Then let’s say I remove E from the frontier. And now I check I’m currently looking at state E. Is it a goal state? It is, because I’m trying to find a path from A to E. So I would return the goal. And that now would be the solution, that I’m now able to return the solution. And I have found a path from A to E. So this is the general idea, the general approach of this search algorithm, to follow these steps, constantly removing nodes from the frontier, until we’re able to find a solution. So the next question you might reasonably ask is, what could go wrong here? What are the potential problems with an approach like this? And here’s one example of a problem that could arise from this sort of approach. Imagine this same graph, same as before, with one change. The change being now, instead of just an arrow from A to B, we also have an arrow from B to A, meaning we can go in both directions. And this is true in something like the 15 puzzle, where when I slide a tile to the right, I could then slide a tile to the left to get back to the original position. I could go back and forth between A and B. And that’s what these double arrows symbolize, the idea that from one state, I can get to another, and then I can get back. And that’s true in many search problems. What’s going to happen if I try to apply the same approach now? Well, I’ll begin with A, same as before. And I’ll remove A from the frontier. And then I’ll consider where I can get to from A. And after A, the only place I can get to is B. So B goes into the frontier. Then I’ll say, all right, let’s take a look at B. That’s the only thing left in the frontier. Where can I get to from B? Before, it was just C and D. But now, because of that reverse arrow, I can get to A or C or D. So all three, A, C, and D, all of those now go into the frontier. They are places I can get to from B. And now I remove one from the frontier. And maybe I’m unlucky, and maybe I pick A. And now I’m looking at A again. And I consider, where can I get to from A? And from A, well, I can get to B. And now we start to see the problem. But if I’m not careful, I go from A to B, and then back to A, and then to B again. And I could be going in this infinite loop, where I never make any progress, because I’m constantly just going back and forth between two states that I’ve already seen. So what is the solution to this? We need some way to deal with this problem. And the way that we can deal with this problem is by somehow keeping track of what we’ve already explored. And the logic is going to be, well, if we’ve already explored the state, there’s no reason to go back to it. Once we’ve explored a state, don’t go back to it. Don’t bother adding it to the frontier. There’s no need to. So here’s going to be our revised approach, a better way to approach this sort of search problem. And it’s going to look very similar, just with a couple of modifications. We’ll start with a frontier that contains the initial state, same as before. But now we’ll start with another data structure, which will just be a set of nodes that we’ve already explored. So what are the states we’ve explored? Initially, it’s empty. We have an empty explored set. And now we repeat. If the frontier is empty, no solution, same as before. We remove a node from the frontier. We check to see if it’s a goal state, return the solution. None of this is any different so far. But now what we’re going to do is we’re going to add the node to the explored state. So if it happens to be the case that we remove a node from the frontier and it’s not the goal, we’ll add it to the explored set so that we know we’ve already explored it. We don’t need to go back to it again if it happens to come up later. And then the final step, we expand the node and we add the resulting nodes to the frontier. But before, we just always added the resulting nodes to the frontier. We’re going to be a little clever about it this time. We’re only going to add the nodes to the frontier if they aren’t already in the frontier and if they aren’t already in the explored set. So we’ll check both the frontier and the explored set, make sure that the node isn’t already in one of those two. And so long as it isn’t, then we’ll go ahead and add it to the frontier, but not otherwise. And so that revised approach is ultimately what’s going to help make sure that we don’t go back and forth between two nodes. Now, the one point that I’ve kind of glossed over here so far is this step here, removing a node from the frontier. Before, I just chose arbitrarily. Like, let’s just remove a node and that’s it. But it turns out it’s actually quite important how we decide to structure our frontier, how we add and how we remove our nodes. The frontier is a data structure and we need to make a choice about in what order are we going to be removing elements. And one of the simplest data structures for adding and removing elements is something called a stack. And a stack is a data structure that is a last in, first out data type, which means the last thing that I add to the frontier is going to be the first thing that I remove from the frontier. So the most recent thing to go into the stack or the frontier in this case is going to be the node that I explore. So let’s see what happens if I apply this stack-based approach to something like this problem, finding a path from A to E. What’s going to happen? Well, again, we’ll start with A and we’ll say, all right, let’s go ahead and look at A first. And then notice this time, we’ve added A to the explored set. A is something we’ve now explored. We have this data structure that’s keeping track. We then say from A, we can get to B. And all right, from B, what can we do? Well, from B, we can explore B and get to both C and D. So we added C and then D. So now, when we explore a node, we’re going to treat the frontier as a stack, last in, first out. D was the last one to come in. So we’ll go ahead and explore that next and say, all right, where can we get to from D? Well, we can get to F. And so all right, we’ll put F into the frontier. And now, because the frontier is a stack, F is the most recent thing that’s gone in the stack. So F is what we’ll explore next. We’ll explore F and say, all right, where can we get to from F? Well, we can’t get anywhere, so nothing gets added to the frontier. So now, what was the new most recent thing added to the frontier? Well, it’s now C, the only thing left in the frontier. We’ll explore that from which we can see, all right, from C, we can get to E. So E goes into the frontier. And then we say, all right, let’s look at E. And E is now the solution. And now, we’ve solved the problem. So when we treat the frontier like a stack, a last in, first out data structure, that’s the result we get. We go from A to B to D to F. And then we sort of backed up and went down to C and then E. And it’s important to get a visual sense for how this algorithm is working. We went very deep in this search tree, so to speak, all the way until the bottom where we hit a dead end. And then we effectively backed up and explored this other route that we didn’t try before. And it’s this going very deep in the search tree idea, this way the algorithm ends up working when we use a stack that we call this version of the algorithm depth first search. Depth first search is the search algorithm where we always explore the deepest node in the frontier. We keep going deeper and deeper through our search tree. And then if we hit a dead end, we back up and we try something else instead. But depth first search is just one of the possible search options that we could use. It turns out that there’s another algorithm called breadth first search, which behaves very similarly to depth first search with one difference. Instead of always exploring the deepest node in the search tree, the way the depth first search does, breadth first search is always going to explore the shallowest node in the frontier. So what does that mean? Well, it means that instead of using a stack which depth first search or DFS used, where the most recent item added to the frontier is the one we’ll explore next, in breadth first search or BFS, we’ll instead use a queue, where a queue is a first in first out data type, where the very first thing we add to the frontier is the first one we’ll explore and they effectively form a line or a queue, where the earlier you arrive in the frontier, the earlier you get explored. So what would that mean for the same exact problem, finding a path from A to E? Well, we start with A, same as before, then we’ll go ahead and have explored A and say, where can we get to from A? Well, from A, we can get to B, same as before. From B, same as before, we can get to C and D. So C and D get added to the frontier. This time, though, we added C to the frontier before D. So we’ll explore C first. So C gets explored. And from C, where can we get to? Well, we can get to E. So E gets added to the frontier. But because D was explored before E, we’ll look at D next. So we’ll explore D and say, where can we get to from D? We can get to F. And only then will we say, all right, now we can get to E. And so what breadth first search or BFS did is we started here, we looked at both C and D, and then we looked at E. Effectively, we’re looking at things one away from the initial state, then two away from the initial state, and only then, things that are three away from the initial state, unlike depth first search, which just went as deep as possible into the search tree until it hit a dead end and then ultimately had to back up. So these now are two different search algorithms that we could apply in order to try and solve a problem. And let’s take a look at how these would actually work in practice with something like maze solving, for example. So here’s an example of a maze. These empty cells represent places where our agent can move. These darkened gray cells represent walls that the agent can’t pass through. And ultimately, our agent, our AI, is going to try to find a way to get from position A to position B via some sequence of actions, where those actions are left, right, up, and down. What will depth first search do in this case? Well, depth first search will just follow one path. If it reaches a fork in the road where it has multiple different options, depth first search is just, in this case, going to choose one. That doesn’t a real preference. But it’s going to keep following one until it hits a dead end. And when it hits a dead end, depth first search effectively goes back to the last decision point and tries the other path, fully exhausting this entire path. And when it realizes that, OK, the goal is not here, then it turns its attention to this path. It goes as deep as possible. When it hits a dead end, it backs up and then tries this other path, keeps going as deep as possible down one particular path. And when it realizes that that’s a dead end, then it’ll back up, and then ultimately find its way to the goal. And maybe you got lucky, and maybe you made a different choice earlier on. But ultimately, this is how depth first search is going to work. It’s going to keep following until it hits a dead end. And when it hits a dead end, it backs up and looks for a different solution. And so one thing you might reasonably ask is, is this algorithm always going to work? Will it always actually find a way to get from the initial state? To the goal. And it turns out that as long as our maze is finite, as long as there are only finitely many spaces where we can travel, then, yes, depth first search is going to find a solution. Because eventually, it’ll just explore everything. If the maze happens to be infinite and there’s an infinite state space, which does exist in certain types of problems, then it’s a slightly different story. But as long as our maze has finitely many squares, we’re going to find a solution. The next question, though, that we want to ask is, is it going to be a good solution? Is it the optimal solution that we can find? And the answer there is not necessarily. And let’s take a look at an example of that. In this maze, for example, we’re again trying to find our way from A to B. And you notice here there are multiple possible solutions. We could go this way or we could go up in order to make our way from A to B. Now, if we’re lucky, depth first search will choose this way and get to B. But there’s no reason necessarily why depth first search would choose between going up or going to the right. It’s sort of an arbitrary decision point because both are going to be added to the frontier. And ultimately, if we get unlucky, depth first search might choose to explore this path first because it’s just a random choice at this point. It’ll explore, explore, explore. And it’ll eventually find the goal, this particular path, when in actuality there was a better path. There was a more optimal solution that used fewer steps, assuming we’re measuring the cost of a solution based on the number of steps that we need to take. So depth first search, if we’re unlucky, might end up not finding the best solution when a better solution is available. So that’s DFS, depth first search. How does BFS, or breadth first search, compare? How would it work in this particular situation? Well, the algorithm is going to look very different visually in terms of how BFS explores. Because BFS looks at shallower nodes first, the idea is going to be, BFS will first look at all of the nodes that are one away from the initial state. Look here and look here, for example, just at the two nodes that are immediately next to this initial state. Then it’ll explore nodes that are two away, looking at this state and that state, for example. Then it’ll explore nodes that are three away, this state and that state. Whereas depth first search just picked one path and kept following it, breadth first search, on the other hand, is taking the option of exploring all of the possible paths as kind of at the same time bouncing back between them, looking deeper and deeper at each one, but making sure to explore the shallower ones or the ones that are closer to the initial state earlier. So we’ll keep following this pattern, looking at things that are four away, looking at things that are five away, looking at things that are six away, until eventually we make our way to the goal. And in this case, it’s true we had to explore some states that ultimately didn’t lead us anywhere, but the path that we found to the goal was the optimal path. This is the shortest way that we could get to the goal. And so what might happen then in a larger maze? Well, let’s take a look at something like this and how breadth first search is going to behave. Well, breadth first search, again, we’ll just keep following the states until it receives a decision point. It could go either left or right. And while DFS just picked one and kept following that until it hit a dead end, BFS, on the other hand, will explore both. It’ll say look at this node, then this node, and it’ll look at this node, then that node. So on and so forth. And when it hits a decision point here, rather than pick one left or two right and explore that path, it’ll again explore both, alternating between them, going deeper and deeper. We’ll explore here, and then maybe here and here, and then keep going. Explore here and slowly make our way, you can visually see, further and further out. Once we get to this decision point, we’ll explore both up and down until ultimately we make our way to the goal. And what you’ll notice is, yes, breadth first search did find our way from A to B by following this particular path, but it needed to explore a lot of states in order to do so. And so we see some trade offs here between DFS and BFS, that in DFS, there may be some cases where there is some memory savings as compared to a breadth first approach, where breadth first search in this case had to explore a lot of states. But maybe that won’t always be the case. So now let’s actually turn our attention to some code and look at the code that we could actually write in order to implement something like depth first search or breadth first search in the context of solving a maze, for example. So I’ll go ahead and go into my terminal. And what I have here inside of maze.py is an implementation of this same idea of maze solving. I’ve defined a class called node that in this case is keeping track of the state, the parent, in other words, the state before the state, and the action. In this case, we’re not keeping track of the path cost because we can calculate the cost of the path at the end after we found our way from the initial state to the goal. In addition to this, I’ve defined a class called a stack frontier. And if unfamiliar with a class, a class is a way for me to define a way to generate objects in Python. It refers to an idea of object oriented programming, where the idea here is that I would like to create an object that is able to store all of my frontier data. And I would like to have functions, otherwise known as methods, on that object that I can use to manipulate the object. And so what’s going on here, if unfamiliar with the syntax, is I have a function that initially creates a frontier that I’m going to represent using a list. And initially, my frontier is represented by the empty list. There’s nothing in my frontier to begin with. I have an add function that adds something to the frontier as by appending it to the end of the list. I have a function that checks if the frontier contains a particular state. I have an empty function that checks if the frontier is empty. If the frontier is empty, that just means the length of the frontier is 0. And then I have a function for removing something from the frontier. I can’t remove something from the frontier if the frontier is empty, so I check for that first. But otherwise, if the frontier isn’t empty, recall that I’m implementing this frontier as a stack, a last in first out data structure, which means the last thing I add to the frontier, in other words, the last thing in the list, is the item that I should remove from this frontier. So what you’ll see here is I have removed the last item of a list. And if you index into a Python list with negative 1, that gets you the last item in the list. Since 0 is the first item, negative 1 kind of wraps around and gets you to the last item in the list. So we give that the node. We call that node. We update the frontier here on line 28 to say, go ahead and remove that node that you just removed from the frontier. And then we return the node as a result. So this class here effectively implements the idea of a frontier. It gives me a way to add something to a frontier and a way to remove something from the frontier as a stack. I’ve also, just for good measure, implemented an alternative version of the same thing called a queue frontier, which in parentheses you’ll see here, it inherits from a stack frontier, meaning it’s going to do all the same things that the stack frontier did, except the way we remove a node from the frontier is going to be slightly different. Instead of removing from the end of the list the way we would in a stack, we’re instead going to remove from the beginning of the list. Self.frontier 0 will get me the first node in the frontier, the first one that was added, and that is going to be the one that we return in the case of a queue. Then under here, I have a definition of a class called maze. This is going to handle the process of taking a sequence, a maze-like text file, and figuring out how to solve it. So it will take as input a text file that looks something like this, for example, where we see hash marks that are here representing walls, and I have the character A representing the starting position and the character B representing the ending position. And you can take a look at the code for parsing this text file right now. That’s the less interesting part. The more interesting part is this solve function here, the solve function is going to figure out how to actually get from point A to point B. And here we see an implementation of the exact same idea we saw from a moment ago. We’re going to keep track of how many states we’ve explored, just so we can report that data later. But I start with a node that represents just the start state. And I start with a frontier that, in this case, is a stack frontier. And given that I’m treating my frontier as a stack, you might imagine that the algorithm I’m using here is now depth-first search, because depth-first search, or DFS, uses a stack as its data structure. And initially, this frontier is just going to contain the start state. We initialize an explored set that initially is empty. There’s nothing we’ve explored so far. And now here’s our loop, that notion of repeating something again and again. First, we check if the frontier is empty by calling that empty function that we saw the implementation of a moment ago. And if the frontier is indeed empty, we’ll go ahead and raise an exception, or a Python error, to say, sorry, there is no solution to this problem. Otherwise, we’ll go ahead and remove a node from the frontier as by calling frontier.remove and update the number of states we’ve explored, because now we’ve explored one additional state. So we say self.numexplored plus equals 1, adding 1 to the number of states we’ve explored. Once we remove a node from the frontier, recall that the next step is to see whether or not it’s the goal, the goal test. And in the case of the maze, the goal is pretty easy. I check to see whether the state of the node is equal to the goal. Initially, when I set up the maze, I set up this value called goal, which is a property of the maze, so I can just check to see if the node is actually the goal. And if it is the goal, then what I want to do is backtrack my way towards figuring out what actions I took in order to get to this goal. And how do I do that? We’ll recall that every node stores its parent, the node that came before it that we used to get to this node, and also the action used in order to get there. So I can create this loop where I’m constantly just looking at the parent of every node and keeping track for all of the parents what action I took to get from the parent to this current node. So this loop is going to keep repeating this process of looking through all of the parent nodes until we get back to the initial state, which has no parent, where node.parent is going to be equal to none. As I do so, I’m going to be building up the list of all of the actions that I’m following and the list of all the cells that are part of the solution. But I’ll reverse them because when I build it up, going from the goal back to the initial state and building the sequence of actions from the goal to the initial state, but I want to reverse them in order to get the sequence of actions from the initial state to the goal. And that is ultimately going to be the solution. So all of that happens if the current state is equal to the goal. And otherwise, if it’s not the goal, well, then I’ll go ahead and add this state to the explored set to say, I’ve explored this state now. No need to go back to it if I come across it in the future. And then this logic here implements the idea of adding neighbors to the frontier. I’m saying, look at all of my neighbors, and I implemented a function called neighbors that you can take a look at. And for each of those neighbors, I’m going to check, is the state already in the frontier? Is the state already in the explored set? And if it’s not in either of those, then I’ll go ahead and add this new child node, this new node, to the frontier. So there’s a fair amount of syntax here, but the key here is not to understand all the nuances of the syntax. So feel free to take a closer look at this file on your own to get a sense for how it is working. But the key is to see how this is an implementation of the same pseudocode, the same idea that we were describing a moment ago on the screen when we were looking at the steps that we might follow in order to solve this kind of search problem. So now let’s actually see this in action. I’ll go ahead and run maze.py on maze1.txt, for example. And what we’ll see is here, we have a printout of what the maze initially looked like. And then here down below is after we’ve solved it. We had to explore 11 states in order to do it, and we found a path from A to B. And in this program, I just happened to generate a graphical representation of this as well. So I can open up maze.png, which is generated by this program, that shows you where in the darker color here are the walls, red is the initial state, green is the goal, and yellow is the path that was followed. We found a path from the initial state to the goal. But now let’s take a look at a more sophisticated maze to see what might happen instead. Let’s look now at maze2.txt. We’re now here. We have a much larger maze. Again, we’re trying to find our way from point A to point B. But now you’ll imagine that depth-first search might not be so lucky. It might not get the goal on the first try. It might have to follow one path, then backtrack and explore something else a little bit later. So let’s try this. We’ll run python maze.py of maze2.txt, this time trying on this other maze. And now, depth-first search is able to find a solution. Here, as indicated by the stars, is a way to get from A to B. And we can represent this visually by opening up this maze. Here’s what that maze looks like, and highlighted in yellow is the path that was found from the initial state to the goal. But how many states did we have to explore before we found that path? Well, recall that in my program, I was keeping track of the number of states that we’ve explored so far. And so I can go back to the terminal and see that, all right, in order to solve this problem, we had to explore 399 different states. And in fact, if I make one small modification of the program and tell the program at the end when we output this image, I added an argument called show explored. And if I set show explored equal to true and rerun this program, python maze.py, running it on maze2, and then I open the maze, what you’ll see here is highlighted in red are all of the states that had to be explored to get from the initial state to the goal. Depth-first search, or DFS, didn’t find its way to the goal right away. It made a choice to first explore this direction. And when it explored this direction, it had to follow every conceivable path all the way to the very end, even this long and winding one, in order to realize that, you know what? That’s a dead end. And instead, the program needed to backtrack. After going this direction, it must have gone this direction. It got lucky here by just not choosing this path, but it got unlucky here, exploring this direction, exploring a bunch of states it didn’t need to, and then likewise exploring all of this top part of the graph when it probably didn’t need to do that either. So all in all, depth-first search here really not performing optimally, or probably exploring more states than it needs to. It finds an optimal solution, the best path to the goal, but the number of states needed to explore in order to do so, the number of steps I had to take, that was much higher. So let’s compare. How would breadth-first search, or BFS, do on this exact same maze instead? And in order to do so, it’s a very easy change. The algorithm for DFS and BFS is identical with the exception of what data structure we use to represent the frontier, that in DFS, I used a stack frontier, last in, first out, whereas in BFS, I’m going to use a queue frontier, first in, first out, where the first thing I add to the frontier is the first thing that I remove. So I’ll go back to the terminal, rerun this program on the same maze, and now you’ll see that the number of states we had to explore was only 77 as compared to almost 400 when we used depth-first search. And we can see exactly why. We can see what happened if we open up maze.png now and take a look. Again, yellow highlight is the solution that breadth-first search found, which incidentally is the same solution that depth-first search found. They’re both finding the best solution. But notice all the white unexplored cells. There was much fewer states that needed to be explored in order to make our way to the goal because breadth-first search operates a little more shallowly. It’s exploring things that are close to the initial state without exploring things that are further away. So if the goal is not too far away, then breadth-first search can actually behave quite effectively on a maze that looks a little something like this. Now, in this case, both BFS and DFS ended up finding the same solution, but that won’t always be the case. And in fact, let’s take a look at one more example. For instance, maze3.txt. In maze3.txt, notice that here there are multiple ways that you could get from A to B. It’s a relatively small maze, but let’s look at what happens. If I use, and I’ll go ahead and turn off show explored so we just see the solution. If I use BFS, breadth-first search, to solve maze3.txt, well, then we find a solution, and if I open up the maze, here is the solution that we found. It is the optimal one. With just four steps, we can get from the initial state to what the goal happens to be. But what happens if we tried to use depth-first search or DFS instead? Well, again, I’ll go back up to my Q frontier, where Q frontier means that we’re using breadth-first search, and I’ll change it to a stack frontier, which means that now we’ll be using depth-first search. I’ll rerun pythonmaze.py, and now you’ll see that we find the solution, but it is not the optimal solution. This instead is what our algorithm finds, and maybe depth-first search would have found the solution. It’s possible, but it’s not guaranteed that if we just happen to be unlucky, if we choose this state instead of that state, then depth-first search might find a longer route to get from the initial state to the goal. So we do see some trade-offs here, where depth-first search might not find the optimal solution. So at that point, it seems like breadth-first search is pretty good. Is that the best we can do, where it’s going to find us the optimal solution, and we don’t have to worry about situations where we might end up finding a longer path to the solution than what actually exists? Where the goal is far away from the initial state, and we might have to take lots of steps in order to get from the initial state to the goal, what ended up happening is that this algorithm, BFS, ended up exploring basically the entire graph, having to go through the entire maze in order to find its way from the initial state to the goal state. What we’d ultimately like is for our algorithm to be a little bit more intelligent. And now what would it mean for our algorithm to be a little bit more intelligent in this case? Well, let’s look back to where breadth-first search might have been able to make a different decision and consider human intuition in this process as well. What might a human do when solving this maze that is different than what BFS ultimately chose to do? Well, the very first decision point that BFS made was right here, when it made five steps and ended up in a position where it had a fork in the row. It could either go left or it could go right. In these initial couple steps, there was no choice. There was only one action that could be taken from each of those states. And so the search algorithm did the only thing that any search algorithm could do, which is keep following that state after the next state. But this decision point is where things get a little bit interesting. Depth-first search, that very first search algorithm we looked at, chose to say, let’s pick one path and exhaust that path. See if anything that way has the goal. And if not, then let’s try the other way. Depth-first search took the alternative approach of saying, you know what, let’s explore things that are shallow, close to us first. Look left and right, then back left and back right, so on and so forth, alternating between our options in the hopes of finding something nearby. But ultimately, what might a human do if confronted with a situation like this of go left or go right? Well, a human might visually see that, all right, I’m trying to get to state b, which is way up there, and going right just feels like it’s closer to the goal. It feels like going right should be better than going left because I’m making progress towards getting to that goal. Now, of course, there are a couple of assumptions that I’m making here. I’m making the assumption that we can represent this grid as like a two-dimensional grid where I know the coordinates of everything. I know that a is in coordinate 0, 0, and b is in some other coordinate pair, and I know what coordinate I’m at now. So I can calculate that, yeah, going this way, that is closer to the goal. And that might be a reasonable assumption for some types of search problems, but maybe not in others. But for now, we’ll go ahead and assume that, that I know what my current coordinate pair is, and I know the coordinate, x, y, of the goal that I’m trying to get to. And in this situation, I’d like an algorithm that is a little bit more intelligent, that somehow knows that I should be making progress towards the goal, and this is probably the way to do that because in a maze, moving in the coordinate direction of the goal is usually, though not always, a good thing. And so here we draw a distinction between two different types of search algorithms, uninformed search and informed search. Uninformed search algorithms are algorithms like DFS and BFS, the two algorithms that we just looked at, which are search strategies that don’t use any problem-specific knowledge to be able to solve the problem. DFS and BFS didn’t really care about the structure of the maze or anything about the way that a maze is in order to solve the problem. They just look at the actions available and choose from those actions, and it doesn’t matter whether it’s a maze or some other problem, the solution or the way that it tries to solve the problem is really fundamentally going to be the same. What we’re going to take a look at now is an improvement upon uninformed search. We’re going to take a look at informed search. Informed search are going to be search strategies that use knowledge specific to the problem to be able to better find a solution. And in the case of a maze, this problem-specific knowledge is something like if I’m in a square that is geographically closer to the goal, that is better than being in a square that is geographically further away. And this is something we can only know by thinking about this problem and reasoning about what knowledge might be helpful for our AI agent to know a little something about. There are a number of different types of informed search. Specifically, first, we’re going to look at a particular type of search algorithm called greedy best-first search. Greedy best-first search, often abbreviated G-BFS, is a search algorithm that instead of expanding the deepest node like DFS or the shallowest node like BFS, this algorithm is always going to expand the node that it thinks is closest to the goal. Now, the search algorithm isn’t going to know for sure whether it is the closest thing to the goal. Because if we knew what was closest to the goal all the time, then we would already have a solution. The knowledge of what is close to the goal, we could just follow those steps in order to get from the initial position to the solution. But if we don’t know the solution, meaning we don’t know exactly what’s closest to the goal, instead we can use an estimate of what’s closest to the goal, otherwise known as a heuristic, just some way of estimating whether or not we’re close to the goal. And we’ll do so using a heuristic function conventionally called h of n that takes a status input and returns our estimate of how close we are to the goal. So what might this heuristic function actually look like in the case of a maze solving algorithm? Where we’re trying to solve a maze, what does the heuristic look like? Well, the heuristic needs to answer a question between these two cells, C and D, which one is better? Which one would I rather be in if I’m trying to find my way to the goal? Well, any human could probably look at this and tell you, you know what, D looks like it’s better. Even if the maze is convoluted and you haven’t thought about all the walls, D is probably better. And why is D better? Well, because if you ignore the wall, so let’s just pretend the walls don’t exist for a moment and relax the problem, so to speak, D, just in terms of coordinate pairs, is closer to this goal. It’s fewer steps that I wouldn’t take to get to the goal as compared to C, even if you ignore the walls. If you just know the xy-coordinate of C and the xy-coordinate of the goal, and likewise you know the xy-coordinate of D, you can calculate the D just geographically. Ignoring the walls looks like it’s better. And so this is the heuristic function that we’re going to use. And it’s something called the Manhattan distance, one specific type of heuristic, where the heuristic is how many squares vertically and horizontally and then left to right, so not allowing myself to go diagonally, just either up or right or left or down. How many steps do I need to take to get from each of these cells to the goal? Well, as it turns out, D is much closer. There are fewer steps. It only needs to take six steps in order to get to that goal. Again, here, ignoring the walls. We’ve relaxed the problem a little bit. We’re just concerned with if you do the math to subtract the x values from each other and the y values from each other, what is our estimate of how far we are away? We can estimate the D is closer to the goal than C is. And so now we have an approach. We have a way of picking which node to remove from the frontier. And at each stage in our algorithm, we’re going to remove a node from the frontier. We’re going to explore the node if it has the smallest value for this heuristic function, if it has the smallest Manhattan distance to the goal. And so what would this actually look like? Well, let me first label this graph, label this maze, with a number representing the value of this heuristic function, the value of the Manhattan distance from any of these cells. So from this cell, for example, we’re one away from the goal. From this cell, we’re two away from the goal, three away, four away. Here, we’re five away because we have to go one to the right and then four up. From somewhere like here, the Manhattan distance is two. We’re only two squares away from the goal geographically, even though in practice, we’re going to have to take a longer path. But we don’t know that yet. The heuristic is just some easy way to estimate how far we are away from the goal. And maybe our heuristic is overly optimistic. It thinks that, yeah, we’re only two steps away. When in practice, when you consider the walls, it might be more steps. So the important thing here is that the heuristic isn’t a guarantee of how many steps it’s going to take. It is estimating. It’s an attempt at trying to approximate. And it does seem generally the case that the squares that look closer to the goal have smaller values for the heuristic function than squares that are further away. So now, using greedy best-first search, what might this algorithm actually do? Well, again, for these first five steps, there’s not much of a choice. We start at this initial state a, and we say, all right, we have to explore these five states. But now we have a decision point. Now we have a choice between going left and going right. And before, when DFS and BFS would just pick arbitrarily, because it just depends on the order you throw these two nodes into the frontier, and we didn’t specify what order you put them into the frontier, only the order you take them out, here we can look at 13 and 11 and say that, all right, this square is a distance of 11 away from the goal according to our heuristic, according to our estimate. And this one, we estimate to be 13 away from the goal. So between those two options, between these two choices, I’d rather have the 11. I’d rather be 11 steps away from the goal, so I’ll go to the right. We’re able to make an informed decision, because we know a little something more about this problem. So then we keep following, 10, 9, 8. Between the two 7s, we don’t really have much of a way to know between those. So then we do just have to make an arbitrary choice. And you know what, maybe we choose wrong. But that’s OK, because now we can still say, all right, let’s try this 7. We say 7, 6, we have to make this choice, even though it increases the value of the heuristic function. But now we have another decision point, between 6 and 8, and between those two. And really, we’re also considering this 13, but that’s much higher. Between 6, 8, and 13, well, the 6 is the smallest value, so we’d rather take the 6. We’re able to make an informed decision that going this way to the right is probably better than going down. So we turn this way, we go to 5. And now we find a decision point where we’ll actually make a decision that we might not want to make, but there’s unfortunately not too much of a way around this. We see 4 and 6. 4 looks closer to the goal, right? It’s going up, and the goal is further up. So we end up taking that route, which ultimately leads us to a dead end. But that’s OK, because we can still say, all right, now let’s try the 6. And now follow this route that will ultimately lead us to the goal. And so this now is how greedy best-for-search might try to approach this problem by saying, whenever we have a decision between multiple nodes that we could explore, let’s explore the node that has the smallest value of h of n, this heuristic function that is estimating how far I have to go. And it just so happens that in this case, we end up doing better in terms of the number of states we needed to explore than BFS needed to. BFS explored all of this section and all of that section, but we were able to eliminate that by taking advantage of this heuristic, this knowledge about how close we are to the goal or some estimate of that idea. So this seems much better. So wouldn’t we always prefer an algorithm like this over an algorithm like breadth-first search? Well, maybe one thing to take into consideration is that we need to come up with a good heuristic, how good the heuristic is, is going to affect how good this algorithm is. And coming up with a good heuristic can oftentimes be challenging. But the other thing to consider is to ask the question, just as we did with the prior two algorithms, is this algorithm optimal? Will it always find the shortest path from the initial state to the goal? And to answer that question, let’s take a look at this example for a moment. Take a look at this example. Again, we’re trying to get from A to B. And again, I’ve labeled each of the cells with their Manhattan distance from the goal. The number of squares up and to the right, you would need to travel in order to get from that square to the goal. And let’s think about, would greedy best-first search that always picks the smallest number end up finding the optimal solution? What is the shortest solution? And would this algorithm find it? And the important thing to realize is that right here is the decision point. We’re estimated to be 12 away from the goal. And we have two choices. We can go to the left, which we estimate to be 13 away from the goal. Or we can go up, where we estimate it to be 11 away from the goal. And between those two, greedy best-first search is going to say the 11 looks better than the 13. And in doing so, greedy best-first search will end up finding this path to the goal. But it turns out this path is not optimal. There is a way to get to the goal using fewer steps. And it’s actually this way, this way that ultimately involved fewer steps, even though it meant at this moment choosing the worst option between the two or what we estimated to be the worst option based on the heuristics. And so this is what we mean by this is a greedy algorithm. It’s making the best decision locally. At this decision point, it looks like it’s better to go here than it is to go to the 13. But in the big picture, it’s not necessarily optimal. That it might find a solution when in actuality, there was a better solution available. So we would like some way to solve this problem. We like the idea of this heuristic, of being able to estimate the path, the distance between us and the goal. And that helps us to be able to make better decisions and to eliminate having to search through entire parts of this state space. But we would like to modify the algorithm so that we can achieve optimality, so that it can be optimal. And what is the way to do this? What is the intuition here? Well, let’s take a look at this problem. In this initial problem, greedy best research found us this solution here, this long path. And the reason why it wasn’t great is because, yes, the heuristic numbers went down pretty low. But later on, they started to build back up. They built back 8, 9, 10, 11, all the way up to 12 in this case. And so how might we go about trying to improve this algorithm? Well, one thing that we might realize is that if we go all the way through this algorithm, through this path, and we end up going to the 12, and we’ve had to take this many steps, who knows how many steps that is, just to get to this 12, we could have also, as an alternative, taken much fewer steps, just six steps, and ended up at this 13 here. And yes, 13 is more than 12, so it looks like it’s not as good. But it required far fewer steps. It only took six steps to get to this 13 versus many more steps to get to this 12. And while greedy best research says, oh, well, 12 is better than 13, so pick the 12, we might more intelligently say, I’d rather be somewhere that heuristically looks like it takes slightly longer if I can get there much more quickly. And we’re going to encode that idea, this general idea, into a more formal algorithm known as A star search. A star search is going to solve this problem by instead of just considering the heuristic, also considering how long it took us to get to any particular state. So the distinction is greedy best for search. If I am in a state right now, the only thing I care about is, what is the estimated distance, the heuristic value, between me and the goal? Whereas A star search will take into consideration two pieces of information. It’ll take into consideration, how far do I estimate I am from the goal? But also, how far did I have to travel in order to get here? Because that is relevant, too. So we’ll search algorithms by expanding the node with the lowest value of g of n plus h of n. h of n is that same heuristic that we were talking about a moment ago that’s going to vary based on the problem. But g of n is going to be the cost to reach the node, how many steps I had to take, in this case, to get to my current position. So what does that search algorithm look like in practice? Well, let’s take a look. Again, we’ve got the same maze. And again, I’ve labeled them with their Manhattan distance. This value is the h of n value, the heuristic estimate of how far each of these squares is away from the goal. But now, as we begin to explore states, we care not just about this heuristic value, but also about g of n, the number of steps I had to take in order to get there. And I care about summing those two numbers together. So what does that look like? On this very first step, I have taken one step. And now I am estimated to be 16 steps away from the goal. So the total value here is 17. Then I take one more step. I’ve now taken two steps. And I estimate myself to be 15 away from the goal, again, a total value of 17. Now I’ve taken three steps. And I’m estimated to be 14 away from the goal, so on and so forth. Four steps, an estimate of 13. Five steps, estimate of 12. And now here’s a decision point. I could either be six steps away from the goal with a heuristic of 13 for a total of 19, or I could be six steps away from the goal with a heuristic of 11 with an estimate of 17 for the total. So between 19 and 17, I’d rather take the 17, the 6 plus 11. So so far, no different than what we saw before. We’re still taking this option because it appears to be better. And I keep taking this option because it appears to be better. But it’s right about here that things get a little bit different. Now I could be 15 steps away from the goal with an estimated distance of 6. So 15 plus 6, total value of 21. Alternatively, I could be six steps away from the goal, because this is five steps away, so this is six steps away, with a total value of 13 as my estimate. So 6 plus 13, that’s 19. So here, we would evaluate g of n plus h of n to be 19, 6 plus 13. Whereas here, we would be 15 plus 6, or 21. And so the intuition is 19 less than 21, pick here. But the idea is ultimately I’d rather be having taken fewer steps, get to a 13, than having taken 15 steps and be at a 6, because it means I’ve had to take more steps in order to get there. Maybe there’s a better path this way. So instead, we’ll explore this route. Now if we go one more, this is seven steps plus 14 is 21. So between those two, it’s sort of a toss-up. We might end up exploring that one anyways. But after that, as these numbers start to get bigger in the heuristic values, and these heuristic values start to get smaller, you’ll find that we’ll actually keep exploring down this path. And you can do the math to see that at every decision point, A star search is going to make a choice based on the sum of how many steps it took me to get to my current position, and then how far I estimate I am from the goal. So while we did have to explore some of these states, the ultimate solution we found was, in fact, an optimal solution. It did find us the quickest possible way to get from the initial state to the goal. And it turns out that A star is an optimal search algorithm under certain conditions. So the conditions are H of n, my heuristic, needs to be admissible. What does it mean for a heuristic to be admissible? Well, a heuristic is admissible if it never overestimates the true cost. H of n always needs to either get it exactly right in terms of how far away I am, or it needs to underestimate. So we saw an example from before where the heuristic value was much smaller than the actual cost it would take. That’s totally fine, but the heuristic value should never overestimate. It should never think that I’m further away from the goal than I actually am. And meanwhile, to make a stronger statement, H of n also needs to be consistent. And what does it mean for it to be consistent? Mathematically, it means that for every node, which we’ll call n, and successor, the node after me, that I’ll call n prime, where it takes a cost of C to make that step, the heuristic value of n needs to be less than or equal to the heuristic value of n prime plus the cost. So it’s a lot of math, but in words what that ultimately means is that if I am here at this state right now, the heuristic value from me to the goal shouldn’t be more than the heuristic value of my successor, the next place I could go to, plus however much it would cost me to just make that step from one step to the next step. And so this is just making sure that my heuristic is consistent between all of these steps that I might take. So as long as this is true, then A star search is going to find me an optimal solution. And this is where much of the challenge of solving these search problems can sometimes come in, that A star search is an algorithm that is known and you could write the code fairly easily, but it’s choosing the heuristic. It can be the interesting challenge. The better the heuristic is, the better I’ll be able to solve the problem in the fewer states that I’ll have to explore. And I need to make sure that the heuristic satisfies these particular constraints. So all in all, these are some of the examples of search algorithms that might work, and certainly there are many more than just this. A star, for example, does have a tendency to use quite a bit of memory. So there are alternative approaches to A star that ultimately use less memory than this version of A star happens to use, and there are other search algorithms that are optimized for other cases as well. But now so far, we’ve only been looking at search algorithms where there is one agent. I am trying to find a solution to a problem. I am trying to navigate my way through a maze. I am trying to solve a 15 puzzle. I am trying to find driving directions from point A to point B. Sometimes in search situations, though, we’ll enter an adversarial situation, where I am an agent trying to make intelligent decisions. And there’s someone else who is fighting against me, so to speak, that has opposite objectives, someone where I am trying to succeed, someone else that wants me to fail. And this is most popular in something like a game, a game like Tic Tac Toe, where we’ve got this 3 by 3 grid, and x and o take turns, either writing an x or an o in any one of these squares. And the goal is to get three x’s in a row if you’re the x player, or three o’s in a row if you’re the o player. And computers have gotten quite good at playing games, Tic Tac Toe very easily, but even more complex games. And so you might imagine, what does an intelligent decision in a game look like? So maybe x makes an initial move in the middle, and o plays up here. What does an intelligent move for x now become? Where should you move if you were x? And it turns out there are a couple of possibilities. But if an AI is playing this game optimally, then the AI might play somewhere like the upper right, where in this situation, o has the opposite objective of x. x is trying to win the game to get three in a row diagonally here. And o is trying to stop that objective, opposite of the objective. And so o is going to place here to try to block. But now, x has a pretty clever move. x can make a move like this, where now x has two possible ways that x can win the game. x could win the game by getting three in a row across here. Or x could win the game by getting three in a row vertically this way. So it doesn’t matter where o makes their next move. o could play here, for example, blocking the three in a row horizontally. But then x is going to win the game by getting a three in a row vertically. And so there’s a fair amount of reasoning that’s going on here in order for the computer to be able to solve a problem. And it’s similar in spirit to the problems we’ve looked at so far. There are actions. There’s some sort of state of the board and some transition from one action to the next. But it’s different in the sense that this is now not just a classical search problem, but an adversarial search problem. That I am at the x player trying to find the best moves to make, but I know that there is some adversary that is trying to stop me. So we need some sort of algorithm to deal with these adversarial type of search situations. And the algorithm we’re going to take a look at is an algorithm called Minimax, which works very well for these deterministic games where there are two players. It can work for other types of games as well. But we’ll look right now at games where I make a move, then my opponent makes a move. And I am trying to win, and my opponent is trying to win also. Or in other words, my opponent is trying to get me to lose. And so what do we need in order to make this algorithm work? Well, any time we try and translate this human concept of playing a game, winning and losing to a computer, we want to translate it in terms that the computer can understand. And ultimately, the computer really just understands the numbers. And so we want some way of translating a game of x’s and o’s on a grid to something numerical, something the computer can understand. The computer doesn’t normally understand notions of win or lose. But it does understand the concept of bigger and smaller. And so what we might do is we might take each of the possible ways that a tic-tac-toe game can unfold and assign a value or a utility to each one of those possible ways. And in a tic-tac-toe game, and in many types of games, there are three possible outcomes. The outcomes are o wins, x wins, or nobody wins. So player one wins, player two wins, or nobody wins. And for now, let’s go ahead and assign each of these possible outcomes a different value. We’ll say o winning, that’ll have a value of negative 1. Nobody winning, that’ll have a value of 0. And x winning, that will have a value of 1. So we’ve just assigned numbers to each of these three possible outcomes. And now we have two players, we have the x player and the o player. And we’re going to go ahead and call the x player the max player. And we’ll call the o player the min player. And the reason why is because in the min and max algorithm, the max player, which in this case is x, is aiming to maximize the score. These are the possible options for the score, negative 1, 0, and 1. x wants to maximize the score, meaning if at all possible, x would like this situation, where x wins the game, and we give it a score of 1. But if this isn’t possible, if x needs to choose between these two options, negative 1, meaning o winning, or 0, meaning nobody winning, x would rather that nobody wins, score of 0, than a score of negative 1, o winning. So this notion of winning and losing and tying has been reduced mathematically to just this idea of try and maximize the score. The x player always wants the score to be bigger. And on the flip side, the min player, in this case o, is aiming to minimize the score. The o player wants the score to be as small as possible. So now we’ve taken this game of x’s and o’s and winning and losing and turned it into something mathematical, something where x is trying to maximize the score, o is trying to minimize the score. Let’s now look at all of the parts of the game that we need in order to encode it in an AI so that an AI can play a game like tic-tac-toe. So the game is going to need a couple of things. We’ll need some sort of initial state that will, in this case, call s0, which is how the game begins, like an empty tic-tac-toe board, for example. We’ll also need a function called player, where the player function is going to take as input a state here represented by s. And the output of the player function is going to be which player’s turn is it. We need to be able to give a tic-tac-toe board to the computer, run it through a function, and that function tells us whose turn it is. We’ll need some notion of actions that we can take. We’ll see examples of that in just a moment. We need some notion of a transition model, same as before. If I have a state and I take an action, I need to know what results as a consequence of it. I need some way of knowing when the game is over. So this is equivalent to kind of like a goal test, but I need some terminal test, some way to check to see if a state is a terminal state, where a terminal state means the game is over. In a classic game of tic-tac-toe, a terminal state means either someone has gotten three in a row or all of the squares of the tic-tac-toe board are filled. Either of those conditions make it a terminal state. In a game of chess, it might be something like when there is checkmate or if checkmate is no longer possible, that that becomes a terminal state. And then finally, we’ll need a utility function, a function that takes a state and gives us a numerical value for that terminal state, some way of saying if x wins the game, that has a value of 1. If o is won the game, that has a value of negative 1. If nobody has won the game, that has a value of 0. So let’s take a look at each of these in turn. The initial state, we can just represent in tic-tac-toe as the empty game board. This is where we begin. It’s the place from which we begin this search. And again, I’ll be representing these things visually, but you can imagine this really just being like an array or a two-dimensional array of all of these possible squares. Then we need the player function that, again, takes a state and tells us whose turn it is. Assuming x makes the first move, if I have an empty game board, then my player function is going to return x. And if I have a game board where x has made a move, then my player function is going to return o. The player function takes a tic-tac-toe game board and tells us whose turn it is. Next up, we’ll consider the actions function. The actions function, much like it did in classical search, takes a state and gives us the set of all of the possible actions we can take in that state. So let’s imagine it’s o is turned to move in a game board that looks like this. What happens when we pass it into the actions function? So the actions function takes this state of the game as input, and the output is a set of possible actions. It’s a set of I could move in the upper left or I could move in the bottom middle. So those are the two possible action choices that I have when I begin in this particular state. Now, just as before, when we had states and actions, we need some sort of transition model to tell us when we take this action in the state, what is the new state that we get. And here, we define that using the result function that takes a state as input as well as an action. And when we apply the result function to this state, saying that let’s let o move in this upper left corner, the new state we get is this resulting state where o is in the upper left corner. And now, this seems obvious to someone who knows how to play tic-tac-toe. Of course, you play in the upper left corner. That’s the board you get. But all of this information needs to be encoded into the AI. The AI doesn’t know how to play tic-tac-toe until you tell the AI how the rules of tic-tac-toe work. And this function, defining this function here, allows us to tell the AI how this game actually works and how actions actually affect the outcome of the game. So the AI needs to know how the game works. The AI also needs to know when the game is over, as by defining a function called terminal that takes as input a state s, such that if we take a game that is not yet over, pass it into the terminal function, the output is false. The game is not over. But if we take a game that is over because x has gotten three in a row along that diagonal, pass that into the terminal function, then the output is going to be true because the game now is, in fact, over. And finally, we’ve told the AI how the game works in terms of what moves can be made and what happens when you make those moves. We’ve told the AI when the game is over. Now we need to tell the AI what the value of each of those states is. And we do that by defining this utility function that takes a state s and tells us the score or the utility of that state. So again, we said that if x wins the game, that utility is a value of 1, whereas if o wins the game, then the utility of that is negative 1. And the AI needs to know, for each of these terminal states where the game is over, what is the utility of that state? So if I give you a game board like this where the game is, in fact, over, and I ask the AI to tell me what the value of that state is, it could do so. The value of the state is 1. Where things get interesting, though, is if the game is not yet over. Let’s imagine a game board like this, where in the middle of the game, it’s o’s turn to make a move. So how do we know it’s o’s turn to make a move? We can calculate that using the player function. We can say player of s, pass in the state, o is the answer. So we know it’s o’s turn to move. And now, what is the value of this board and what action should o take? Well, that’s going to depend. We have to do some calculation here. And this is where the minimax algorithm really comes in. Recall that x is trying to maximize the score, which means that o is trying to minimize the score. So o would like to minimize the total value that we get at the end of the game. And because this game isn’t over yet, we don’t really know just yet what the value of this game board is. We have to do some calculation in order to figure that out. And so how do we do that kind of calculation? Well, in order to do so, we’re going to consider, just as we might in a classical search situation, what actions could happen next and what states will that take us to. And it turns out that in this position, there are only two open squares, which means there are only two open places where o can make a move. o could either make a move in the upper left or o can make a move in the bottom middle. And minimax doesn’t know right out of the box which of those moves is going to be better. So it’s going to consider both. But now, we sort of run into the same situation. Now, I have two more game boards, neither of which is over. What happens next? And now, it’s in this sense that minimax is what we’ll call a recursive algorithm. It’s going to now repeat the exact same process, although now considering it from the opposite perspective. It’s as if I am now going to put myself, if I am the o player, I’m going to put myself in my opponent’s shoes, my opponent as the x player, and consider what would my opponent do if they were in this position? What would my opponent do, the x player, if they were in that position? And what would then happen? Well, the other player, my opponent, the x player, is trying to maximize the score, whereas I am trying to minimize the score as the o player. So x is trying to find the maximum possible value that they can get. And so what’s going to happen? Well, from this board position, x only has one choice. x is going to play here, and they’re going to get three in a row. And we know that that board, x winning, that has a value of 1. If x wins the game, the value of that game board is 1. And so from this position, if this state can only ever lead to this state, it’s the only possible option, and this state has a value of 1, then the maximum possible value that the x player can get from this game board is also 1. From here, the only place we can get is to a game with a value of 1, so this game board also has a value of 1. Now we consider this one over here. What’s going to happen now? Well, x needs to make a move. The only move x can make is in the upper left, so x will go there. And in this game, no one wins the game. Nobody has three in a row. And so the value of that game board is 0. Nobody is 1. And so again, by the same logic, if from this board position the only place we can get to is a board where the value is 0, then this state must also have a value of 0. And now here comes the choice part, the idea of trying to minimize. I, as the o player, now know that if I make this choice moving in the upper left, that is going to result in a game with a value of 1, assuming everyone plays optimally. And if I instead play in the lower middle, choose this fork in the road, that is going to result in a game board with a value of 0. I have two options. I have a 1 and a 0 to choose from, and I need to pick. And as the min player, I would rather choose the option with the minimum value. So whenever a player has multiple choices, the min player will choose the option with the smallest value. The max player will choose the option with the largest value. Between the 1 and the 0, the 0 is smaller, meaning I’d rather tie the game than lose the game. And so this game board will say also has a value of 0, because if I am playing optimally, I will pick this fork in the road. I’ll place my o here to block x’s 3 in a row, x will move in the upper left, and the game will be over, and no one will have won the game. So this is now the logic of minimax, to consider all of the possible options that I can take, all of the actions that I can take, and then to put myself in my opponent’s shoes. I decide what move I’m going to make now by considering what move my opponent will make on the next turn. And to do that, I consider what move I would make on the turn after that, so on and so forth, until I get all the way down to the end of the game, to one of these so-called terminal states. In fact, this very decision point, where I am trying to decide as the o player what to make a decision about, might have just been a part of the logic that the x player, my opponent, was using, the move before me. This might be part of some larger tree, where x is trying to make a move in this situation, and needs to pick between three different options in order to make a decision about what to happen. And the further and further away we are from the end of the game, the deeper this tree has to go. Because every level in this tree is going to correspond to one move, one move or action that I take, one move or action that my opponent takes, in order to decide what happens. And in fact, it turns out that if I am the x player in this position, and I recursively do the logic, and see I have a choice, three choices, in fact, one of which leads to a value of 0. If I play here, and if everyone plays optimally, the game will be a tie. If I play here, then o is going to win, and I’ll lose playing optimally. Or here, where I, the x player, can win, well between a score of 0, and negative 1, and 1, I’d rather pick the board with a value of 1, because that’s the maximum value I can get. And so this board would also have a maximum value of 1. And so this tree can get very, very deep, especially as the game starts to have more and more moves. And this logic works not just for tic-tac-toe, but any of these sorts of games, where I make a move, my opponent makes a move, and ultimately, we have these adversarial objectives. And we can simplify the diagram into a diagram that looks like this. This is a more abstract version of the minimax tree, where these are each states, but I’m no longer representing them as exactly like tic-tac-toe boards. This is just representing some generic game that might be tic-tac-toe, might be some other game altogether. Any of these green arrows that are pointing up, that represents a maximizing state. I would like the score to be as big as possible. And any of these red arrows pointing down, those are minimizing states, where the player is the min player, and they are trying to make the score as small as possible. So if you imagine in this situation, I am the maximizing player, this player here, and I have three choices. One choice gives me a score of 5, one choice gives me a score of 3, and one choice gives me a score of 9. Well, then between those three choices, my best option is to choose this 9 over here, the score that maximizes my options out of all the three options. And so I can give this state a value of 9, because among my three options, that is the best choice that I have available to me. So that’s my decision now. You imagine it’s like one move away from the end of the game. But then you could also ask a reasonable question, what might my opponent do two moves away from the end of the game? My opponent is the minimizing player. They are trying to make the score as small as possible. Imagine what would have happened if they had to pick which choice to make. One choice leads us to this state, where I, the maximizing player, am going to opt for 9, the biggest score that I can get. And 1 leads to this state, where I, the maximizing player, would choose 8, which is then the largest score that I can get. Now the minimizing player, forced to choose between a 9 or an 8, is going to choose the smallest possible score, which in this case is an 8. And that is then how this process would unfold, that the minimizing player in this case considers both of their options, and then all of the options that would happen as a result of that. So this now is a general picture of what the minimax algorithm looks like. Let’s now try to formalize it using a little bit of pseudocode. So what exactly is happening in the minimax algorithm? Well, given a state s, we need to decide what to happen. The max player, if it’s max’s player’s turn, then max is going to pick an action a in actions of s. Recall that actions is a function that takes a state and gives me back all of the possible actions that I can take. It tells me all of the moves that are possible. The max player is going to specifically pick an action a in this set of actions that gives me the highest value of min value of result of s and a. So what does that mean? Well, it means that I want to make the option that gives me the highest score of all of the actions a. But what score is that going to have? To calculate that, I need to know what my opponent, the min player, is going to do if they try to minimize the value of the state that results. So we say, what state results after I take this action? And what happens when the min player tries to minimize the value of that state? I consider that for all of my possible options. And after I’ve considered that for all of my possible options, I pick the action a that has the highest value. Likewise, the min player is going to do the same thing but backwards. They’re also going to consider what are all of the possible actions they can take if it’s their turn. And they’re going to pick the action a that has the smallest possible value of all the options. And the way they know what the smallest possible value of all the options is is by considering what the max player is going to do by saying, what’s the result of applying this action to the current state? And then what would the max player try to do? What value would the max player calculate for that particular state? So everyone makes their decision based on trying to estimate what the other person would do. And now we need to turn our attention to these two functions, max value and min value. How do you actually calculate the value of a state if you’re trying to maximize its value? And how do you calculate the value of a state if you’re trying to minimize the value? If you can do that, then we have an entire implementation of this min and max algorithm. So let’s try it. Let’s try and implement this max value function that takes a state and returns as output the value of that state if I’m trying to maximize the value of the state. Well, the first thing I can check for is to see if the game is over. Because if the game is over, in other words, if the state is a terminal state, then this is easy. I already have this utility function that tells me what the value of the board is. If the game is over, I just check, did x win, did o win, is it a tie? And this utility function just knows what the value of the state is. What’s trickier is if the game isn’t over. Because then I need to do this recursive reasoning about thinking, what is my opponent going to do on the next move? And I want to calculate the value of this state. And I want the value of the state to be as high as possible. And I’ll keep track of that value in a variable called v. And if I want the value to be as high as possible, I need to give v an initial value. And initially, I’ll just go ahead and set it to be as low as possible. Because I don’t know what options are available to me yet. So initially, I’ll set v equal to negative infinity, which seems a little bit strange. But the idea here is I want the value initially to be as low as possible. Because as I consider my actions, I’m always going to try and do better than v. And if I set v to negative infinity, I know I can always do better than that. So now I consider my actions. And this is going to be some kind of loop where for every action in actions of state, recall actions as a function that takes my state and gives me all the possible actions that I can use in that state. So for each one of those actions, I want to compare it to v and say, all right, v is going to be equal to the maximum of v and this expression. So what is this expression? Well, first it is get the result of taking the action in the state and then get the min value of that. In other words, let’s say I want to find out from that state what is the best that the min player can do because they’re going to try and minimize the score. So whatever the resulting score is of the min value of that state, compare it to my current best value and just pick the maximum of those two because I am trying to maximize the value. In short, what these three lines of code are doing are going through all of my possible actions and asking the question, how do I maximize the score given what my opponent is going to try to do? After this entire loop, I can just return v and that is now the value of that particular state. And for the min player, it’s the exact opposite of this, the same logic just backwards. To calculate the minimum value of a state, first we check if it’s a terminal state. If it is, we return its utility. Otherwise, we’re going to now try to minimize the value of the state given all of my possible actions. So I need an initial value for v, the value of the state. And initially, I’ll set it to infinity because I know I can always get something less than infinity. So by starting with v equals infinity, I make sure that the very first action I find, that will be less than this value of v. And then I do the same thing, loop over all of my possible actions. And for each of the results that we could get when the max player makes their decision, let’s take the minimum of that and the current value of v. So after all is said and done, I get the smallest possible value of v that I then return back to the user. So that, in effect, is the pseudocode for Minimax. That is how we take a gain and figure out what the best move to make is by recursively using these max value and min value functions, where max value calls min value, min value calls max value back and forth, all the way until we reach a terminal state, at which point our algorithm can simply return the utility of that particular state. So what you might imagine is that this is going to start to be a long process, especially as games start to get more complex, as we start to add more moves and more possible options and games that might last quite a bit longer. So the next question to ask is, what sort of optimizations can we make here? How can we do better in order to use less space or take less time to be able to solve this kind of problem? And we’ll take a look at a couple of possible optimizations. But for one, we’ll take a look at this example. Again, returning to these up arrows and down arrows, let’s imagine that I now am the max player, this green arrow. I am trying to make this score as high as possible. And this is an easy game where there are just two moves. I make a move, one of these three options. And then my opponent makes a move, one of these three options, based on what move I make. And as a result, we get some value. Let’s look at the order in which I do these calculations and figure out if there are any optimizations I might be able to make to this calculation process. I’m going to have to look at these states one at a time. So let’s say I start here on the left and say, all right, now I’m going to consider, what will the min player, my opponent, try to do here? Well, the min player is going to look at all three of their possible actions and look at their value, because these are terminal states. They’re the end of the game. And so they’ll see, all right, this node is a value of four, value of eight, value of five. And the min player is going to say, well, all right, between these three options, four, eight, and five, I’ll take the smallest one. I’ll take the four. So this state now has a value of four. Then I, as the max player, say, all right, if I take this action, it will have a value of four. That’s the best that I can do, because min player is going to try and minimize my score. So now what if I take this option? We’ll explore this next. And now explore what the min player would do if I choose this action. And the min player is going to say, all right, what are the three options? The min player has options between nine, three, and seven. And so three is the smallest among nine, three, and seven. So we’ll go ahead and say this state has a value of three. So now I, as the max player, I have now explored two of my three options. I know that one of my options will guarantee me a score of four, at least. And one of my options will guarantee me a score of three. And now I consider my third option and say, all right, what happens here? Same exact logic. The min player is going to look at these three states, two, four, and six. I’ll say the minimum possible option is two. So the min player wants the two. Now I, as the max player, have calculated all of the information by looking two layers deep, by looking at all of these nodes. And I can now say, between the four, the three, and the two, you know what? I’d rather take the four. Because if I choose this option, if my opponent plays optimally, they will try and get me to the four. But that’s the best I can do. I can’t guarantee a higher score. Because if I pick either of these two options, I might get a three or I might get a two. And it’s true that down here is a nine. And that’s the highest score out of any of the scores. So I might be tempted to say, you know what? Maybe I should take this option because I might get the nine. But if the min player is playing intelligently, if they’re making the best moves at each possible option they have when they get to make a choice, I’ll be left with a three. Whereas I could better, playing optimally, have guaranteed that I would get the four. So that is, in effect, the logic that I would use as a min and max player trying to maximize my score from that node there. But it turns out they took quite a bit of computation for me to figure that out. I had to reason through all of these nodes in order to draw this conclusion. And this is for a pretty simple game where I have three choices, my opponent has three choices, and then the game’s over. So what I’d like to do is come up with some way to optimize this. Maybe I don’t need to do all of this calculation to still reach the conclusion that, you know what, this action to the left, that’s the best that I could do. Let’s go ahead and try again and try to be a little more intelligent about how I go about doing this. So first, I start the exact same way. I don’t know what to do initially, so I just have to consider one of the options and consider what the min player might do. Min has three options, four, eight, and five. And between those three options, min says four is the best they can do because they want to try to minimize the score. Now I, the max player, will consider my second option, making this move here, and considering what my opponent would do in response. What will the min player do? Well, the min player is going to, from that state, look at their options. And I would say, all right, nine is an option, three is an option. And if I am doing the math from this initial state, doing all this calculation, when I see a three, that should immediately be a red flag for me. Because when I see a three down here at this state, I know that the value of this state is going to be at most three. It’s going to be three or something less than three, even though I haven’t yet looked at this last action or even further actions if there were more actions that could be taken here. How do I know that? Well, I know that the min player is going to try to minimize my score. And if they see a three, the only way this could be something other than a three is if this remaining thing that I haven’t yet looked at is less than three, which means there is no way for this value to be anything more than three because the min player can already guarantee a three and they are trying to minimize my score. So what does that tell me? Well, it tells me that if I choose this action, my score is going to be three or maybe even less than three if I’m unlucky. But I already know that this action will guarantee me a four. And so given that I know that this action guarantees me a score of four and this action means I can’t do better than three, if I’m trying to maximize my options, there is no need for me to consider this triangle here. There is no value, no number that could go here that would change my mind between these two options. I’m always going to opt for this path that gets me a four as opposed to this path where the best I can do is a three if my opponent plays optimally. And this is going to be true for all the future states that I look at too. That if I look over here at what min player might do over here, if I see that this state is a two, I know that this state is at most a two because the only way this value could be something other than two is if one of these remaining states is less than a two and so the min player would opt for that instead. So even without looking at these remaining states, I as the maximizing player can know that choosing this path to the left is going to be better than choosing either of those two paths to the right because this one can’t be better than three. This one can’t be better than two. And so four in this case is the best that I can do. So in order to do this cut, and I can say now that this state has a value of four. So in order to do this type of calculation, I was doing a little bit more bookkeeping, keeping track of things, keeping track all the time of what is the best that I can do, what is the worst that I can do, and for each of these states saying, all right, well, if I already know that I can get a four, then if the best I can do at this state is a three, no reason for me to consider it, I can effectively prune this leaf and anything below it from the tree. And it’s for that reason this approach, this optimization to minimax, is called alpha, beta pruning. Alpha and beta stand for these two values that you’ll have to keep track of of the best you can do so far and the worst you can do so far. And pruning is the idea of if I have a big, long, deep search tree, I might be able to search it more efficiently if I don’t need to search through everything, if I can remove some of the nodes to try and optimize the way that I look through this entire search space. So alpha, beta pruning can definitely save us a lot of time as we go about the search process by making our searches more efficient. But even then, it’s still not great as games get more complex. Tic-tac-toe, fortunately, is a relatively simple game. And we might reasonably ask a question like, how many total possible tic-tac-toe games are there? You can think about it. You can try and estimate how many moves are there at any given point, how many moves long can the game last. It turns out there are about 255,000 possible tic-tac-toe games that can be played. But compare that to a more complex game, something like a game of chess, for example. Far more pieces, far more moves, games that last much longer. How many total possible chess games could there be? It turns out that after just four moves each, four moves by the white player, four moves by the black player, that there are 288 billion possible chess games that can result from that situation, after just four moves each. And going even further, if you look at entire chess games and how many possible chess games there could be as a result there, there are more than 10 to the 29,000 possible chess games, far more chess games than could ever be considered. And this is a pretty big problem for the Minimax algorithm, because the Minimax algorithm starts with an initial state, considers all the possible actions, and all the possible actions after that, all the way until we get to the end of the game. And that’s going to be a problem if the computer is going to need to look through this many states, which is far more than any computer could ever do in any reasonable amount of time. So what do we do in order to solve this problem? Instead of looking through all these states which is totally intractable for a computer, we need some better approach. And it turns out that better approach generally takes the form of something called depth-limited Minimax, where normally Minimax is depth-unlimited. We just keep going layer after layer, move after move, until we get to the end of the game. Depth-limited Minimax is instead going to say, you know what, after a certain number of moves, maybe I’ll look 10 moves ahead, maybe I’ll look 12 moves ahead, but after that point, I’m going to stop and not consider additional moves that might come after that, just because it would be computationally intractable to consider all of those possible options. But what do we do after we get 10 or 12 moves deep when we arrive at a situation where the game’s not over? Minimax still needs a way to assign a score to that game board or game state to figure out what its current value is, which is easy to do if the game is over, but not so easy to do if the game is not yet over. So in order to do that, we need to add one additional feature to depth-limited Minimax called an evaluation function, which is just some function that is going to estimate the expected utility of a game from a given state. So in a game like chess, if you imagine that a game value of 1 means white wins, negative 1 means black wins, 0 means it’s a draw, then you might imagine that a score of 0.8 means white is very likely to win, though certainly not guaranteed. And you would have an evaluation function that estimates how good the game state happens to be. And depending on how good that evaluation function is, that is ultimately what’s going to constrain how good the AI is. The better the AI is at estimating how good or how bad any particular game state is, the better the AI is going to be able to play that game. If the evaluation function is worse and not as good as it estimating what the expected utility is, then it’s going to be a whole lot harder. And you can imagine trying to come up with these evaluation functions. In chess, for example, you might write an evaluation function based on how many pieces you have as compared to how many pieces your opponent has, because each one has a value. And your evaluation function probably needs to be a little bit more complicated than that to consider other possible situations that might arise as well. And there are many other variants on Minimax that add additional features in order to help it perform better under these larger, more computationally untractable situations where we couldn’t possibly explore all of the possible moves. So we need to figure out how to use evaluation functions and other techniques to be able to play these games ultimately better. But this now was a look at this kind of adversarial search, these search problems where we have situations where I am trying to play against some sort of opponent. And these search problems show up all over the place throughout artificial intelligence. We’ve been talking a lot today about more classical search problems, like trying to find directions from one location to another. But any time an AI is faced with trying to make a decision, like what do I do now in order to do something that is rational, or do something that is intelligent, or trying to play a game, like figuring out what move to make, these sort of algorithms can really come in handy. It turns out that for tic-tac-toe, the solution is pretty simple because it’s a small game. XKCD has famously put together a web comic where he will tell you exactly what move to make as the optimal move to make no matter what your opponent happens to do. This type of thing is not quite as possible for a much larger game like Checkers or Chess, for example, where chess is totally computationally untractable for most computers to be able to explore all the possible states. So we really need our AI to be far more intelligent about how they go about trying to deal with these problems and how they go about taking this environment that they find themselves in and ultimately searching for one of these solutions. So this, then, was a look at search in artificial intelligence. Next time, we’ll take a look at knowledge, thinking about how it is that our AIs are able to know information, reason about that information, and draw conclusions, all in our look at AI and the principles behind it. We’ll see you next time. [“AIMS INTRO MUSIC”] All right, welcome back, everyone, to an introduction to artificial intelligence with Python. Last time, we took a look at search problems, in particular, where we have AI agents that are trying to solve some sort of problem by taking actions in some sort of environment, whether that environment is trying to take actions by playing moves in a game or whether those actions are something like trying to figure out where to make turns in order to get driving directions from point A to point B. This time, we’re going to turn our attention more generally to just this idea of knowledge, the idea that a lot of intelligence is based on knowledge, especially if we think about human intelligence. People know information. We know facts about the world. And using that information that we know, we’re able to draw conclusions, reason about the information that we know in order to figure out how to do something or figure out some other piece of information that we conclude based on the information we already have available to us. What we’d like to focus on now is the ability to take this idea of knowledge and being able to reason based on knowledge and apply those ideas to artificial intelligence. In particular, we’re going to be building what are known as knowledge-based agents, agents that are able to reason and act by representing knowledge internally. Somehow inside of our AI, they have some understanding of what it means to know something. And ideally, they have some algorithms or some techniques they can use based on that knowledge that they know in order to figure out the solution to a problem or figure out some additional piece of information that can be helpful in some sense. So what do we mean by reasoning based on knowledge to be able to draw conclusions? Well, let’s look at a simple example drawn from the world of Harry Potter. We take one sentence that we know to be true. Imagine if it didn’t rain, then Harry visited Hagrid today. So one fact that we might know about the world. And then we take another fact. Harry visited Hagrid or Dumbledore today, but not both. So it tells us something about the world, that Harry either visited Hagrid but not Dumbledore, or Harry visited Dumbledore but not Hagrid. And now we have a third piece of information about the world that Harry visited Dumbledore today. So we now have three pieces of information now, three facts. Inside of a knowledge base, so to speak, information that we know. And now we, as humans, can try and reason about this and figure out, based on this information, what additional information can we begin to conclude? And well, looking at these last two statements, Harry either visited Hagrid or Dumbledore but not both, and we know that Harry visited Dumbledore today, well, then it’s pretty reasonable that we could draw the conclusion that, you know what, Harry must not have visited Hagrid today. Because based on a combination of these two statements, we can draw this inference, so to speak, a conclusion that Harry did not visit Hagrid today. But it turns out we can even do a little bit better than that, get some more information by taking a look at this first statement and reasoning about that. This first statement says, if it didn’t rain, then Harry visited Hagrid today. So what does that mean? In all cases where it didn’t rain, then we know that Harry visited Hagrid. But if we also know now that Harry did not visit Hagrid, then that tells us something about our initial premise that we were thinking about. In particular, it tells us that it did rain today, because we can reason, if it didn’t rain, that Harry would have visited Hagrid. But we know for a fact that Harry did not visit Hagrid today. So it’s this kind of reason, this sort of logical reasoning, where we use logic based on the information that we know in order to take information and reach conclusions that is going to be the focus of what we’re going to be talking about today. How can we make our artificial intelligence logical so that they can perform the same kinds of deduction, the same kinds of reasoning that we’ve been doing so far? Of course, humans reason about logic generally in terms of human language. That I just now was speaking in English, talking in English about these sentences and trying to reason through how it is that they relate to one another. We’re going to need to be a little bit more formal when we turn our attention to computers and being able to encode this notion of logic and truthhood and falsehood inside of a machine. So we’re going to need to introduce a few more terms and a few symbols that will help us reason through this idea of logic inside of an artificial intelligence. And we’ll begin with the idea of a sentence. Now, a sentence in a natural language like English is just something that I’m saying, like what I’m saying right now. In the context of AI, though, a sentence is just an assertion about the world in what we’re going to call a knowledge representation language, some way of representing knowledge inside of our computers. And the way that we’re going to spend most of today reasoning about knowledge is through a type of logic known as propositional logic. There are a number of different types of logic, some of which we’ll touch on. But propositional logic is based on a logic of propositions, or just statements about the world. And so we begin in propositional logic with a notion of propositional symbols. We will have certain symbols that are oftentimes just letters, something like P or Q or R, where each of those symbols is going to represent some fact or sentence about the world. So P, for example, might represent the fact that it is raining. And so P is going to be a symbol that represents that idea. And Q, for example, might represent Harry visited Hagrid today. Each of these propositional symbols represents some sentence or some fact about the world. But in addition to just having individual facts about the world, we want some way to connect these propositional symbols together in order to reason more complexly about other facts that might exist inside of the world in which we’re reasoning. So in order to do that, we’ll need to introduce some additional symbols that are known as logical connectives. Now, there are a number of these logical connectives. But five of the most important, and the ones we’re going to focus on today, are these five up here, each represented by a logical symbol. Not is represented by this symbol here, and is represented as sort of an upside down V, or is represented by a V shape. Implication, and we’ll talk about what that means in just a moment, is represented by an arrow. And biconditional, again, we’ll talk about what that means in a moment, is represented by these double arrows. But these five logical connectives are the main ones we’re going to be focusing on in terms of thinking about how it is that a computer can reason about facts and draw conclusions based on the facts that it knows. But in order to get there, we need to take a look at each of these logical connectives and build up an understanding for what it is that they actually mean. So let’s go ahead and begin with the not symbol, so this not symbol here. And what we’re going to show for each of these logical connectives is what we’re going to call a truth table, a table that demonstrates what this word not means when we attach it to a propositional symbol or any sentence inside of our logical language. And so the truth table for not is shown right here. If P, some propositional symbol, or some other sentence even, is false, then not P is true. And if P is true, then not P is false. So you can imagine that placing this not symbol in front of some sentence of propositional logic just says the opposite of that. So if, for example, P represented it is raining, then not P would represent the idea that it is not raining. And as you might expect, if P is false, meaning if the sentence, it is raining, is false, well then the sentence not P must be true. The sentence that it is not raining is therefore true. So not, you can imagine, just takes whatever is in P and it inverts it. It turns false into true and true into false, much analogously to what the English word not means, just taking whatever comes after it and inverting it to mean the opposite. Next up, and also very English-like, is this idea of and represented by this upside-down V shape or this point shape. And as opposed to just taking a single argument the way not does, we have P and we have not P. And is going to combine two different sentences in propositional logic together. So I might have one sentence P and another sentence Q, and I want to combine them together to say P and Q. And the general logic for what P and Q means is it means that both of its operands are true. P is true and also Q is true. And so here’s what that truth table looks like. This time we have two variables, P and Q. And when we have two variables, each of which can be in two possible states, true or false, that leads to two squared or four possible combinations of truth and falsehood. So we have P is false and Q is false. We have P is false and Q is true. P is true and Q is false. And then P and Q both are true. And those are the only four possibilities for what P and Q could mean. And in each of those situations, this third column here, P and Q, is telling us a little bit about what it actually means for P and Q to be true. And we see that the only case where P and Q is true is in this fourth row here, where P happens to be true, Q also happens to be true. And in all other situations, P and Q is going to evaluate to false. So this, again, is much in line with what our intuition of and might mean. If I say P and Q, I probably mean that I expect both P and Q to be true. Next up, also potentially consistent with what we mean, is this word or, represented by this V shape, sort of an upside down and symbol. And or, as the name might suggest, is true if either of its arguments are true, as long as P is true or Q is true, then P or Q is going to be true. Which means the only time that P or Q is false is if both of its operands are false. If P is false and Q is false, then P or Q is going to be false. But in all other cases, at least one of the operands is true. Maybe they’re both true, in which case P or Q is going to evaluate to true. Now, this is mostly consistent with the way that most people might use the word or, in the sense of speaking the word or in normal English, though there is sometimes when we might say or, where we mean P or Q, but not both, where we mean, sort of, it can only be one or the other. It’s important to note that this symbol here, this or, means P or Q or both, that those are totally OK. As long as either or both of them are true, then the or is going to evaluate to be true, as well. It’s only in the case where all of the operands are false that P or Q ultimately evaluates to false, as well. In logic, there’s another symbol known as the exclusive or, which encodes this idea of exclusivity of one or the other, but not both. But we’re not going to be focusing on that today. Whenever we talk about or, we’re always talking about either or both, in this case, as represented by this truth table here. So that now is not an and an or. And next up is what we might call implication, as denoted by this arrow symbol. So we have P and Q. And this sentence here will generally read as P implies Q. And what P implies Q means is that if P is true, then Q is also true. So I might say something like, if it is raining, then I will be indoors. Meaning, it is raining implies I will be indoors, as the logical sentence that I’m saying there. And the truth table for this can sometimes be a little bit tricky. So obviously, if P is true and Q is true, then P implies Q. That’s true. That definitely makes sense. And it should also stand to reason that when P is true and Q is false, then P implies Q is false. Because if I said to you, if it is raining, then I will be out indoors. And it is raining, but I’m not indoors? Well, then it would seem to be that my original statement was not true. P implies Q means that if P is true, then Q also needs to be true. And if it’s not, well, then the statement is false. What’s also worth noting, though, is what happens when P is false. When P is false, the implication makes no claim at all. If I say something like, if it is raining, then I will be indoors. And it turns out it’s not raining. Then in that case, I am not making any statement as to whether or not I will be indoors or not. P implies Q just means that if P is true, Q must be true. But if P is not true, then we make no claim about whether or not Q is true at all. So in either case, if P is false, it doesn’t matter what Q is. Whether it’s false or true, we’re not making any claim about Q whatsoever. We can still evaluate the implication to true. The only way that the implication is ever false is if our premise, P, is true, but the conclusion that we’re drawing Q happens to be false. So in that case, we would say P does not imply Q in that case. Finally, the last connective that we’ll discuss is this bi-conditional. You can think of a bi-conditional as a condition that goes in both directions. So originally, when I said something like, if it is raining, then I will be indoors. I didn’t say what would happen if it wasn’t raining. Maybe I’ll be indoors, maybe I’ll be outdoors. This bi-conditional, you can read as an if and only if. So I can say, I will be indoors if and only if it is raining, meaning if it is raining, then I will be indoors. And if I am indoors, it’s reasonable to conclude that it is also raining. So this bi-conditional is only true when P and Q are the same. So if P is true and Q is true, then this bi-conditional is also true. P implies Q, but also the reverse is true. Q also implies P. So if P and Q both happen to be false, we would still say it’s true. But in any of these other two situations, this P if and only if Q is going to ultimately evaluate to false. So a lot of trues and falses going on there, but these five basic logical connectives are going to form the core of the language of propositional logic, the language that we’re going to use in order to describe ideas, and the language that we’re going to use in order to reason about those ideas in order to draw conclusions. So let’s now take a look at some of the additional terms that we’ll need to know about in order to go about trying to form this language of propositional logic and writing AI that’s actually able to understand this sort of logic. The next thing we’re going to need is the notion of what is actually true about the world. We have a whole bunch of propositional symbols, P and Q and R and maybe others, but we need some way of knowing what actually is true in the world. Is P true or false? Is Q true or false? So on and so forth. And to do that, we’ll introduce the notion of a model. A model just assigns a truth value, where a truth value is either true or false, to every propositional symbol. In other words, it’s creating what we might call a possible world. So let me give an example. If, for example, I have two propositional symbols, P is it is raining and Q is it is a Tuesday, a model just takes each of these two symbols and assigns a truth value to them, either true or false. So here’s a sample model. In this model, in other words, in this possible world, it is possible that P is true, meaning it is raining, and Q is false, meaning it is not a Tuesday. But there are other possible worlds or other models as well. There is some model where both of these variables are true, some model where both of these variables are false. In fact, if there are n variables that are propositional symbols like this that are either true or false, then the number of possible models is 2 to the n, because each of these possible models, possible variables within my model, could be set to either true or false if I don’t know any information about it. So now that I have the symbols and the connectives that I’m going to need in order to construct these parts of knowledge, we need some way to represent that knowledge. And to do so, we’re going to allow our AI access to what we’ll call a knowledge base. And a knowledge base is really just a set of sentences that our AI knows to be true. Some set of sentences in propositional logic that are things that our AI knows about the world. And so we might tell our AI some information, information about a situation that it finds itself in, or a situation about a problem that it happens to be trying to solve. And we would give that information to the AI that the AI would store inside of its knowledge base. And what happens next is the AI would like to use that information in the knowledge base to be able to draw conclusions about the rest of the world. And what do those conclusions look like? Well, to understand those conclusions, we’ll need to introduce one more idea, one more symbol. And that is the notion of entailment. So this sentence here, with this double turnstile in these Greek letters, this is the Greek letter alpha and the Greek letter beta. And we read this as alpha entails beta. And alpha and beta here are just sentences in propositional logic. And what this means is that alpha entails beta means that in every model, in other words, in every possible world in which sentence alpha is true, then sentence beta is also true. So if something entails something else, if alpha entails beta, it means that if I know alpha to be true, then beta must therefore also be true. So if my alpha is something like I know that it is a Tuesday in January, then a reasonable beta might be something like I know that it is January. Because in all worlds where it is a Tuesday in January, I know for sure that it must be January, just by definition. This first statement or sentence about the world entails the second statement. And we can reasonably use deduction based on that first sentence to figure out that the second sentence is, in fact, true as well. And ultimately, it’s this idea of entailment that we’re going to try and encode into our computer. We want our AI agent to be able to figure out what the possible entailments are. We want our AI to be able to take these three sentences, sentences like, if it didn’t rain, Harry visited Hagrid. That Harry visited Hagrid or Dumbledore, but not both. And that Harry visited Dumbledore. And just using that information, we’d like our AI to be able to infer or figure out that using these three sentences inside of a knowledge base, we can draw some conclusions. In particular, we can draw the conclusions here that, one, Harry did not visit Hagrid today. And we can draw the entailment, too, that it did, in fact, rain today. And this process is known as inference. And that’s what we’re going to be focusing on today, this process of deriving new sentences from old ones, that I give you these three sentences, you put them in the knowledge base in, say, the AI. And the AI is able to use some sort of inference algorithm to figure out that these two sentences must also be true. And that is how we define inference. So let’s take a look at an inference example to see how we might actually go about inferring things in a human sense before we take a more algorithmic approach to see how we could encode this idea of inference in AI. And we’ll see there are a number of ways that we can actually achieve this. So again, we’ll deal with a couple of propositional symbols. We’ll deal with P, Q, and R. P is it is a Tuesday. Q is it is raining. And R is Harry will go for a run, three propositional symbols that we are just defining to mean this. We’re not saying anything yet about whether they’re true or false. We’re just defining what they are. Now, we’ll give ourselves or an AI access to a knowledge base, abbreviated to KB, the knowledge that we know about the world. We know this statement. All right. So let’s try to parse it. The parentheses here are just used for precedent, so we can see what associates with what. But you would read this as P and not Q implies R. All right. So what does that mean? Let’s put it piece by piece. P is it is a Tuesday. Q is it is raining, so not Q is it is not raining, and implies R is Harry will go for a run. So the way to read this entire sentence in human natural language at least is if it is a Tuesday and it is not raining, then Harry will go for a run. So if it is a Tuesday and it is not raining, then Harry will go for a run. And that is now inside of our knowledge base. And let’s now imagine that our knowledge base has two other pieces of information as well. It has information that P is true, that it is a Tuesday. And we also have the information not Q, that it is not raining, that this sentence Q, it is raining, happens to be false. And those are the three sentences that we have access to. P and not Q implies R, P and not Q. Using that information, we should be able to draw some inferences. P and not Q is only true if both P and not Q are true. All right, we know that P is true and we know that not Q is true. So we know that this whole expression is true. And the definition of implication is if this whole thing on the left is true, then this thing on the right must also be true. So if we know that P and not Q is true, then R must be true as well. So the inference we should be able to draw from all of this is that R is true and we know that Harry will go for a run by taking this knowledge inside of our knowledge base and being able to reason based on that idea. And so this ultimately is the beginning of what we might consider to be some sort of inference algorithm, some process that we can use to try and figure out whether or not we can draw some conclusion. And ultimately, what these inference algorithms are going to answer is the central question about entailment. Given some query about the world, something we’re wondering about the world, and we’ll call that query alpha, the question we want to ask using these inference algorithms is does KB, our knowledge base, entail alpha? In other words, using only the information we know inside of our knowledge base, the knowledge that we have access to, can we conclude that this sentence alpha is true? And that’s ultimately what we would like to do. So how can we do that? How can we go about writing an algorithm that can look at this knowledge base and figure out whether or not this query alpha is actually true? Well, it turns out there are a couple of different algorithms for doing so. And one of the simplest, perhaps, is known as model checking. Now, remember that a model is just some assignment of all of the propositional symbols inside of our language to a truth value, true or false. And you can think of a model as a possible world, that there are many possible worlds where different things might be true or false, and we can enumerate all of them. And the model checking algorithm does exactly that. So what does our model checking algorithm do? Well, if we wanted to determine if our knowledge base entails some query alpha, then we are going to enumerate all possible models. In other words, consider all possible values of true and false for our variables, all possible states in which our world can be in. And if in every model where our knowledge base is true, alpha is also true, then we know that the knowledge base entails alpha. So let’s take a closer look at that sentence and try and figure out what it actually means. If we know that in every model, in other words, in every possible world, no matter what assignment of true and false to variables you give, if we know that whenever our knowledge is true, what we know to be true is true, that this query alpha is also true, well, then it stands to reason that as long as our knowledge base is true, then alpha must also be true. And so this is going to form the foundation of our model checking algorithm. We’re going to enumerate all of the possible worlds and ask ourselves whenever the knowledge base is true, is alpha true? And if that’s the case, then we know alpha to be true. And otherwise, there is no entailment. Our knowledge base does not entail alpha. All right. So this is a little bit abstract, but let’s take a look at an example to try and put real propositional symbols to this idea. So again, we’ll work with the same example. P is it is a Tuesday, Q is it is raining, R as Harry will go for a run. Our knowledge base contains these pieces of information. P and not Q implies R. We also know P. It is a Tuesday and not Q. It is not raining. And our query, our alpha in this case, the thing we want to ask is R. We want to know, is it guaranteed? Is it entailed that Harry will go for a run? So the first step is to enumerate all of the possible models. We have three propositional symbols here, P, Q, and R, which means we have 2 to the third power, or eight possible models. All false, false, false true, false true, false, false true, true, et cetera. Eight possible ways you could assign true and false to all of these models. And we might ask in each one of them, is the knowledge base true? Here are the set of things that we know. In which of these worlds could this knowledge base possibly apply to? In which world is this knowledge base true? Well, in the knowledge base, for example, we know P. We know it is a Tuesday, which means we know that these four first four rows where P is false, none of those are going to be true or are going to work for this particular knowledge base. Our knowledge base is not true in those worlds. Likewise, we also know not Q. We know that it is not raining. So any of these models where Q is true, like these two and these two here, those aren’t going to work either because we know that Q is not true. And finally, we also know that P and not Q implies R, which means that when P is true or P is true here and Q is false, Q is false in these two, then R must be true. And if ever P is true, Q is false, but R is also false, well, that doesn’t satisfy this implication here. That implication does not hold true under those situations. So we could say that for our knowledge base, we can conclude under which of these possible worlds is our knowledge base true and under which of the possible worlds is our knowledge base false. And it turns out there is only one possible world where our knowledge base is actually true. In some cases, there might be multiple possible worlds where the knowledge base is true. But in this case, it just so happens that there’s only one, one possible world where we can definitively say something about our knowledge base. And in this case, we would look at the query. The query of R is R true, R is true, and so as a result, we can draw that conclusion. And so this is this idea of model check-in. Enumerate all the possible models and look in those possible models to see whether or not, if our knowledge base is true, is the query in question true as well. So let’s now take a look at how we might actually go about writing this in a programming language like Python. Take a look at some actual code that would encode this notion of propositional symbols and logic and these connectives like and and or and not and implication and so forth and see what that code might actually look like. So I’ve written in advance a logic library that’s more detailed than we need to worry about entirely today. But the important thing is that we have one class for every type of logical symbol or connective that we might have. So we just have one class for logical symbols, for example, where every symbol is going to represent and store some name for that particular symbol. And we also have a class for not that takes an operand. So we might say not one symbol to say something is not true or some other sentence is not true. We have one for and, one for or, so on and so forth. And I’ll just demonstrate how this works. And you can take a look at the actual logic.py later on. But I’ll go ahead and call this file harry.py. We’re going to store information about this world of Harry Potter, for example. So I’ll go ahead and import from my logic module. I’ll import everything. And in this library, in order to create a symbol, you use capital S symbol. And I’ll create a symbol for rain, to mean it is raining, for example. And I’ll create a symbol for Hagrid, to mean Harry visited Hagrid, is what this symbol is going to mean. So this symbol means it is raining. This symbol means Harry visited Hagrid. And I’ll add another symbol called Dumbledore for Harry visited Dumbledore. Now, I’d like to save these symbols so that I can use them later as I do some logical analysis. So I’ll go ahead and save each one of them inside of a variable. So like rain, Hagrid, and Dumbledore, so you could call the variables anything. And now that I have these logical symbols, I can use logical connectives to combine them together. So for example, if I have a sentence like and rain and Hagrid, for example, which is not necessarily true, but just for demonstration, I can now try and print out sentence.formula, which is a function I wrote that takes a sentence in propositional logic and just prints it out so that we, the programmers, can now see this in order to get an understanding for how it actually works. So if I run python harry.py, what we’ll see is this sentence in propositional logic, rain and Hagrid. This is the logical representation of what we have here in our Python program of saying and whose arguments are rain and Hagrid. So we’re saying rain and Hagrid by encoding that idea. And this is quite common in Python object-oriented programming, where you have a number of different classes, and you pass arguments into them in order to create a new and object, for example, in order to represent this idea. But now what I’d like to do is somehow encode the knowledge that I have about the world in order to solve that problem from the beginning of class, where we talked about trying to figure out who Harry visited and trying to figure out if it’s raining or if it’s not raining. And so what knowledge do I have? I’ll go ahead and create a new variable called knowledge. And what do I know? Well, I know the very first sentence that we talked about was the idea that if it is not raining, then Harry will visit Hagrid. So all right, how do I encode the idea that it is not raining? Well, I can use not and then the rain symbol. So here’s me saying that it is not raining. And now the implication is that if it is not raining, then Harry visited Hagrid. So I’ll wrap this inside of an implication to say, if it is not raining, this first argument to the implication will then Harry visited Hagrid. So I’m saying implication, the premise is that it’s not raining. And if it is not raining, then Harry visited Hagrid. And I can print out knowledge.formula to see the logical formula equivalent of that same idea. So I run Python of harry.py. And this is the logical formula that we see as a result, which is a text-based version of what we were looking at before, that if it is not raining, then that implies that Harry visited Hagrid. But there was additional information that we had access to as well. In this case, we had access to the fact that Harry visited either Hagrid or Dumbledore. So how do I encode that? Well, this means that in my knowledge, I’ve really got multiple pieces of knowledge going on. I know one thing and another thing and another thing. So I’ll go ahead and wrap all of my knowledge inside of an and. And I’ll move things on to new lines just for good measure. But I know multiple things. So I’m saying knowledge is an and of multiple different sentences. I know multiple different sentences to be true. One such sentence that I know to be true is this implication, that if it is not raining, then Harry visited Hagrid. Another such sentence that I know to be true is or Hagrid Dumbledore. In other words, Hagrid or Dumbledore is true, because I know that Harry visited Hagrid or Dumbledore. But I know more than that, actually. That initial sentence from before said that Harry visited Hagrid or Dumbledore, but not both. So now I want a sentence that will encode the idea that Harry didn’t visit both Hagrid and Dumbledore. Well, the notion of Harry visiting Hagrid and Dumbledore would be represented like this, and of Hagrid and Dumbledore. And if that is not true, if I want to say not that, then I’ll just wrap this whole thing inside of a not. So now these three lines, line 8 says that if it is not raining, then Harry visited Hagrid. Line 9 says Harry visited Hagrid or Dumbledore. And line 10 says Harry didn’t visit both Hagrid and Dumbledore, that it is not true that both the Hagrid symbol and the Dumbledore symbol are true. Only one of them can be true. And finally, the last piece of information that I knew was the fact that Harry visited Dumbledore. So these now are the pieces of knowledge that I know, one sentence and another sentence and another and another. And I can print out what I know just to see it a little bit more visually. And here now is a logical representation of the information that my computer is now internally representing using these various different Python objects. And again, take a look at logic.py if you want to take a look at how exactly it’s implementing this, but no need to worry too much about all of the details there. We’re here saying that if it is not raining, then Harry visited Hagrid. We’re saying that Hagrid or Dumbledore is true. And we’re saying it is not the case that Hagrid and Dumbledore is true, that they’re not both true. And we also know that Dumbledore is true. So this long logical sentence represents our knowledge base. It is the thing that we know. And now what we’d like to do is we’d like to use model checking to ask a query, to ask a question like, based on this information, do I know whether or not it’s raining? And we as humans were able to logic our way through it and figure out that, all right, based on these sentences, we can conclude this and that to figure out that, yes, it must have been raining. But now we’d like for the computer to do that as well. So let’s take a look at the model checking algorithm that is going to follow that same pattern that we drew out in pseudocode a moment ago. So I’ve defined a function here in logic.py that you can take a look at called model check. Model check takes two arguments, the knowledge that I already know, and the query. And the idea is, in order to do model checking, I need to enumerate all of the possible models. And for each of the possible models, I need to ask myself, is the knowledge base true? And is the query true? So the first thing I need to do is somehow enumerate all of the possible models, meaning for all possible symbols that exist, I need to assign true and false to each one of them and see whether or not it’s still true. And so here is the way we’re going to do that. We’re going to start. So I’ve defined another helper function internally that we’ll get to in just a moment. But this function starts by getting all of the symbols in both the knowledge and the query, by figuring out what symbols am I dealing with. In this case, the symbols I’m dealing with are rain and Hagrid and Dumbledore, but there might be other symbols depending on the problem. And we’ll take a look soon at some examples of situations where ultimately we’re going to need some additional symbols in order to represent the problem. And then we’re going to run this check all function, which is a helper function that’s basically going to recursively call itself checking every possible configuration of propositional symbols. So we start out by looking at this check all function. And what do we do? So if not symbols means if we finish assigning all of the symbols. We’ve assigned every symbol a value. So far we haven’t done that, but if we ever do, then we check. In this model, is the knowledge true? That’s what this line is saying. If we evaluate the knowledge propositional logic formula using the model’s assignment of truth values, is the knowledge true? If the knowledge is true, then we should return true only if the query is true. Because if the knowledge is true, we want the query to be true as well in order for there to be entailment. Otherwise, we don’t know that there otherwise there won’t be an entailment if there’s ever a situation where what we know in our knowledge is true, but the query, the thing we’re asking, happens to be false. So this line here is checking that same idea that in all worlds where the knowledge is true, the query must also be true. Otherwise, we can just return true because if the knowledge isn’t true, then we don’t care. This is equivalent to when we were enumerating this table from a moment ago. In all situations where the knowledge base wasn’t true, all of these seven rows here, we didn’t care whether or not our query was true or not. We only care to check whether the query is true when the knowledge base is actually true, which was just this green highlighted row right there. So that logic is encoded using that statement there. And otherwise, if we haven’t assigned symbols yet, which we haven’t seen anything yet, then the first thing we do is pop one of the symbols. I make a copy of the symbols first just to save an existing copy. But I pop one symbol off of the remaining symbols so that I just pick one symbol at random. And I create one copy of the model where that symbol is true. And I create a second copy of the model where that symbol is false. So I now have two copies of the model, one where the symbol is true and one where the symbol is false. And I need to make sure that this entailment holds in both of those models. So I recursively check all on the model where the statement is true and check all on the model where the statement is false. So again, you can take a look at that function to try to get a sense for how exactly this logic is working. But in effect, what it’s doing is recursively calling this check all function again and again and again. And on every level of the recursion, we’re saying let’s pick a new symbol that we haven’t yet assigned, assign it to true and assign it to false, and then check to make sure that the entailment holds in both cases. Because ultimately, I need to check every possible world. I need to take every combination of symbols and try every combination of true and false in order to figure out whether the entailment relation actually holds. So that function we’ve written for you. But in order to use that function inside of harry.py, what I’ll write is something like this. I would like to model check based on the knowledge. And then I provide as a second argument what the query is, what the thing I want to ask is. And what I want to ask in this case is, is it raining? So model check again takes two arguments. The first argument is the information that I know, this knowledge, which in this case is this information that was given to me at the beginning. And the second argument, rain, is encoding the idea of the query. What am I asking? I would like to ask, based on this knowledge, do I know for sure that it is raining? And I can try and print out the result of that. And when I run this program, I see that the answer is true. That based on this information, I can conclusively say that it is raining, because using this model checking algorithm, we were able to check that in every world where this knowledge is true, it is raining. In other words, there is no world where this knowledge is true, and it is not raining. So you can conclude that it is, in fact, raining. And this sort of logic can be applied to a number of different types of problems, that if confronted with a problem where some sort of logical deduction can be used in order to try to solve it, you might try thinking about what propositional symbols you might need in order to represent that information, and what statements and propositional logic you might use in order to encode that information which you know. And this process of trying to take a problem and figure out what propositional symbols to use in order to encode that idea, or how to represent it logically, is known as knowledge engineering. That software engineers and AI engineers will take a problem and try and figure out how to distill it down into knowledge that is representable by a computer. And if we can take any general purpose problem, some problem that we find in the human world, and turn it into a problem that computers know how to solve as by using any number of different variables, well, then we can take a computer that is able to do something like model checking or some other inference algorithm and actually figure out how to solve that problem. So now we’ll take a look at two or three examples of knowledge engineering and practice, of taking some problem and figuring out how we can apply logical symbols and use logical formulas to be able to encode that idea. And we’ll start with a very popular board game in the US and the UK known as Clue. Now, in the game of Clue, there’s a number of different factors that are going on. But the basic premise of the game, if you’ve never played it before, is that there are a number of different people. For now, we’ll just use three, Colonel Mustard, Professor Plumb, and Miss Scarlet. There are a number of different rooms, like a ballroom, a kitchen, and a library. And there are a number of different weapons, a knife, a revolver, and a wrench. And three of these, one person, one room, and one weapon, is the solution to the mystery, the murderer and what room they were in and what weapon they happened to use. And what happens at the beginning of the game is that all these cards are randomly shuffled together. And three of them, one person, one room, and one weapon, are placed into a sealed envelope that we don’t know. And we would like to figure out, using some sort of logical process, what’s inside the envelope, which person, which room, and which weapon. And we do so by looking at some, but not all, of these cards here, by looking at these cards to try and figure out what might be going on. And so this is a very popular game. But let’s now try and formalize it and see if we could train a computer to be able to play this game by reasoning through it logically. So in order to do this, we’ll begin by thinking about what propositional symbols we’re ultimately going to need. Remember, again, that propositional symbols are just some symbol, some variable, that can be either true or false in the world. And so in this case, the propositional symbols are really just going to correspond to each of the possible things that could be inside the envelope. Mustard is a propositional symbol that, in this case, will just be true if Colonel Mustard is inside the envelope, if he is the murderer, and false otherwise. And likewise for Plum, for Professor Plum, and Scarlet, for Miss Scarlet. And likewise for each of the rooms and for each of the weapons. We have one propositional symbol for each of these ideas. Then using those propositional symbols, we can begin to create logical sentences, create knowledge that we know about the world. So for example, we know that someone is the murderer, that one of the three people is, in fact, the murderer. And how would we encode that? Well, we don’t know for sure who the murderer is. But we know it is one person or the second person or the third person. So I could say something like this. Mustard or Plum or Scarlet. And this piece of knowledge encodes that one of these three people is the murderer. We don’t know which, but one of these three things must be true. What other information do we know? Well, we know that, for example, one of the rooms must have been the room in the envelope. The crime was committed either in the ballroom or the kitchen or the library. Again, right now, we don’t know which. But this is knowledge we know at the outset, knowledge that one of these three must be inside the envelope. And likewise, we can say the same thing about the weapon, that it was either the knife or the revolver or the wrench, that one of those weapons must have been the weapon of choice and therefore the weapon in the envelope. And then as the game progresses, the gameplay works by people get various different cards. And using those cards, you can deduce information. That if someone gives you a card, for example, I have the Professor Plum card in my hand, then I know the Professor Plum card can’t be inside the envelope. I know that Professor Plum is not the criminal, so I know a piece of information like not Plum, for example. I know that Professor Plum has to be false. This propositional symbol is not true. And sometimes I might not know for sure that a particular card is not in the middle, but sometimes someone will make a guess and I’ll know that one of three possibilities is not true. Someone will guess Colonel Mustard in the library with the revolver or something to that effect. And in that case, a card might be revealed that I don’t see. But if it is a card and it is either Colonel Mustard or the revolver or the library, then I know that at least one of them can’t be in the middle. So I know something like it is either not Mustard or it is not the library or it is not the revolver. Now maybe multiple of these are not true, but I know that at least one of Mustard, Library, and Revolver must, in fact, be false. And so this now is a propositional logic representation of this game of Clue, a way of encoding the knowledge that we know inside this game using propositional logic that a computer algorithm, something like model checking that we saw a moment ago, can actually look at and understand. So let’s now take a look at some code to see how this algorithm might actually work in practice. All right, so I’m now going to open up a file called Clue.py, which I’ve started already. And what we’ll see here is I’ve defined a couple of things. To find some symbols initially, notice I have a symbol for Colonel Mustard, a symbol for Professor Plum, a symbol for Miss Scarlett, all of which I’ve put inside of this list of characters. I have a symbol for Ballroom and Kitchen and Library inside of a list of rooms. And then I have symbols for Knife and Revolver and Wrench. These are my weapons. And so all of these characters and rooms and weapons altogether, those are my symbols. And now I also have this check knowledge function. And what the check knowledge function does is it takes my knowledge and it’s going to try and draw conclusions about what I know. So for example, we’ll loop over all of the possible symbols and we’ll check, do I know that that symbol is true? And a symbol is going to be something like Professor Plum or the Knife or the Library. And if I know that it is true, in other words, I know that it must be the card in the envelope, then I’m going to print out using a function called cprint, which prints things in color. I’m going to print out the word yes, and I’m going to print that in green, just to make it very clear to us. If we’re not sure that the symbol is true, maybe I can check to see if I’m sure that the symbol is not true. Like if I know for sure that it is not Professor Plum, for example. And I do that by running model check again, this time checking if my knowledge is not the symbol, if I know for sure that the symbol is not true. And if I don’t know for sure that the symbol is not true, because I say if not model check, meaning I’m not sure that the symbol is false, well, then I’ll go ahead and print out maybe next to the symbol. Because maybe the symbol is true, maybe it’s not, I don’t actually know. So what knowledge do I actually have? Well, let’s try and represent my knowledge now. So my knowledge is, I know a couple of things, so I’ll put them in an and. And I know that one of the three people must be the criminal. So I know or mustard, plum, scarlet. This is my way of encoding that it is either Colonel Mustard or Professor Plum or Miss Scarlet. I know that it must have happened in one of the rooms. So I know or ballroom, kitchen, library, for example. And I know that one of the weapons must have been used as well. So I know or knife, revolver, wrench. So that might be my initial knowledge, that I know that it must have been one of the people, I know it must have been in one of the rooms, and I know that it must have been one of the weapons. And I can see what that knowledge looks like as a formula by printing out knowledge.formula. So I’ll run python clue.py. And here now is the information that I know in logical format. I know that it is Colonel Mustard or Professor Plum or Miss Scarlet. And I know that it is the ballroom, the kitchen, or the library. And I know that it is the knife, the revolver, or the wrench. But I don’t know much more than that. I can’t really draw any firm conclusions. And in fact, we can see that if I try and do, let me go ahead and run my knowledge check function on my knowledge. Knowledge check is this function that I, or check knowledge rather, is this function that I just wrote that looks over all of the symbols and tries to see what conclusions I can actually draw about any of the symbols. So I’ll go ahead and run clue.py and see what it is that I know. And it seems that I don’t really know anything for sure. I have all three people are maybes, all three of the rooms are maybes, all three of the weapons are maybes. I don’t really know anything for certain just yet. But now let me try and add some additional information and see if additional information, additional knowledge, can help us to logically reason our way through this process. And we are just going to provide the information. Our AI is going to take care of doing the inference and figuring out what conclusions it’s able to draw. So I start with some cards. And those cards tell me something. So if I have the kernel mustard card, for example, I know that the mustard symbol must be false. In other words, mustard is not the one in the envelope, is not the criminal. So I can say, knowledge supports something called, every and in this library supports dot add, which is a way of adding knowledge or adding an additional logical sentence to an and clause. So I can say, knowledge dot add, not mustard. I happen to know, because I have the mustard card, that kernel mustard is not the suspect. And maybe I have a couple of other cards too. Maybe I also have a card for the kitchen. So I know it’s not the kitchen. And maybe I have another card that says that it is not the revolver. So I have three cards, kernel mustard, the kitchen, and the revolver. And I encode that into my AI this way by saying, it’s not kernel mustard, it’s not the kitchen, and it’s not the revolver. And I know those to be true. So now, when I rerun clue.py, we’ll see that I’ve been able to eliminate some possibilities. Before, I wasn’t sure if it was the knife or the revolver or the wrench. If a knife was maybe, a revolver was maybe, wrench is maybe. Now I’m down to just the knife and the wrench. Between those two, I don’t know which one it is. They’re both maybes. But I’ve been able to eliminate the revolver, which is one that I know to be false, because I have the revolver card. And so additional information might be acquired over the course of this game. And we would represent that just by adding knowledge to our knowledge set or knowledge base that we’ve been building here. So if, for example, we additionally got the information that someone made a guess, someone guessed like Miss Scarlet in the library with the wrench. And we know that a card was revealed, which means that one of those three cards, either Miss Scarlet or the library or the wrench, one of those at minimum must not be inside of the envelope. So I could add some knowledge, say knowledge.add. And I’m going to add an or clause, because I don’t know for sure which one it’s not, but I know one of them is not in the envelope. So it’s either not Scarlet, or it’s not the library, and or supports multiple arguments. I can say it’s also or not the wrench. So at least one of those needs a Scarlet library and wrench. At least one of those needs to be false. I don’t know which, though. Maybe it’s multiple. Maybe it’s just one, but at least one I know needs to hold. And so now if I rerun clue.py, I don’t actually have any additional information just yet. Nothing I can say conclusively. I still know that maybe it’s Professor Plum, maybe it’s Miss Scarlet. I haven’t eliminated any options. But let’s imagine that I get some more information, that someone shows me the Professor Plum card, for example. So I say, all right, let’s go back here, knowledge.add, not Plum. So I have the Professor Plum card. I know the Professor Plum is not in the middle. I rerun clue.py. And right now, I’m able to draw some conclusions. Now I’ve been able to eliminate Professor Plum, and the only person it could left remaining be is Miss Scarlet. So I know, yes, Miss Scarlet, this variable must be true. And I’ve been able to infer that based on the information I already had. Now between the ballroom and the library and the knife and the wrench, for those two, I’m still not sure. So let’s add one more piece of information. Let’s say that I know that it’s not the ballroom. Someone has shown me the ballroom card, so I know it’s not the ballroom. Which means at this point, I should be able to conclude that it’s the library. Let’s see. I’ll say knowledge.add, not the ballroom. And we’ll go ahead and run that. And it turns out that after all of this, not only can I conclude that I know that it’s the library, but I also know that the weapon was the knife. And that might have been an inference that was a little bit trickier, something I wouldn’t have realized immediately, but the AI, via this model checking algorithm, is able to draw that conclusion, that we know for sure that it must be Miss Scarlet in the library with the knife. And how did we know that? Well, we know it from this or clause up here, that we know that it’s either not Scarlet, or it’s not the library, or it’s not the wrench. And given that we know that it is Miss Scarlet, and we know that it is the library, then the only remaining option for the weapon is that it is not the wrench, which means that it must be the knife. So we as humans now can go back and reason through that, even though it might not have been immediately clear. And that’s one of the advantages of using an AI or some sort of algorithm in order to do this, is that the computer can exhaust all of these possibilities and try and figure out what the solution actually should be. And so for that reason, it’s often helpful to be able to represent knowledge in this way. Knowledge engineering, some situation where we can use a computer to be able to represent knowledge and draw conclusions based on that knowledge. And any time we can translate something into propositional logic symbols like this, this type of approach can be useful. So you might be familiar with logic puzzles, where you have to puzzle your way through trying to figure something out. This is what a classic logic puzzle might look like. Something like Gilderoy, Minerva, Pomona, and Horace each belong to a different one of the four houses, Gryffindor, Hufflepuff, Ravenclaw, and Slytherin. And then we have some information. The Gilderoy belongs to Gryffindor or Ravenclaw, Pomona does not belong in Slytherin, and Minerva does belong to Gryffindor. So we have a couple pieces of information. And using that information, we need to be able to draw some conclusions about which person should be assigned to which house. And again, we can use the exact same idea to try and implement this notion. So we need some propositional symbols. And in this case, the propositional symbols are going to get a little more complex, although we’ll see ways to make this a little bit cleaner later on. But we’ll need 16 propositional symbols, one for each person and house. So we need to say, remember, every propositional symbol is either true or false. So Gilderoy Gryffindor is either true or false. Either he’s in Gryffindor or he is not. Likewise, Gilderoy Hufflepuff also true or false. Either it is true or it’s false. And that’s true for every combination of person and house that we could come up with. We have some sort of propositional symbol for each one of those. Using this type of knowledge, we can then begin to think about what types of logical sentences we can say about the puzzle. That if we know what will before even think about the information we were given, we can think about the premise of the problem, that every person is assigned to a different house. So what does that tell us? Well, it tells us sentences like this. It tells us like Pomona Slytherin implies not Pomona Hufflepuff. Something like if Pomona is in Slytherin, then we know that Pomona is not in Hufflepuff. And we know this for all four people and for all combinations of houses, that no matter what person you pick, if they’re in one house, then they’re not in some other house. So I’ll probably have a whole bunch of knowledge statements that are of this form, that if we know Pomona is in Slytherin, then we know Pomona is not in Hufflepuff. We were also given the information that each person is in a different house. So I also have pieces of knowledge that look something like this. Minerva Ravenclaw implies not Gilderoy Ravenclaw. If they’re all in different houses, then if Minerva is in Ravenclaw, then we know the Gilderoy is not in Ravenclaw as well. And I have a whole bunch of similar sentences like this that are expressing that idea for other people and other houses as well. And so in addition to sentences of these form, I also have the knowledge that was given to me. Information like Gilderoy was in Gryffindor or in Ravenclaw that would be represented like this, Gilderoy Gryffindor or Gilderoy Ravenclaw. And then using these sorts of sentences, I can begin to draw some conclusions about the world. So let’s see an example of this. We’ll go ahead and actually try and implement this logic puzzle to see if we can figure out what the answer is. I’ll go ahead and open up puzzle.py, where I’ve already started to implement this sort of idea. I’ve defined a list of people and a list of houses. And I’ve so far created one symbol for every person and for every house. That’s what this double four loop is doing, looping over all people, looping over all houses, creating a new symbol for each of them. And then I’ve added some information. I know that every person belongs to a house, so I’ve added the information for every person that person Gryffindor or person Hufflepuff or person Ravenclaw or person Slytherin, that one of those four things must be true. Every person belongs to a house. What other information do I know? I also know that only one house per person, so no person belongs to multiple houses. So how does this work? Well, this is going to be true for all people. So I’ll loop over every person. And then I need to loop over all different pairs of houses. The idea is I want to encode the idea that if Minerva is in Gryffindor, then Minerva can’t be in Ravenclaw. So I’ll loop over all houses, each one. And I’ll loop over all houses again, h2. And as long as they’re different, h1 not equal to h2, then I’ll add to my knowledge base this piece of information. That implication, in other words, an if then, if the person is in h1, then I know that they are not in house h2. So these lines here are encoding the notion that for every person, if they belong to house one, then they are not in house two. And the other piece of logic we need to encode is the idea that every house can only have one person. In other words, if Pomona is in Hufflepuff, then nobody else is allowed to be in Hufflepuff either. And that’s the same logic, but sort of backwards. I loop over all of the houses and loop over all different pairs of people. So I loop over people once, loop over people again, and only do this when the people are different, p1 not equal to p2. And I add the knowledge that if, as given by the implication, if person one belongs to the house, then it is not the case that person two belongs to the same house. So here I’m just encoding the knowledge that represents the problem’s constraints. I know that everyone’s in a different house. I know that any person can only belong to one house. And I can now take my knowledge and try and print out the information that I happen to know. So I’ll go ahead and print out knowledge.formula, just to see this in action, and I’ll go ahead and skip this for now. But we’ll come back to this in a second. Let’s print out the knowledge that I know by running Python puzzle.py. It’s a lot of information, a lot that I have to scroll through, because there are 16 different variables all going on. But the basic idea, if we scroll up to the very top, is I see my initial information. Gilderoy is either in Gryffindor, or Gilderoy is in Hufflepuff, or Gilderoy is in Ravenclaw, or Gilderoy is in Slytherin, and then way more information as well. So this is quite messy, more than we really want to be looking at. And soon, too, we’ll see ways of representing this a little bit more nicely using logic. But for now, we can just say these are the variables that we’re dealing with. And now we’d like to add some information. So the information we’re going to add is Gilderoy is in Gryffindor, or he is in Ravenclaw. So that knowledge was given to us. So I’ll go ahead and say knowledge.add. And I know that either or Gilderoy Gryffindor or Gilderoy Ravenclaw. One of those two things must be true. I also know that Pomona was not in Slytherin, so I can say knowledge.add not this symbol, not the Pomona-Slytherin symbol. And then I can add the knowledge that Minerva is in Gryffindor by adding the symbol Minerva Gryffindor. So those are the pieces of knowledge that I know. And this loop here at the bottom just loops over all of my symbols, checks to see if the knowledge entails that symbol by calling this model check function again. And if it does, if we know the symbol is true, we print out the symbol. So now I can run Python, puzzle.py, and Python is going to solve this puzzle for me. We’re able to conclude that Gilderoy belongs to Ravenclaw, Pomona belongs to Hufflepuff, Minerva to Gryffindor, and Horace to Slytherin just by encoding this knowledge inside the computer, although it was quite tedious to do in this case. And as a result, we were able to get the conclusion from that as well. And you can imagine this being applied to many sorts of different deductive situations. So not only these situations where we’re trying to deal with Harry Potter characters in this puzzle, but if you’ve ever played games like Mastermind, where you’re trying to figure out which order different colors go in and trying to make predictions about it, I could tell you, for example, let’s play a simplified version of Mastermind where there are four colors, red, blue, green, and yellow, and they’re in some order, but I’m not telling you what order. You just have to make a guess, and I’ll tell you of red, blue, green, and yellow how many of the four you got in the right position. So a simplified version of this game, you might make a guess like red, blue, green, yellow, and I would tell you something like two of those four are in the correct position, but the other two are not. And then you could reasonably make a guess and say, all right, look at this, blue, red, green, yellow. Try switching two of them around, and this time maybe I tell you, you know what, none of those are in the correct position. And the question then is, all right, what is the correct order of these four colors? And we as humans could begin to reason this through. All right, well, if none of these were correct, but two of these were correct, well, it must have been because I switched the red and the blue, which means red and blue here must be correct, which means green and yellow are probably not correct. You can begin to do this sort of deductive reasoning. And we can also equivalently try and take this and encode it inside of our computer as well. And it’s going to be very similar to the logic puzzle that we just did a moment ago. So I won’t spend too much time on this code because it is fairly similar. But again, we have a whole bunch of colors and four different positions in which those colors can be. And then we have some additional knowledge. And I encode all of that knowledge. And you can take a look at this code on your own time. But I just want to demonstrate that when we run this code, run python mastermind.py and run and see what we get, we ultimately are able to compute red 0 in the 0 position, blue in the 1 position, yellow in the 2 position, and green in the 3 position as the ordering of those symbols. Now, ultimately, what you might have noticed is this process was taking quite a long time. And in fact, model checking is not a particularly efficient algorithm, right? What I need to do in order to model check is take all of my possible different variables and enumerate all of the possibilities that they could be in. If I have n variables, I have 2 to the n possible worlds that I need to be looking through in order to perform this model checking algorithm. And this is probably not tractable, especially as we start to get to much larger and larger sets of data where you have many, many more variables that are at play. Right here, we only have a relatively small number of variables. So this sort of approach can actually work. But as the number of variables increases, model checking becomes less and less good of a way of trying to solve these sorts of problems. So while it might have been OK for something like Mastermind to conclude that this is indeed the correct sequence where all four are in the correct position, what we’d like to do is come up with some better ways to be able to make inferences rather than just enumerate all of the possibilities. And to do so, what we’ll transition to next is the idea of inference rules, some sort of rules that we can apply to take knowledge that already exists and translate it into new forms of knowledge. And the general way we’ll structure an inference rule is by having a horizontal line here. Anything above the line is going to represent a premise, something that we know to be true. And then anything below the line will be the conclusion that we can arrive at after we apply the logic from the inference rule that we’re going to demonstrate. So we’ll do some of these inference rules by demonstrating them in English first, but then translating them into the world of propositional logic so you can see what those inference rules actually look like. So for example, let’s imagine that I have access to two pieces of information. I know, for example, that if it is raining, then Harry is inside, for example. And let’s say I also know it is raining. Then most of us could reasonably then look at this information and conclude that, all right, Harry must be inside. This inference rule is known as modus ponens, and it’s phrased more formally in logic as this. If we know that alpha implies beta, in other words, if alpha, then beta, and we also know that alpha is true, then we should be able to conclude that beta is also true. We can apply this inference rule to take these two pieces of information and generate this new piece of information. Notice that this is a totally different approach from the model checking approach, where the approach was look at all of the possible worlds and see what’s true in each of these worlds. Here, we’re not dealing with any specific world. We’re just dealing with the knowledge that we know and what conclusions we can arrive at based on that knowledge. That I know that A implies B, and I know A, and the conclusion is B. And this should seem like a relatively obvious rule. But of course, if alpha, then beta, and we know alpha, then we should be able to conclude that beta is also true. And that’s going to be true for many, but maybe even all of the inference rules that we’ll take a look at. You should be able to look at them and say, yeah, of course that’s going to be true. But it’s putting these all together, figuring out the right combination of inference rules that can be applied that ultimately is going to allow us to generate interesting knowledge inside of our AI. So that’s modus ponensis application of implication, that if we know alpha and we know that alpha implies beta, then we can conclude beta. Let’s take a look at another example. Fairly straightforward, something like Harry is friends with Ron and Hermione. Based on that information, we can reasonably conclude Harry is friends with Hermione. That must also be true. And this inference rule is known as and elimination. And what and elimination says is that if we have a situation where alpha and beta are both true, I have information alpha and beta, well then, just alpha is true. Or likewise, just beta is true. That if I know that both parts are true, then one of those parts must also be true. Again, something obvious from the point of view of human intuition, but a computer needs to be told this kind of information. To be able to apply the inference rule, we need to tell the computer that this is an inference rule that you can apply, so the computer has access to it and is able to use it in order to translate information from one form to another. In addition to that, let’s take a look at another example of an inference rule, something like it is not true that Harry did not pass the test. Bit of a tricky sentence to parse. I’ll read it again. It is not true, or it is false, that Harry did not pass the test. Well, if it is false that Harry did not pass the test, then the only reasonable conclusion is that Harry did pass the test. And so this, instead of being and elimination, is what we call double negation elimination. That if we have two negatives inside of our premise, then we can just remove them altogether. They cancel each other out. One turns true to false, and the other one turns false back into true. Phrased a little bit more formally, we say that if the premise is not alpha, then the conclusion we can draw is just alpha. We can say that alpha is true. We’ll take a look at a couple more of these. If I have it is raining, then Harry is inside. How do I reframe this? Well, this one is a little bit trickier. But if I know if it is raining, then Harry is inside, then I conclude one of two things must be true. Either it is not raining, or Harry is inside. Now, this one’s trickier. So let’s think about it a little bit. This first premise here, if it is raining, then Harry is inside, is saying that if I know that it is raining, then Harry must be inside. So what is the other possible case? Well, if Harry is not inside, then I know that it must not be raining. So one of those two situations must be true. Either it’s not raining, or it is raining, in which case Harry is inside. So the conclusion I can draw is either it is not raining, or it is raining, so therefore, Harry is inside. And so this is a way to translate if-then statements into or statements. And this is known as implication elimination. And this is similar to what we actually did in the beginning when we were first looking at those very first sentences about Harry and Hagrid and Dumbledore. And phrased a little bit more formally, this says that if I have the implication, alpha implies beta, that I can draw the conclusion that either not alpha or beta, because there are only two possibilities. Either alpha is true or alpha is not true. So one of those possibilities is alpha is not true. But if alpha is true, well, then we can draw the conclusion that beta must be true. So either alpha is not true or alpha is true, in which case beta is also true. So this is one way to turn an implication into just a statement about or. In addition to eliminating implications, we can also eliminate biconditionals as well. So let’s take an English example, something like, it is raining if and only if Harry is inside. And this if and only if really sounds like that biconditional, that double arrow sign that we saw in propositional logic not too long ago. And what does this actually mean if we were to translate this? Well, this means that if it is raining, then Harry is inside. And if Harry is inside, then it is raining, that this implication goes both ways. And this is what we would call biconditional elimination, that I can take a biconditional, a if and only if b, and translate that into something like this, a implies b, and b implies a. So many of these inference rules are taking logic that uses certain symbols and turning them into different symbols, taking an implication and turning it into an or, or taking a biconditional and turning it into implication. And another example of it would be something like this. It is not true that both Harry and Ron passed the test. Well, all right, how do we translate that? What does that mean? Well, if it is not true that both of them passed the test, well, then the reasonable conclusion we might draw is that at least one of them didn’t pass the test. So the conclusion is either Harry did not pass the test or Ron did not pass the test, or both. This is not an exclusive or. But if it is true that it is not true that both Harry and Ron passed the test, well, then either Harry didn’t pass the test or Ron didn’t pass the test. And this type of law is one of De Morgan’s laws. Quite famous in logic where the idea is that we can turn an and into an or. We can say we can take this and that both Harry and Ron passed the test and turn it into an or by moving the nots around. So if it is not true that Harry and Ron passed the test, well, then either Harry did not pass the test or Ron did not pass the test either. And the way we frame that more formally using logic is to say this. If it is not true that alpha and beta, well, then either not alpha or not beta. The way I like to think about this is that if you have a negation in front of an and expression, you move the negation inwards, so to speak, moving the negation into each of these individual sentences and then flip the and into an or. So the negation moves inwards and the and flips into an or. So I go from not a and b to not a or not b. And there’s actually a reverse of De Morgan’s law that goes in the other direction for something like this. If I say it is not true that Harry or Ron passed the test, meaning neither of them passed the test, well, then the conclusion I can draw is that Harry did not pass the test and Ron did not pass the test. So in this case, instead of turning an and into an or, we’re turning an or into an and. But the idea is the same. And this, again, is another example of De Morgan’s laws. And the way that works is that if I have not a or b this time, the same logic is going to apply. I’m going to move the negation inwards. And I’m going to flip this time, flip the or into an and. So if not a or b, meaning it is not true that a or b or alpha or beta, then I can say not alpha and not beta, moving the negation inwards in order to make that conclusion. So those are De Morgan’s laws and a couple other inference rules that are worth just taking a look at. One is the distributive law that works this way. So if I have alpha and beta or gamma, well, then much in the same way that you can use in math, use distributive laws to distribute operands like addition and multiplication, I can do a similar thing here, where I can say if alpha and beta or gamma, then I can say something like alpha and beta or alpha and gamma, that I’ve been able to distribute this and sign throughout this expression. So this is an example of the distributive property or the distributive law as applied to logic in much the same way that you would distribute a multiplication over the addition of something, for example. This works the other way too. So if, for example, I have alpha or beta and gamma, I can distribute the or throughout the expression. I can say alpha or beta and alpha or gamma. So the distributive law works in that way too. And it’s helpful if I want to take an or and move it into the expression. And we’ll see an example soon of why it is that we might actually care to do something like that. All right, so now we’ve seen a lot of different inference rules. And the question now is, how can we use those inference rules to actually try and draw some conclusions, to actually try and prove something about entailment, proving that given some initial knowledge base, we would like to find some way to prove that a query is true? Well, one way to think about it is actually to think back to what we talked about last time when we talked about search problems. Recall again that search problems have some sort of initial state. They have actions that you can take from one state to another as defined by a transition model that tells you how to get from one state to another. We talked about testing to see if you were at a goal. And then some path cost function to see how many steps did you have to take or how costly was the solution that you found. Now that we have these inference rules that take some set of sentences in propositional logic and get us some new set of sentences in propositional logic, we can actually treat those sentences or those sets of sentences as states inside of a search problem. So if we want to prove that some query is true, prove that some logical theorem is true, we can treat theorem proving as a form of a search problem. I can say that we begin in some initial state, where that initial state is the knowledge base that I begin with, the set of all of the sentences that I know to be true. What actions are available to me? Well, the actions are any of the inference rules that I can apply at any given time. The transition model just tells me after I apply the inference rule, here is the new set of all of the knowledge that I have, which will be the old set of knowledge, plus some additional inference that I’ve been able to draw, much as in the same way we saw what we got when we applied those inference rules and got some sort of conclusion. That conclusion gets added to our knowledge base, and our transition model will encode that. What is the goal test? Well, our goal test is checking to see if we have proved the statement we’re trying to prove, if the thing we’re trying to prove is inside of our knowledge base. And the path cost function, the thing we’re trying to minimize, is maybe the number of inference rules that we needed to use, the number of steps, so to speak, inside of our proof. And so here we’ve been able to apply the same types of ideas that we saw last time with search problems to something like trying to prove something about knowledge by taking our knowledge and framing it in terms that we can understand as a search problem with an initial state, with actions, with a transition model. So this shows a couple of things, one being how versatile search problems are, that they can be the same types of algorithms that we use to solve a maze or figure out how to get from point A to point B inside of driving directions, for example, can also be used as a theorem proving method of taking some sort of starting knowledge base and trying to prove something about that knowledge. So this, yet again, is a second way, in addition to model checking, to try and prove that certain statements are true. But it turns out there’s yet another way that we can try and apply inference. And we’ll talk about this now, which is not the only way, but certainly one of the most common, which is known as resolution. And resolution is based on another inference rule that we’ll take a look at now, quite a powerful inference rule that will let us prove anything that can be proven about a knowledge base. And it’s based on this basic idea. Let’s say I know that either Ron is in the Great Hall or Hermione is in the library. And let’s say I also know that Ron is not in the Great Hall. Based on those two pieces of information, what can I conclude? Well, I could pretty reasonably conclude that Hermione must be in the library. How do I know that? Well, it’s because these two statements, these two what we’ll call complementary literals, literals that complement each other, they’re opposites of each other, seem to conflict with each other. This sentence tells us that either Ron is in the Great Hall or Hermione is in the library. So if we know that Ron is not in the Great Hall, that conflicts with this one, which means Hermione must be in the library. And this we can frame as a more general rule known as the unit resolution rule, a rule that says that if we have p or q and we also know not p, well then from that we can reasonably conclude q. That if p or q are true and we know that p is not true, the only possibility is for q to then be true. And this, it turns out, is quite a powerful inference rule in terms of what it can do, in part because we can quickly start to generalize this rule. This q right here doesn’t need to just be a single propositional symbol. It could be multiple, all chained together in a single clause, as we’ll call it. So if I had something like p or q1 or q2 or q3, so on and so forth, up until qn, so I had n different other variables, and I have not p, well then what happens when these two complement each other is that these two clauses resolve, so to speak, to produce a new clause that is just q1 or q2 all the way up to qn. And in an or, the order of the arguments in the or doesn’t actually matter. The p doesn’t need to be the first thing. It could have been in the middle. But the idea here is that if I have p in one clause and not p in the other clause, well then I know that one of these remaining things must be true. I’ve resolved them in order to produce a new clause. But it turns out we can generalize this idea even further, in fact, and display even more power that we can have with this resolution rule. So let’s take another example. Let’s say, for instance, that I know the same piece of information that either Ron is in the Great Hall or Hermione is in the library. And the second piece of information I know is that Ron is not in the Great Hall or Harry is sleeping. So it’s not just a single piece of information. I have two different clauses. And we’ll define clauses more precisely in just a moment. What do I know here? Well again, for any propositional symbol like Ron is in the Great Hall, there are only two possibilities. Either Ron is in the Great Hall, in which case, based on resolution, we know that Harry must be sleeping, or Ron is not in the Great Hall, in which case we know based on the same rule that Hermione must be in the library. Based on those two things in combination, I can say based on these two premises that I can conclude that either Hermione is in the library or Harry is sleeping. So again, because these two conflict with each other, I know that one of these two must be true. And you can take a closer look and try and reason through that logic. Make sure you convince yourself that you believe this conclusion. Stated more generally, we can name this resolution rule by saying that if we know p or q is true, and we also know that not p or r is true, we resolve these two clauses together to get a new clause, q or r, that either q or r must be true. And again, much as in the last case, q and r don’t need to just be single propositional symbols. It could be multiple symbols. So if I had a rule that had p or q1 or q2 or q3, so on and so forth, up until qn, where n is just some number. And likewise, I had not p or r1 or r2, so on and so forth, up until rm, where m, again, is just some other number. I can resolve these two clauses together to get one of these must be true, q1 or q2 up until qn or r1 or r2 up until rm. And this is just a generalization of that same rule we saw before. Each of these things here are what we’re going to call a clause, where a clause is formally defined as a disjunction of literals, where a disjunction means it’s a bunch of things that are connected with or. Disjunction means things connected with or. Conjunction, meanwhile, is things connected with and. And a literal is either a propositional symbol or the opposite of a propositional symbol. So it’s something like p or q or not p or not q. Those are all propositional symbols or not of the propositional symbols. And we call those literals. And so a clause is just something like this, p or q or r, for example. Meanwhile, what this gives us an ability to do is it gives us an ability to turn logic, any logical sentence, into something called conjunctive normal form. A conjunctive normal form sentence is a logical sentence that is a conjunction of clauses. Recall, again, conjunction means things are connected to one another using and. And so a conjunction of clauses means it is an and of individual clauses, each of which has ors in it. So something like this, a or b or c, and d or not e, and f or g. Everything in parentheses is one clause. All of the clauses are connected to each other using an and. And everything in the clause is separated using an or. And this is just a standard form that we can translate a logical sentence into that just makes it easy to work with and easy to manipulate. And it turns out that we can take any sentence in logic and turn it into conjunctive normal form just by applying some inference rules and transformations to it. So we’ll take a look at how we can actually do that. So what is the process for taking a logical formula and converting it into conjunctive normal form, otherwise known as c and f? Well, the process looks a little something like this. We need to take all of the symbols that are not part of conjunctive normal form. The bi-conditionals and the implications and so forth, and turn them into something that is more closely like conjunctive normal form. So the first step will be to eliminate bi-conditionals, those if and only if double arrows. And we know how to eliminate bi-conditionals because we saw there was an inference rule to do just that. Any time I have an expression like alpha if and only if beta, I can turn that into alpha implies beta and beta implies alpha based on that inference rule we saw before. Likewise, in addition to eliminating bi-conditionals, I can eliminate implications as well, the if then arrows. And I can do that using the same inference rule we saw before too, taking alpha implies beta and turning that into not alpha or beta because that is logically equivalent to this first thing here. Then we can move knots inwards because we don’t want knots on the outsides of our expressions. Conjunctive normal form requires that it’s just claws and claws and claws and claws. Any knots need to be immediately next to propositional symbols. But we can move those knots around using De Morgan’s laws by taking something like not A and B and turn it into not A or not B, for example, using De Morgan’s laws to manipulate that. And after that, all we’ll be left with are ands and ors. And those are easy to deal with. We can use the distributive law to distribute the ors so that the ors end up on the inside of the expression, so to speak, and the ands end up on the outside. So this is the general pattern for how we’ll take a formula and convert it into conjunctive normal form. And let’s now take a look at an example of how we would do this and explore then why it is that we would want to do something like this. Here’s how we can do it. Let’s take this formula, for example. P or Q implies R. And I’d like to convert this into conjunctive normal form, where it’s all ands of clauses, and every clause is a disjunctive clause. It’s ors together. So what’s the first thing I need to do? Well, this is an implication. So let me go ahead and remove that implication. Using the implication inference rule, I can turn P or Q into P or Q implies R into not P or Q or R. So that’s the first step. I’ve gotten rid of the implication. And next, I can get rid of the not on the outside of this expression, too. I can move the nots inwards so they’re closer to the literals themselves by using De Morgan’s laws. And De Morgan’s law says that not P or Q is equivalent to not P and not Q. Again, here, just applying the inference rules that we’ve already seen in order to translate these statements. And now, I have two things that are separated by an or, where this thing on the inside is an and. What I’d really like to move the ors so the ors are on the inside, because conjunctive normal form means I need clause and clause and clause and clause. And so to do that, I can use the distributive law. If I have not P and not Q or R, I can distribute the or R to both of these to get not P or R and not Q or R using the distributive law. And this now here at the bottom is in conjunctive normal form. It is a conjunction and and of disjunctions of clauses that just are separated by ors. So this process can be used by any formula to take a logical sentence and turn it into this conjunctive normal form, where I have clause and clause and clause and clause and clause and so on. So why is this helpful? Why do we even care about taking all these sentences and converting them into this form? It’s because once they’re in this form where we have these clauses, these clauses are the inputs to the resolution inference rule that we saw a moment ago, that if I have two clauses where there’s something that conflicts or something complementary between those two clauses, I can resolve them to get a new clause, to draw a new conclusion. And we call this process inference by resolution, using the resolution rule to draw some sort of inference. And it’s based on the same idea, that if I have P or Q, this clause, and I have not P or R, that I can resolve these two clauses together to get Q or R as the resulting clause, a new piece of information that I didn’t have before. Now, a couple of key points that are worth noting about this before we talk about the actual algorithm. One thing is that, let’s imagine we have P or Q or S, and I also have not P or R or S. The resolution rule says that because this P conflicts with this not P, we would resolve to put everything else together to get Q or S or R or S. But it turns out that this double S is redundant, or S here and or S there. It doesn’t change the meaning of the sentence. So in resolution, when we do this resolution process, we’ll usually also do a process known as factoring, where we take any duplicate variables that show up and just eliminate them. So Q or S or R or S just becomes Q or R or S. The S only needs to appear once, no need to include it multiple times. Now, one final question worth considering is what happens if I try to resolve P and not P together? If I know that P is true and I know that not P is true, well, resolution says I can merge these clauses together and look at everything else. Well, in this case, there is nothing else, so I’m left with what we might call the empty clause. I’m left with nothing. And the empty clause is always false. The empty clause is equivalent to just being false. And that’s pretty reasonable because it’s impossible for both P and not P to both hold at the same time. P is either true or it’s not true, which means that if P is true, then this must be false. And if this is true, then this must be false. There is no way for both of these to hold at the same time. So if ever I try and resolve these two, it’s a contradiction, and I’ll end up getting this empty clause where the empty clause I can call equivalent to false. And this idea that if I resolve these two contradictory terms, I get the empty clause, this is the basis for our inference by resolution algorithm. Here’s how we’re going to perform inference by resolution at a very high level. We want to prove that our knowledge base entails some query alpha, that based on the knowledge we have, we can prove conclusively that alpha is going to be true. How are we going to do that? Well, in order to do that, we’re going to try to prove that if we know the knowledge and not alpha, that that would be a contradiction. And this is a common technique in computer science more generally, this idea of proving something by contradiction. If I want to prove that something is true, I can do so by first assuming that it is false and showing that it would be contradictory, showing that it leads to some contradiction. And if the thing I’m trying to prove, if when I assume it’s false, leads to a contradiction, then it must be true. And that’s the logical approach or the idea behind a proof by contradiction. And that’s what we’re going to do here. We want to prove that this query alpha is true. So we’re going to assume that it’s not true. We’re going to assume not alpha. And we’re going to try and prove that it’s a contradiction. If we do get a contradiction, well, then we know that our knowledge entails the query alpha. If we don’t get a contradiction, there is no entailment. This is this idea of a proof by contradiction of assuming the opposite of what you’re trying to prove. And if you can demonstrate that that’s a contradiction, then what you’re proving must be true. But more formally, how do we actually do this? How do we check that knowledge base and not alpha is going to lead to a contradiction? Well, here is where resolution comes into play. To determine if our knowledge base entails some query alpha, we’re going to convert knowledge base and not alpha to conjunctive normal form, that form where we have a whole bunch of clauses that are all anded together. And when we have these individual clauses, now we can keep checking to see if we can use resolution to produce a new clause. We can take any pair of clauses and check, is there some literal that is the opposite of each other or complementary to each other in both of them? For example, I have a p in one clause and a not p in another clause. Or an r in one clause and a not r in another clause. If ever I have that situation where once I convert to conjunctive normal form and I have a whole bunch of clauses, I see two clauses that I can resolve to produce a new clause, then I’ll do so. This process occurs in a loop. I’m going to keep checking to see if I can use resolution to produce a new clause and keep using those new clauses to try to generate more new clauses after that. Now, it just so may happen that eventually we may produce the empty clause, the clause we were talking about before. If I resolve p and not p together, that produces the empty clause and the empty clause we know to be false. Because we know that there’s no way for both p and not p to both simultaneously be true. So if ever we produce the empty clause, then we have a contradiction. And if we have a contradiction, that’s exactly what we were trying to do in a fruit by contradiction. If we have a contradiction, then we know that our knowledge base must entail this query alpha. And we know that alpha must be true. And it turns out, and we won’t go into the proof here, but you can show that otherwise, if you don’t produce the empty clause, then there is no entailment. If we run into a situation where there are no more new clauses to add, we’ve done all the resolution that we can do, and yet we still haven’t produced the empty clause, then there is no entailment in this case. And this now is the resolution algorithm. And it’s very abstract looking, especially this idea of like, what does it even mean to have the empty clause? So let’s take a look at an example, actually try and prove some entailment by using this inference by resolution process. So here’s our question. We have this knowledge base. Here is the knowledge that we know, A or B, and not B or C, and not C. And we want to know if all of this entails A. So this is our knowledge base here, this whole log thing. And our query alpha is just this propositional symbol, A. So what do we do? Well, first, we want to prove by contradiction. So we want to first assume that A is false, and see if that leads to some sort of contradiction. So here is what we’re going to start with, A or B, and not B or C, and not C. This is our knowledge base. And we’re going to assume not A. We’re going to assume that the thing we’re trying to prove is, in fact, false. And so this is now in conjunctive normal form, and I have four different clauses. I have A or B. I have not B or C. I have not C, and I have not A. And now, I can begin to just pick two clauses that I can resolve, and apply the resolution rule to them. And so looking at these four clauses, I see, all right, these two clauses are ones I can resolve. I can resolve them because there are complementary literals that show up in them. There’s a C here, and a not C here. So just looking at these two clauses, if I know that not B or C is true, and I know that C is not true, well, then I can resolve these two clauses to say, all right, not B, that must be true. I can generate this new clause as a new piece of information that I now know to be true. And all right, now I can repeat this process, do the process again. Can I use resolution again to get some new conclusion? Well, it turns out I can. I can use that new clause I just generated, along with this one here. There are complementary literals. This B is complementary to, or conflicts with, this not B over here. And so if I know that A or B is true, and I know that B is not true, well, then the only remaining possibility is that A must be true. So now we have A. That is a new clause that I’ve been able to generate. And now, I can do this one more time. I’m looking for two clauses that can be resolved, and you might programmatically do this by just looping over all possible pairs of clauses and checking for complementary literals in each. And here, I can say, all right, I found two clauses, not A and A, that conflict with each other. And when I resolve these two together, well, this is the same as when we were resolving P and not P from before. When I resolve these two clauses together, I get rid of the As, and I’m left with the empty clause. And the empty clause we know to be false, which means we have a contradiction, which means we can safely say that this whole knowledge base does entail A. That if this sentence is true, that we know that A for sure is also true. So this now, using inference by resolution, is an entirely different way to take some statement and try and prove that it is, in fact, true. Instead of enumerating all of the possible worlds that we might be in in order to try to figure out in which cases is the knowledge base true and in which cases are query true, instead we use this resolution algorithm to say, let’s keep trying to figure out what conclusions we can draw and see if we reach a contradiction. And if we reach a contradiction, then that tells us something about whether our knowledge actually entails the query or not. And it turns out there are many different algorithms that can be used for inference. What we’ve just looked at here are just a couple of them. And in fact, all of this is just based on one particular type of logic. It’s based on propositional logic, where we have these individual symbols and we connect them using and and or and not and implies and by conditionals. But propositional logic is not the only kind of logic that exists. And in fact, we see that there are limitations that exist in propositional logic, especially as we saw in examples like with the mastermind example or with the example with the logic puzzle where we had different Hogwarts house people that belong to different houses and we were trying to figure out who belonged to which houses. There were a lot of different propositional symbols that we needed in order to represent some fairly basic ideas. So now is the final topic that we’ll take a look at just before we end class today is one final type of logic different from propositional logic known as first order logic, which is a little bit more powerful than propositional logic and is going to make it easier for us to express certain types of ideas. In propositional logic, if we think back to that puzzle with the people in the Hogwarts houses, we had a whole bunch of symbols. And every symbol could only be true or false. We had a symbol for Minerva Gryffindor, which was either true of Minerva within Gryffindor and false otherwise, and likewise for Minerva Hufflepuff and Minerva Ravenclaw and Minerva Slytherin and so forth. But this was starting to get quite redundant. We wanted some way to be able to express that there is a relationship between these propositional symbols, that Minerva shows up in all of them. And also, I would have liked to have not have had so many different symbols to represent what really was a fairly straightforward problem. So first order logic will give us a different way of trying to deal with this idea by giving us two different types of symbols. We’re going to have constant symbols that are going to represent objects like people or houses. And then predicate symbols, which you can think of as relations or functions that take an input and evaluate them to true or false, for example, that tell us whether or not some property of some constant or some pair of constants or multiple constants actually holds. So we’ll see an example of that in just a moment. For now, in this same problem, our constant symbols might be objects, things like people or houses. So Minerva, Pomona, Horace, Gilderoy, those are all constant symbols, as are my four houses, Gryffindor, Hufflepuff, Ravenclaw, and Slytherin. Predicates, meanwhile, these predicate symbols are going to be properties that might hold true or false of these individual constants. So person might hold true of Minerva, but it would be false for Gryffindor because Gryffindor is not a person. And house is going to hold true for Ravenclaw, but it’s not going to hold true for Horace, for example, because Horace is a person. And belongs to, meanwhile, is going to be some relation that is going to relate people to their houses. And it’s going to only tell me when someone belongs to a house or does not. So let’s take a look at some examples of what a sentence in first order logic might actually look like. A sentence might look like something like this. Person Minerva, with Minerva in parentheses, and person being a predicate symbol, Minerva being a constant symbol. This sentence in first order logic effectively means Minerva is a person, or the person property applies to the Minerva object. So if I want to say something like Minerva is a person, here is how I express that idea using first order logic. Meanwhile, I can say something like, house Gryffindor, to likewise express the idea that Gryffindor is a house. I can do that this way. And all of the same logical connectives that we saw in propositional logic, those are going to work here too. And or implication by conditional not. In fact, I can use not to say something like, not house Minerva. And this sentence in first order logic means something like, Minerva is not a house. It is not true that the house property applies to Minerva. Meanwhile, in addition to some of these predicate symbols that just take a single argument, some of our predicate symbols are going to express binary relations, relations between two of its arguments. So I could say something like, belongs to, and then two inputs, Minerva and Gryffindor, to express the idea that Minerva belongs to Gryffindor. And so now here’s the key difference, or one of the key differences, between this and propositional logic. In propositional logic, I needed one symbol for Minerva Gryffindor, and one symbol for Minerva Hufflepuff, and one symbol for all the other people’s Gryffindor and Hufflepuff variables. In this case, I just need one symbol for each of my people, and one symbol for each of my houses. And then I can express as a predicate something like, belongs to, and say, belongs to Minerva Gryffindor, to express the idea that Minerva belongs to Gryffindor House. So already we can see that first order logic is quite expressive in being able to express these sorts of sentences using the existing constant symbols and predicates that already exist, while minimizing the number of new symbols that I need to create. I can just use eight symbols for people for houses, instead of 16 symbols for every possible combination of each. But first order logic gives us a couple of additional features that we can use to express even more complex ideas. And these more additional features are generally known as quantifiers. And there are two main quantifiers in first order logic, the first of which is universal quantification. Universal quantification lets me express an idea like something is going to be true for all values of a variable. Like for all values of x, some statement is going to hold true. So what might a sentence in universal quantification look like? Well, we’re going to use this upside down a to mean for all. So upside down ax means for all values of x, where x is any object, this is going to hold true. Belongs to x Gryffindor implies not belongs to x Hufflepuff. So let’s try and parse this out. This means that for all values of x, if this holds true, if x belongs to Gryffindor, then this does not hold true. x does not belong to Hufflepuff. So translated into English, this sentence is saying something like for all objects x, if x belongs to Gryffindor, then x does not belong to Hufflepuff, for example. Or a phrase even more simply, anyone in Gryffindor is not in Hufflepuff, simplified way of saying the same thing. So this universal quantification lets us express an idea like something is going to hold true for all values of a particular variable. In addition to universal quantification though, we also have existential quantification. Whereas universal quantification said that something is going to be true for all values of a variable, existential quantification says that some expression is going to be true for some value of a variable, at least one value of the variable. So let’s take a look at a sample sentence using existential quantification. One such sentence looks like this. There exists an x. This backwards e stands for exists. And here we’re saying there exists an x such that house x and belongs to Minerva x. In other words, there exists some object x where x is a house and Minerva belongs to x. Or phrased a little more succinctly in English, I’m here just saying Minerva belongs to a house. There’s some object that is a house and Minerva belongs to a house. And combining this universal and existential quantification, we can create far more sophisticated logical statements than we were able to just using propositional logic. I could combine these to say something like this. For all x, person x implies there exists a y such that house y and belongs to xy. All right. So a lot of stuff going on there, a lot of symbols. Let’s try and parse it out and just understand what it’s saying. Here we’re saying that for all values of x, if x is a person, then this is true. So in other words, I’m saying for all people, and we call that person x, this statement is going to be true. What statement is true of all people? Well, there exists a y that is a house, so there exists some house, and x belongs to y. In other words, I’m saying that for all people out there, there exists some house such that x, the person, belongs to y, the house. This is phrased more succinctly. I’m saying that every person belongs to a house, that for all x, if x is a person, then there exists a house that x belongs to. And so we can now express a lot more powerful ideas using this idea now of first order logic. And it turns out there are many other kinds of logic out there. There’s second order logic and other higher order logic, each of which allows us to express more and more complex ideas. But all of it, in this case, is really in pursuit of the same goal, which is the representation of knowledge. We want our AI agents to be able to know information, to represent that information, whether that’s using propositional logic or first order logic or some other logic, and then be able to reason based on that, to be able to draw conclusions, make inferences, figure out whether there’s some sort of entailment relationship, as by using some sort of inference algorithm, something like inference by resolution or model checking or any number of these other algorithms that we can use in order to take information that we know and translate it to additional conclusions. So all of this has helped us to create AI that is able to represent information about what it knows and what it doesn’t know. Next time, though, we’ll take a look at how we can make our AI even more powerful by not just encoding information that we know for sure to be true and not to be true, but also to take a look at uncertainty, to look at what happens if AI thinks that something might be probable or maybe not very probable or somewhere in between those two extremes, all in the pursuit of trying to build our intelligent systems to be even more intelligent. We’ll see you next time. Thank you. All right, welcome back, everyone, to an introduction to artificial intelligence with Python. And last time, we took a look at how it is that AI inside of our computers can represent knowledge. We represented that knowledge in the form of logical sentences in a variety of different logical languages. And the idea was we wanted our AI to be able to represent knowledge or information and somehow use those pieces of information to be able to derive new pieces of information by inference, to be able to take some information and deduce some additional conclusions based on the information that it already knew for sure. But in reality, when we think about computers and we think about AI, very rarely are our machines going to be able to know things for sure. Oftentimes, there’s going to be some amount of uncertainty in the information that our AIs or our computers are dealing with, where it might believe something with some probability, as we’ll soon discuss what probability is all about and what it means, but not entirely for certain. And we want to use the information that it has some knowledge about, even if it doesn’t have perfect knowledge, to still be able to make inferences, still be able to draw conclusions. So you might imagine, for example, in the context of a robot that has some sensors and is exploring some environment, it might not know exactly where it is or exactly what’s around it, but it does have access to some data that can allow it to draw inferences with some probability. There’s some likelihood that one thing is true or another. Or you can imagine in context where there is a little bit more randomness and uncertainty, something like predicting the weather, where you might not be able to know for sure what tomorrow’s weather is with 100% certainty, but you can probably infer with some probability what tomorrow’s weather is going to be based on maybe today’s weather and yesterday’s weather and other data that you might have access to as well. And so oftentimes, we can distill this in terms of just possible events that might happen and what the likelihood of those events are. This comes a lot in games, for example, where there is an element of chance inside of those games. So you imagine rolling a dice. You’re not sure exactly what the die roll is going to be, but you know it’s going to be one of these possibilities from 1 to 6, for example. And so here now, we introduce the idea of probability theory. And what we’ll take a look at today is beginning by looking at the mathematical foundations of probability theory, getting an understanding for some of the key concepts within probability, and then diving into how we can use probability and the ideas that we look at mathematically to represent some ideas in terms of models that we can put into our computers in order to program an AI that is able to use information about probability to draw inferences, to make some judgments about the world with some probability or likelihood of being true. So probability ultimately boils down to this idea that there are possible worlds that we’re here representing using this little Greek letter omega. And the idea of a possible world is that when I roll a die, there are six possible worlds that could result from it. I could roll a 1, or a 2, or a 3, or a 4, or a 5, or a 6. And each of those are a possible world. And each of those possible worlds has some probability of being true, the probability that I do roll a 1, or a 2, or a 3, or something else. And we represent that probability like this, using the capital letter P. And then in parentheses, what it is that we want the probability of. So this right here would be the probability of some possible world as represented by the little letter omega. Now, there are a couple of basic axioms of probability that become relevant as we consider how we deal with probability and how we think about it. First and foremost, every probability value must range between 0 and 1 inclusive. So the smallest value any probability can have is the number 0, which is an impossible event. Something like I roll a die, and the die is a 7 is the roll that I get. If the die only has numbers 1 through 6, the event that I roll a 7 is impossible, so it would have probability 0. And on the other end of the spectrum, probability can range all the way up to the positive number 1, meaning an event is certain to happen, that I roll a die and the number is less than 10, for example. That is an event that is guaranteed to happen if the only sides on my die are 1 through 6, for instance. And then they can range through any real number in between these two values. Where, generally speaking, a higher value for the probability means an event is more likely to take place, and a lower value for the probability means the event is less likely to take place. And the other key rule for probability looks a little bit like this. This sigma notation, if you haven’t seen it before, refers to summation, the idea that we’re going to be adding up a whole sequence of values. And this sigma notation is going to come up a couple of times today, because as we deal with probability, oftentimes we’re adding up a whole bunch of individual values or individual probabilities to get some other value. So we’ll see this come up a couple of times. But what this notation means is that if I sum up all of the possible worlds omega that are in big omega, which represents the set of all the possible worlds, meaning I take for all of the worlds in the set of possible worlds and add up all of their probabilities, what I ultimately get is the number 1. So if I take all the possible worlds, add up what each of their probabilities is, I should get the number 1 at the end, meaning all probabilities just need to sum to 1. So for example, if I take dice, for example, and if you imagine I have a fair die with numbers 1 through 6 and I roll the die, each one of these rolls has an equal probability of taking place. And the probability is 1 over 6, for example. So each of these probabilities is between 0 and 1, 0 meaning impossible and 1 meaning for certain. And if you add up all of these probabilities for all of the possible worlds, you get the number 1. And we can represent any one of those probabilities like this. The probability that we roll the number 2, for example, is just 1 over 6. Every six times we roll the die, we’d expect that one time, for instance, the die might come up as a 2. Its probability is not certain, but it’s a little more than nothing, for instance. And so this is all fairly straightforward for just a single die. But things get more interesting as our models of the world get a little bit more complex. Let’s imagine now that we’re not just dealing with a single die, but we have two dice, for example. I have a red die here and a blue die there, and I care not just about what the individual roll is, but I care about the sum of the two rolls. In this case, the sum of the two rolls is the number 3. How do I begin to now reason about what does the probability look like if instead of having one die, I now have two dice? Well, what we might imagine is that we could first consider what are all of the possible worlds. And in this case, all of the possible worlds are just every combination of the red and blue die that I could come up with. For the red die, it could be a 1 or a 2 or a 3 or a 4 or a 5 or a 6. And for each of those possibilities, the blue die, likewise, could also be either 1 or 2 or 3 or 4 or 5 or 6. And it just so happens that in this particular case, each of these possible combinations is equally likely. Equally likely are all of these various different possible worlds. That’s not always going to be the case. If you imagine more complex models that we could try to build and things that we could try to represent in the real world, it’s probably not going to be the case that every single possible world is always equally likely. But in the case of fair dice, where in any given die roll, any one number has just as good a chance of coming up as any other number, we can consider all of these possible worlds to be equally likely. But even though all of the possible worlds are equally likely, that doesn’t necessarily mean that their sums are equally likely. So if we consider what the sum is of all of these two, so 1 plus 1, that’s a 2. 2 plus 1 is a 3. And consider for each of these possible pairs of numbers what their sum ultimately is, we can notice that there are some patterns here, where it’s not entirely the case that every number comes up equally likely. If you consider 7, for example, what’s the probability that when I roll two dice, their sum is 7? There are several ways this can happen. There are six possible worlds where the sum is 7. It could be a 1 and a 6, or a 2 and a 5, or a 3 and a 4, a 4 and a 3, and so forth. But if you instead consider what’s the probability that I roll two dice, and the sum of those two die rolls is 12, for example, we’re looking at this diagram, there’s only one possible world in which that can happen. And that’s the possible world where both the red die and the blue die both come up as sixes to give us a sum total of 12. So based on just taking a look at this diagram, we see that some of these probabilities are likely different. The probability that the sum is a 7 must be greater than the probability that the sum is a 12. And we can represent that even more formally by saying, OK, the probability that we sum to 12 is 1 out of 36. Out of the 36 equally likely possible worlds, 6 squared because we have six options for the red die and six options for the blue die, out of those 36 options, only one of them sums to 12. Whereas on the other hand, the probability that if we take two dice rolls and they sum up to the number 7, well, out of those 36 possible worlds, there were six worlds where the sum was 7. And so we get 6 over 36, which we can simplify as a fraction to just 1 over 6. So here now, we’re able to represent these different ideas of probability, representing some events that might be more likely and then other events that are less likely as well. And these sorts of judgments, where we’re figuring out just in the abstract what is the probability that this thing takes place, are generally known as unconditional probabilities. Some degree of belief we have in some proposition, some fact about the world, in the absence of any other evidence. Without knowing any additional information, if I roll a die, what’s the chance it comes up as a 2? Or if I roll two dice, what’s the chance that the sum of those two die rolls is a 7? But usually when we’re thinking about probability, especially when we’re thinking about training in AI to intelligently be able to know something about the world and make predictions based on that information, it’s not unconditional probability that our AI is dealing with, but rather conditional probability, probability where rather than having no original knowledge, we have some initial knowledge about the world and how the world actually works. So conditional probability is the degree of belief in a proposition given some evidence that has already been revealed to us. So what does this look like? Well, it looks like this in terms of notation. We’re going to represent conditional probability as probability of A and then this vertical bar and then B. And the way to read this is the thing on the left-hand side of the vertical bar is what we want the probability of. Here now, I want the probability that A is true, that it is the real world, that it is the event that actually does take place. And then on the right side of the vertical bar is our evidence, the information that we already know for certain about the world. For example, that B is true. So the way to read this entire expression is what is the probability of A given B, the probability that A is true, given that we already know that B is true. And this type of judgment, conditional probability, the probability of one thing given some other fact, comes up quite a lot when we think about the types of calculations we might want our AI to be able to do. For example, we might care about the probability of rain today given that we know that it rained yesterday. We could think about the probability of rain today just in the abstract. What is the chance that today it rains? But usually, we have some additional evidence. I know for certain that it rained yesterday. And so I would like to calculate the probability that it rains today given that I know that it rained yesterday. Or you might imagine that I want to know the probability that my optimal route to my destination changes given the current traffic condition. So whether or not traffic conditions change, that might change the probability that this route is actually the optimal route. Or you might imagine in a medical context, I want to know the probability that a patient has a particular disease given some results of some tests that have been performed on that patient. And I have some evidence, the results of that test, and I would like to know the probability that a patient has a particular disease. So this notion of conditional probability comes up everywhere. So we begin to think about what we would like to reason about, but being able to reason a little more intelligently by taking into account evidence that we already have. We’re more able to get an accurate result for what is the likelihood that someone has this disease if we know this evidence, the results of the test, as opposed to if we were just calculating the unconditional probability of saying, what is the probability they have the disease without any evidence to try and back up our result one way or the other. So now that we’ve got this idea of what conditional probability is, the next question we have to ask is, all right, how do we calculate conditional probability? How do we figure out mathematically, if I have an expression like this, how do I get a number from that? What does conditional probability actually mean? Well, the formula for conditional probability looks a little something like this. The probability of a given b, the probability that a is true, given that we know that b is true, is equal to this fraction, the probability that a and b are true, divided by just the probability that b is true. And the way to intuitively try to think about this is that if I want to know the probability that a is true, given that b is true, well, I want to consider all the ways they could both be true out of the only worlds that I care about are the worlds where b is already true. I can sort of ignore all the cases where b isn’t true, because those aren’t relevant to my ultimate computation. They’re not relevant to what it is that I want to get information about. So let’s take a look at an example. Let’s go back to that example of rolling two dice and the idea that those two dice might sum up to the number 12. We discussed earlier that the unconditional probability that if I roll two dice and they sum to 12 is 1 out of 36, because out of the 36 possible worlds that I might care about, in only one of them is the sum of those two dice 12. It’s only when red is 6 and blue is also 6. But let’s say now that I have some additional information. I now want to know what is the probability that the two dice sum to 12, given that I know that the red die was a 6. So I already have some evidence. I already know the red die is a 6. I don’t know what the blue die is. That information isn’t given to me in this expression. But given the fact that I know that the red die rolled a 6, what is the probability that we sum to 12? And so we can begin to do the math using that expression from before. Here, again, are all of the possibilities, all of the possible combinations of red die being 1 through 6 and blue die being 1 through 6. And I might consider first, all right, what is the probability of my evidence, my B variable, where I want to know, what is the probability that the red die is a 6? Well, the probability that the red die is a 6 is just 1 out of 6. So these 1 out of 6 options are really the only worlds that I care about here now. All the rest of them are irrelevant to my calculation, because I already have this evidence that the red die was a 6, so I don’t need to care about all of the other possibilities that could result. So now, in addition to the fact that the red die rolled as a 6 and the probability of that, the other piece of information I need to know in order to calculate this conditional probability is the probability that both of my variables, A and B, are true. The probability that both the red die is a 6, and they all sum to 12. So what is the probability that both of these things happen? Well, it only happens in one possible case in 1 out of these 36 cases, and it’s the case where both the red and the blue die are equal to 6. This is a piece of information that we already knew. And so this probability is equal to 1 over 36. And so to get the conditional probability that the sum is 12, given that I know that the red dice is equal to 6, well, I just divide these two values together, and 1 over 36 divided by 1 over 6 gives us this probability of 1 over 6. Given that I know that the red die rolled a value of 6, the probability that the sum of the two dice is 12 is also 1 over 6. And that probably makes intuitive sense to you, too, because if the red die is a 6, the only way for me to get to a 12 is if the blue die also rolls a 6, and we know that the probability of the blue die rolling a 6 is 1 over 6. So in this case, the conditional probability seems fairly straightforward. But this idea of calculating a conditional probability by looking at the probability that both of these events take place is an idea that’s going to come up again and again. This is the definition now of conditional probability. And we’re going to use that definition as we think about probability more generally to be able to draw conclusions about the world. This, again, is that formula. The probability of A given B is equal to the probability that A and B take place divided by the probability of B. And you’ll see this formula sometimes written in a couple of different ways. You could imagine algebraically multiplying both sides of this equation by probability of B to get rid of the fraction, and you’ll get an expression like this. The probability of A and B, which is this expression over here, is just the probability of B times the probability of A given B. Or you could represent this equivalently since A and B in this expression are interchangeable. A and B is the same thing as B and A. You could imagine also representing the probability of A and B as the probability of A times the probability of B given A, just switching all of the A’s and B’s. These three are all equivalent ways of trying to represent what joint probability means. And so you’ll sometimes see all of these equations, and they might be useful to you as you begin to reason about probability and to think about what values might be taking place in the real world. Now, sometimes when we deal with probability, we don’t just care about a Boolean event like did this happen or did this not happen. Sometimes we might want the ability to represent variable values in a probability space where some variable might take on multiple different possible values. And in probability, we call a variable in probability theory a random variable. A random variable in probability is just some variable in probability theory that has some domain of values that it can take on. So what do I mean by this? Well, what I mean is I might have a random variable that is just called roll, for example, that has six possible values. Roll is my variable, and the possible values, the domain of values that it can take on are 1, 2, 3, 4, 5, and 6. And I might like to know the probability of each. In this case, they happen to all be the same. But in other random variables, that might not be the case. For example, I might have a random variable to represent the weather, for example, where the domain of values it could take on are things like sun or cloudy or rainy or windy or snowy. And each of those might have a different probability. And I care about knowing what is the probability that the weather equals sun or that the weather equals clouds, for instance. And I might like to do some mathematical calculations based on that information. Other random variables might be something like traffic. What are the odds that there is no traffic or light traffic or heavy traffic? Traffic, in this case, is my random variable. And the values that that random variable can take on are here. It’s either none or light or heavy. And I, the person doing these calculations, I, the person encoding these random variables into my computer, need to make the decision as to what these possible values actually are. You might imagine, for example, for a flight. If I care about whether or not I make it or do a flight on time, my flight has a couple of possible values that it could take on. My flight could be on time. My flight could be delayed. My flight could be canceled. So flight, in this case, is my random variable. And these are the values that it can take on. And often, I want to know something about the probability that my random variable takes on each of those possible values. And this is what we then call a probability distribution. A probability distribution takes a random variable and gives me the probability for each of the possible values in its domain. So in the case of this flight, for example, my probability distribution might look something like this. My probability distribution says the probability that the random variable flight is equal to the value on time is 0.6. Or otherwise, put into more English human-friendly terms, the likelihood that my flight is on time is 60%, for example. And in this case, the probability that my flight is delayed is 30%. The probability that my flight is canceled is 10% or 0.1. And if you sum up all of these possible values, the sum is going to be 1, right? If you take all of the possible worlds, here are my three possible worlds for the value of the random variable flight, add them all up together, the result needs to be the number 1 per that axiom of probability theory that we’ve discussed before. So this now is one way of representing this probability distribution for the random variable flight. Sometimes you’ll see it represented a little bit more concisely that this is pretty verbose for really just trying to express three possible values. And so often, you’ll instead see the same notation representing using a vector. And all a vector is is a sequence of values. As opposed to just a single value, I might have multiple values. And so I could extend instead, represent this idea this way. Bold p, so a larger p, generally meaning the probability distribution of this variable flight is equal to this vector represented in angle brackets. The probability distribution is 0.6, 0.3, and 0.1. And I would just have to know that this probability distribution is in order of on time or delayed and canceled to know how to interpret this vector. To mean the first value in the vector is the probability that my flight is on time. The second value in the vector is the probability that my flight is delayed. And the third value in the vector is the probability that my flight is canceled. And so this is just an alternate way of representing this idea, a little more verbosely. But oftentimes, you’ll see us just talk about a probability distribution over a random variable. And whenever we talk about that, what we’re really doing is trying to figure out the probabilities of each of the possible values that that random variable can take on. But this notation is just a little bit more succinct, even though it can sometimes be a little confusing, depending on the context in which you see it. So we’ll start to look at examples where we use this sort of notation to describe probability and to describe events that might take place. A couple of other important ideas to know with regards to probability theory. One is this idea of independence. And independence refers to the idea that the knowledge of one event doesn’t influence the probability of another event. So for example, in the context of my two dice rolls, where I had the red die and the blue die, the probability that I roll the red die and the blue die, those two events, red die and blue die, are independent. Knowing the result of the red die doesn’t change the probabilities for the blue die. It doesn’t give me any additional information about what the value of the blue die is ultimately going to be. But that’s not always going to be the case. You might imagine that in the case of weather, something like clouds and rain, those are probably not independent. But if it is cloudy, that might increase the probability that later in the day it’s going to rain. So some information informs some other event or some other random variable. So independence refers to the idea that one event doesn’t influence the other. And if they’re not independent, then there might be some relationship. So mathematically, formally, what does independence actually mean? Well, recall this formula from before, that the probability of A and B is the probability of A times the probability of B given A. And the more intuitive way to think about this is that to know how likely it is that A and B happen, well, let’s first figure out the likelihood that A happens. And then given that we know that A happens, let’s figure out the likelihood that B happens and multiply those two things together. But if A and B were independent, meaning knowing A doesn’t change anything about the likelihood that B is true, well, then the probability of B given A, meaning the probability that B is true, given that I know A is true, well, that I know A is true shouldn’t really make a difference if these two things are independent, that A shouldn’t influence B at all. So the probability of B given A is really just the probability of B. If it is true that A and B are independent. And so this right here is one example of a definition for what it means for A and B to be independent. The probability of A and B is just the probability of A times the probability of B. Anytime you find two events A and B where this relationship holds, then you can say that A and B are independent. So an example of that might be the dice that we were taking a look at before. Here, if I wanted the probability of red being a 6 and blue being a 6, well, that’s just the probability that red is a 6 multiplied by the probability that blue is a 6. It’s both equal to 1 over 36. So I can say that these two events are independent. What wouldn’t be independent, for example, would be an example. So this, for example, has a probability of 1 over 36, as we talked about before. But what wouldn’t be independent would be a case like this, the probability that the red die rolls a 6 and the red die rolls a 4. If you just naively took, OK, red die 6, red die 4, well, if I’m only rolling the die once, you might imagine the naive approach is to say, well, each of these has a probability of 1 over 6. So multiply them together, and the probability is 1 over 36. But of course, if you’re only rolling the red die once, there’s no way you could get two different values for the red die. It couldn’t both be a 6 and a 4. So the probability should be 0. But if you were to multiply probability of red 6 times probability of red 4, well, that would equal 1 over 36. But of course, that’s not true. Because we know that there is no way, probability 0, that when we roll the red die once, we get both a 6 and a 4, because only one of those possibilities can actually be the result. And so we can say that the event that red roll is 6 and the event that red roll is 4, those two events are not independent. If I know that the red roll is a 6, I know that the red roll cannot possibly be a 4, so these things are not independent. And instead, if I wanted to calculate the probability, I would need to use this conditional probability as the regular definition of the probability of two events taking place. And the probability of this now, well, the probability of the red roll being a 6, that’s 1 over 6. But what’s the probability that the roll is a 4 given that the roll is a 6? Well, this is just 0, because there’s no way for the red roll to be a 4, given that we already know the red roll is a 6. And so the value, if we do add all that multiplication, is we get the number 0. So this idea of conditional probability is going to come up again and again, especially as we begin to reason about multiple different random variables that might be interacting with each other in some way. And this gets us to one of the most important rules in probability theory, which is known as Bayes rule. And it turns out that just using the information we’ve already learned about probability and just applying a little bit of algebra, we can actually derive Bayes rule for ourselves. But it’s a very important rule when it comes to inference and thinking about probability in the context of what it is that a computer can do or what a mathematician could do by having access to information about probability. So let’s go back to these equations to be able to derive Bayes rule ourselves. We know the probability of A and B, the likelihood that A and B take place, is the likelihood of B, and then the likelihood of A, given that we know that B is already true. And likewise, the probability of A given A and B is the probability of A times the probability of B, given that we know that A is already true. This is sort of a symmetric relationship where it doesn’t matter the order of A and B and B and A mean the same thing. And so in these equations, we can just swap out A and B to be able to represent the exact same idea. So we know that these two equations are already true. We’ve seen that already. And now let’s just do a little bit of algebraic manipulation of this stuff. Both of these expressions on the right-hand side are equal to the probability of A and B. So what I can do is take these two expressions on the right-hand side and just set them equal to each other. If they’re both equal to the probability of A and B, then they both must be equal to each other. So probability of A times probability of B given A is equal to the probability of B times the probability of A given B. And now all we’re going to do is do a little bit of division. I’m going to divide both sides by P of A. And now I get what is Bayes’ rule. The probability of B given A is equal to the probability of B times the probability of A given B divided by the probability of A. And sometimes in Bayes’ rule, you’ll see the order of these two arguments switched. So instead of B times A given B, it’ll be A given B times B. That ultimately doesn’t matter because in multiplication, you can switch the order of the two things you’re multiplying, and it doesn’t change the result. But this here right now is the most common formulation of Bayes’ rule. The probability of B given A is equal to the probability of A given B times the probability of B divided by the probability of A. And this rule, it turns out, is really important when it comes to trying to infer things about the world, because it means you can express one conditional probability, the conditional probability of B given A, using knowledge about the probability of A given B, using the reverse of that conditional probability. So let’s first do a little bit of an example with this, just to see how we might use it, and then explore what this means a little bit more generally. So we’re going to construct a situation where I have some information. There are two events that I care about, the idea that it’s cloudy in the morning and the idea that it is rainy in the afternoon. Those are two different possible events that could take place, cloudy in the morning, or the AM, rainy in the PM. And what I care about is, given clouds in the morning, what is the probability of rain in the afternoon? A reasonable question I might ask, in the morning, I look outside, or an AI’s camera looks outside and sees that there are clouds in the morning. And we want to conclude, we want to figure out what is the probability that in the afternoon, there is going to be rain. Of course, in the abstract, we don’t have access to this kind of information, but we can use data to begin to try and figure this out. So let’s imagine now that I have access to some pieces of information. I have access to the idea that 80% of rainy afternoons start out with a cloudy morning. And you might imagine that I could have gathered this data just by looking at data over a sequence of time, that I know that 80% of the time when it’s raining in the afternoon, it was cloudy that morning. I also know that 40% of days have cloudy mornings. And I also know that 10% of days have rainy afternoons. And now using this information, I would like to figure out, given clouds in the morning, what is the probability that it rains in the afternoon? I want to know the probability of afternoon rain given morning clouds. And I can do that, in particular, using this fact, the probability of, so if I know that 80% of rainy afternoons start with cloudy mornings, then I know the probability of cloudy mornings given rainy afternoons. So using sort of the reverse conditional probability, I can figure that out. Expressed in terms of Bayes rule, this is what that would look like. Probability of rain given clouds is the probability of clouds given rain times the probability of rain divided by the probability of clouds. Here I’m just substituting in for the values of a and b from that equation of Bayes rule from before. And then I can just do the math. I have this information. I know that 80% of the time, if it was raining, then there were clouds in the morning. So 0.8 here. Probability of rain is 0.1, because 10% of days were rainy, and 40% of days were cloudy. I do the math, and I can figure out the answer is 0.2. So the probability that it rains in the afternoon, given that it was cloudy in the morning, is 0.2 in this case. And this now is an application of Bayes rule, the idea that using one conditional probability, we can get the reverse conditional probability. And this is often useful when one of the conditional probabilities might be easier for us to know about or easier for us to have data about. And using that information, we can calculate the other conditional probability. So what does this look like? Well, it means that knowing the probability of cloudy mornings given rainy afternoons, we can calculate the probability of rainy afternoons given cloudy mornings. Or, for example, more generally, if we know the probability of some visible effect, some effect that we can see and observe, given some unknown cause that we’re not sure about, well, then we can calculate the probability of that unknown cause given the visible effect. So what might that look like? Well, in the context of medicine, for example, I might know the probability of some medical test result given a disease. Like, I know that if someone has a disease, then x% of the time the medical test result will show up as this, for instance. And using that information, then I can calculate, all right, what is the probability that given I know the medical test result, what is the likelihood that someone has the disease? This is the piece of information that is usually easier to know, easier to immediately have access to data for. And this is the information that I actually want to calculate. Or I might want to know, for example, if I know that some probability of counterfeit bills have blurry text around the edges, because counterfeit printers aren’t nearly as good at printing text precisely. So I have some information about, given that something is a counterfeit bill, like x% of counterfeit bills have blurry text, for example. And using that information, then I can calculate some piece of information that I might want to know, like, given that I know there’s blurry text on a bill, what is the probability that that bill is counterfeit? So given one conditional probability, I can calculate the other conditional probability as well. And so now we’ve taken a look at a couple of different types of probability. And we’ve looked at unconditional probability, where I just look at what is the probability of this event occurring, given no additional evidence that I might have access to. And we’ve also looked at conditional probability, where I have some sort of evidence, and I would like to, using that evidence, be able to calculate some other probability as well. And the other kind of probability that will be important for us to think about is joint probability. And this is when we’re considering the likelihood of multiple different events simultaneously. And so what do we mean by this? For example, I might have probability distributions that look a little something like this. Like, oh, I want to know the probability distribution of clouds in the morning. And that distribution looks like this. 40% of the time, C, which is my random variable here, is equal to it’s cloudy. And 60% of the time, it’s not cloudy. So here is just a simple probability distribution that is effectively telling me that 40% of the time, it’s cloudy. I might also have a probability distribution for rain in the afternoon, where 10% of the time, or with probability 0.1, it is raining in the afternoon. And with probability 0.9, it is not raining in the afternoon. And using just these two pieces of information, I don’t actually have a whole lot of information about how these two variables relate to each other. But I could if I had access to their joint probability, meaning for every combination of these two things, meaning morning cloudy and afternoon rain, morning cloudy and afternoon not rain, morning not cloudy and afternoon rain, and morning not cloudy and afternoon not raining, if I had access to values for each of those four, I’d have more information. So information that’d be organized in a table like this, and this, rather than just a probability distribution, is a joint probability distribution. It tells me the probability distribution of each of the possible combinations of values that these random variables can take on. So if I want to know what is the probability that on any given day it is both cloudy and rainy, well, I would say, all right, we’re looking at cases where it is cloudy and cases where it is raining. And the intersection of those two, that row in that column, is 0.08. So that is the probability that it is both cloudy and rainy using that information. And using this conditional probability table, using this joint probability table, I can begin to draw other pieces of information about things like conditional probability. So I might ask a question like, what is the probability distribution of clouds given that I know that it is raining? Meaning I know for sure that it’s raining. Tell me the probability distribution over whether it’s cloudy or not, given that I know already that it is, in fact, raining. And here I’m using C to stand for that random variable. I’m looking for a distribution, meaning the answer to this is not going to be a single value. It’s going to be two values, a vector of two values, where the first value is probability of clouds, the second value is probability that it is not cloudy, but the sum of those two values is going to be 1. Because when you add up the probabilities of all of the possible worlds, the result that you get must be the number 1. And well, what do we know about how to calculate a conditional probability? Well, we know that the probability of A given B is the probability of A and B divided by the probability of B. So what does this mean? Well, it means that I can calculate the probability of clouds given that it’s raining as the probability of clouds and raining divided by the probability of rain. And this comma here for the probability distribution of clouds and rain, this comma sort of stands in for the word and. You’ll sort of see in the logical operator and and the comma used interchangeably. This means the probability distribution over the clouds and knowing the fact that it is raining divided by the probability of rain. And the interesting thing to note here and what we’ll often do in order to simplify our mathematics is that dividing by the probability of rain, the probability of rain here is just some numerical constant. It is some number. Dividing by probability of rain is just dividing by some constant, or in other words, multiplying by the inverse of that constant. And it turns out that oftentimes we can just not worry about what the exact value of this is and just know that it is, in fact, a constant value. And we’ll see why in a moment. So instead of expressing this as this joint probability divided by the probability of rain, sometimes we’ll just represent it as alpha times the numerator here, the probability distribution of C, this variable, and that we know that it is raining, for instance. So all we’ve done here is said this value of 1 over the probability of rain, that’s really just a constant we’re going to divide by or equivalently multiply by the inverse of at the end. We’ll just call it alpha for now and deal with it a little bit later. But the key idea here now, and this is an idea that’s going to come up again, is that the conditional distribution of C given rain is proportional to, meaning just some factor multiplied by the joint probability of C and rain being true. And so how do we figure this out? Well, this is going to be the probability that it is cloudy given that it’s raining, which is 0.08, and the probability that it’s not cloudy given that it’s raining, which is 0.02. And so we get alpha times here now is that probability distribution. 0.08 is clouds and rain. 0.02 is not cloudy and rain. But of course, 0.08 and 0.02 don’t sum up to the number 1. And we know that in a probability distribution, if you consider all of the possible values, they must sum up to a probability of 1. And so we know that we just need to figure out some constant to normalize, so to speak, these values, something we can multiply or divide by to get it so that all these probabilities sum up to 1, and it turns out that if we multiply both numbers by 10, then we can get that result of 0.8 and 0.2. The proportions are still equivalent, but now 0.8 plus 0.2, those sum up to the number 1. So take a look at this and see if you can understand step by step how it is we’re getting from one point to another. The key idea here is that by using the joint probabilities, these probabilities that it is both cloudy and rainy and that it is not cloudy and rainy, I can take that information and figure out the conditional probability given that it’s raining. What is the chance that it’s cloudy versus not cloudy? Just by multiplying by some normalization constant, so to speak. And this is what a computer can begin to use to be able to interact with these various different types of probabilities. And it turns out there are a number of other probability rules that are going to be useful to us as we begin to explore how we can actually use this information to encode into our computers some more complex analysis that we might want to do about probability and distributions and random variables that we might be interacting with. So here are a couple of those important probability rules. One of the simplest rules is just this negation rule. What is the probability of not event A? So A is an event that has some probability, and I would like to know what is the probability that A does not occur. And it turns out it’s just 1 minus P of A, which makes sense. Because if those are the two possible cases, either A happens or A doesn’t happen, then when you add up those two cases, you must get 1, which means that P of not A must just be 1 minus P of A. Because P of A and P of not A must sum up to the number 1. They must include all of the possible cases. We’ve seen an expression for calculating the probability of A and B. We might also reasonably want to calculate the probability of A or B. What is the probability that one thing happens or another thing happens? So for example, I might want to calculate what is the probability that if I roll two dice, a red die and a blue die, what is the likelihood that A is a 6 or B is a 6, like one or the other? And what you might imagine you could do, and the wrong way to approach it, would be just to say, all right, well, A comes up as a 6 with the red die comes up as a 6 with probability 1 over 6. The same for the blue die, it’s also 1 over 6. Add them together, and you get 2 over 6, otherwise known as 1 third. But this suffers from a problem of over counting, that we’ve double counted the case, where both A and B, both the red die and the blue die, both come up as a 6-roll. And I’ve counted that instance twice. So to resolve this, the actual expression for calculating the probability of A or B uses what we call the inclusion-exclusion formula. So I take the probability of A, add it to the probability of B. That’s all same as before. But then I need to exclude the cases that I’ve double counted. So I subtract from that the probability of A and B. And that gets me the result for A or B. I consider all the cases where A is true and all the cases where B is true. And if you imagine this is like a Venn diagram of cases where A is true, cases where B is true, I just need to subtract out the middle to get rid of the cases that I have overcounted by double counting them inside of both of these individual expressions. One other rule that’s going to be quite helpful is a rule called marginalization. So marginalization is answering the question of how do I figure out the probability of A using some other variable that I might have access to, like B? Even if I don’t know additional information about it, I know that B, some event, can have two possible states, either B happens or B doesn’t happen, assuming it’s a Boolean, true or false. And well, what that means is that for me to be able to calculate the probability of A, there are only two cases. Either A happens and B happens, or A happens and B doesn’t happen. And those are two disjoint, meaning they can’t both happen together. Either B happens or B doesn’t happen. They’re disjoint or separate cases. And so I can figure out the probability of A just by adding up those two cases. The probability that A is true is the probability that A and B is true, plus the probability that A is true and B isn’t true. So by marginalizing, I’ve looked at the two possible cases that might take place, either B happens or B doesn’t happen. And in either of those cases, I look at what’s the probability that A happens. And if I add those together, well, then I get the probability that A happens as a whole. So take a look at that rule. It doesn’t matter what B is or how it’s related to A. So long as I know these joint distributions, I can figure out the overall probability of A. And this can be a useful way if I have a joint distribution, like the joint distribution of A and B, to just figure out some unconditional probability, like the probability of A. And we’ll see examples of this soon as well. Now, sometimes these might not just be random, might not just be variables that are events that are like they happened or they didn’t happen, like B is here. They might be some broader probability distribution where there are multiple possible values. And so here, in order to use this marginalization rule, I need to sum up not just over B and not B, but for all of the possible values that the other random variable could take on. And so here, we’ll see a version of this rule for random variables. And it’s going to include that summation notation to indicate that I’m summing up, adding up a whole bunch of individual values. So here’s the rule. Looks a lot more complicated, but it’s actually the equivalent exactly the same rule. What I’m saying here is that if I have two random variables, one called x and one called y, well, the probability that x is equal to some value x sub i, this is just some value that this variable takes on. How do I figure it out? Well, I’m going to sum up over j, where j is going to range over all of the possible values that y can take on. Well, let’s look at the probability that x equals xi and y equals yj. So the exact same rule, the only difference here is now I’m summing up over all of the possible values that y can take on, saying let’s add up all of those possible cases and look at this joint distribution, this joint probability, that x takes on the value I care about, given all of the possible values for y. And if I add all those up, then I can get this unconditional probability of what x is equal to, whether or not x is equal to some value x sub i. So let’s take a look at this rule, because it does look a little bit complicated. Let’s try and put a concrete example to it. Here again is that same joint distribution from before. I have cloud, not cloudy, rainy, not rainy. And maybe I want to access some variable. I want to know what is the probability that it is cloudy. Well, marginalization says that if I have this joint distribution and I want to know what is the probability that it is cloudy, well, I need to consider the other variable, the variable that’s not here, the idea that it’s rainy. And I consider the two cases, either it’s raining or it’s not raining. And I just sum up the values for each of those possibilities. In other words, the probability that it is cloudy is equal to the sum of the probability that it’s cloudy and it’s rainy and the probability that it’s cloudy and it is not raining. And so these now are values that I have access to. These are values that are just inside of this joint probability table. What is the probability that it is both cloudy and rainy? Well, it’s just the intersection of these two here, which is 0.08. And the probability that it’s cloudy and not raining is, all right, here’s cloudy, here’s not raining. It’s 0.32. So it’s 0.08 plus 0.32, which just gives us equal to 0.4. That is the unconditional probability that it is, in fact, cloudy. And so marginalization gives us a way to go from these joint distributions to just some individual probability that I might care about. And you’ll see a little bit later why it is that we care about that and why that’s actually useful to us as we begin doing some of these calculations. Last rule we’ll take a look at before transitioning to something a little bit different is this rule of conditioning, very similar to the marginalization rule. But it says that, again, if I have two events, a and b, but instead of having access to their joint probabilities, I have access to their conditional probabilities, how they relate to each other. Well, again, if I want to know the probability that a happens, and I know that there’s some other variable b, either b happens or b doesn’t happen, and so I can say that the probability of a is the probability of a given b times the probability of b, meaning b happened. And given that I know b happened, what’s the likelihood that a happened? And then I consider the other case, that b didn’t happen. So here’s the probability that b didn’t happen. And here’s the probability that a happens, given that I know that b didn’t happen. And this is really the equivalent rule just using conditional probability instead of joint probability, where I’m saying let’s look at both of these two cases and condition on b. Look at the case where b happens, and look at the case where b doesn’t happen, and look at what probabilities I get as a result. And just as in the case of marginalization, where there was an equivalent rule for random variables that could take on multiple possible values in a domain of possible values, here, too, conditioning has the same equivalent rule. Again, there’s a summation to mean I’m summing over all of the possible values that some random variable y could take on. But if I want to know what is the probability that x takes on this value, then I’m going to sum up over all the values j that y could take on, and say, all right, what’s the chance that y takes on that value yj? And multiply it by the conditional probability that x takes on this value, given that y took on that value yj. So equivalent rule just using conditional probabilities instead of joint probabilities. And using the equation we know about joint probabilities, we can translate between these two. So all right, we’ve seen a whole lot of mathematics, and we’ve just laid the foundation for mathematics. And no need to worry if you haven’t seen probability in too much detail up until this point. These are the foundations of the ideas that are going to come up as we begin to explore how we can now take these ideas from probability and begin to apply them to represent something inside of our computer, something inside of the AI agent we’re trying to design that is able to represent information and probabilities and the likelihoods between various different events. So there are a number of different probabilistic models that we can generate, but the first of the models we’re going to talk about are what are known as Bayesian networks. And a Bayesian network is just going to be some network of random variables, connected random variables that are going to represent the dependence between these random variables. The odds are most random variables in this world are not independent from each other, but there’s some relationship between things that are happening that we care about. If it is rainy today, that might increase the likelihood that my flight or my train gets delayed, for example. There are some dependence between these random variables, and a Bayesian network is going to be able to capture those dependencies. So what is a Bayesian network? What is its actual structure, and how does it work? Well, a Bayesian network is going to be a directed graph. And again, we’ve seen directed graphs before. They are individual nodes with arrows or edges that connect one node to another node pointing in a particular direction. And so this directed graph is going to have nodes as well, where each node in this directed graph is going to represent a random variable, something like the weather, or something like whether my train was on time or delayed. And we’re going to have an arrow from a node x to a node y to mean that x is a parent of y. So that’ll be our notation. If there’s an arrow from x to y, x is going to be considered a parent of y. And the reason that’s important is because each of these nodes is going to have a probability distribution that we’re going to store along with it, which is the distribution of x given some evidence, given the parents of x. So the way to more intuitively think about this is the parents seem to be thought of as sort of causes for some effect that we’re going to observe. And so let’s take a look at an actual example of a Bayesian network and think about the types of logic that might be involved in reasoning about that network. Let’s imagine for a moment that I have an appointment out of town, and I need to take a train in order to get to that appointment. So what are the things I might care about? Well, I care about getting to my appointment on time. Whether I make it to my appointment and I’m able to attend it or I miss the appointment. And you might imagine that that’s influenced by the train, that the train is either on time or it’s delayed, for example. But that train itself is also influenced. Whether the train is on time or not depends maybe on the rain. Is there no rain? Is it light rain? Is there heavy rain? And it might also be influenced by other variables too. It might be influenced as well by whether or not there’s maintenance on the train track, for example. If there is maintenance on the train track, that probably increases the likelihood that my train is delayed. And so we can represent all of these ideas using a Bayesian network that looks a little something like this. Here I have four nodes representing four random variables that I would like to keep track of. I have one random variable called rain that can take on three possible values in its domain, either none or light or heavy, for no rain, light rain, or heavy rain. I have a variable called maintenance for whether or not there is maintenance on the train track, which it has two possible values, just either yes or no. Either there is maintenance or there’s no maintenance happening on the track. Then I have a random variable for the train indicating whether or not the train was on time or not. That random variable has two possible values in its domain. The train is either on time or the train is delayed. And then finally, I have a random variable for whether I make it to my appointment. For my appointment down here, I have a random variable called appointment that itself has two possible values, attend and miss. And so here are the possible values. Here are my four nodes, each of which represents a random variable, each of which has a domain of possible values that it can take on. And the arrows, the edges pointing from one node to another, encode some notion of dependence inside of this graph, that whether I make it to my appointment or not is dependent upon whether the train is on time or delayed. And whether the train is on time or delayed is dependent on two things given by the two arrows pointing at this node. It is dependent on whether or not there was maintenance on the train track. And it is also dependent upon whether or not it was raining or whether it is raining. And just to make things a little complicated, let’s say as well that whether or not there is maintenance on the track, this too might be influenced by the rain. That if there’s heavier rain, well, maybe it’s less likely that it’s going to be maintenance on the train track that day because they’re more likely to want to do maintenance on the track on days when it’s not raining, for example. And so these nodes might have different relationships between them. But the idea is that we can come up with a probability distribution for any of these nodes based only upon its parents. And so let’s look node by node at what this probability distribution might actually look like. And we’ll go ahead and begin with this root node, this rain node here, which is at the top, and has no arrows pointing into it, which means its probability distribution is not going to be a conditional distribution. It’s not based on anything. I just have some probability distribution over the possible values for the rain random variable. And that distribution might look a little something like this. None, light and heavy, each have a possible value. Here I’m saying the likelihood of no rain is 0.7, of light rain is 0.2, of heavy rain is 0.1, for example. So here is a probability distribution for this root node in this Bayesian network. And let’s now consider the next node in the network, maintenance. Track maintenance is yes or no. And the general idea of what this distribution is going to encode, at least in this story, is the idea that the heavier the rain is, the less likely it is that there’s going to be maintenance on the track. Because the people that are doing maintenance on the track probably want to wait until a day when it’s not as rainy in order to do the track maintenance, for example. And so what might that probability distribution look like? Well, this now is going to be a conditional probability distribution, that here are the three possible values for the rain random variable, which I’m here just going to abbreviate to R, either no rain, light rain, or heavy rain. And for each of those possible values, either there is yes track maintenance or no track maintenance. And those have probabilities associated with them. That I see here that if it is not raining, then there is a probability of 0.4 that there’s track maintenance and a probability of 0.6 that there isn’t. But if there’s heavy rain, then here the chance that there is track maintenance is 0.1 and the chance that there is not track maintenance is 0.9. Each of these rows is going to sum up to 1. Because each of these represent different values of whether or not it’s raining, the three possible values that that random variable can take on. And each is associated with its own probability distribution that is ultimately all going to add up to the number 1. So that there is our distribution for this random variable called maintenance, about whether or not there is maintenance on the train track. And now let’s consider the next variable. Here we have a node inside of our Bayesian network called train that has two possible values, on time and delayed. And this node is going to be dependent upon the two nodes that are pointing towards it, that whether or not the train is on time or delayed depends on whether or not there is track maintenance. And it depends on whether or not there is rain, that heavier rain probably means more likely that my train is delayed. And if there is track maintenance, that also probably means it’s more likely that my train is delayed as well. And so you could construct a larger probability distribution, a conditional probability distribution, that instead of conditioning on just one variable, as was the case here, is now conditioning on two variables, conditioning both on rain represented by r and on maintenance represented by yes. Again, each of these rows has two values that sum up to the number 1, one for whether the train is on time, one for whether the train is delayed. And here I can say something like, all right, if I know there was light rain and track maintenance, well, OK, that would be r is light and m is yes. Well, then there is a probability of 0.6 that my train is on time, and a probability of 0.4 the train is delayed. And you can imagine gathering this data just by looking at real world data, looking at data about, all right, if I knew that it was light rain and there was track maintenance, how often was a train delayed or not delayed? And you could begin to construct this thing. The interesting thing is intelligently, being able to try to figure out how might you go about ordering these things, what things might influence other nodes inside of this Bayesian network. And the last thing I care about is whether or not I make it to my appointment. So did I attend or miss the appointment? And ultimately, whether I attend or miss the appointment, it is influenced by track maintenance, because it’s indirectly this idea that, all right, if there is track maintenance, well, then my train might more likely be delayed. And if my train is more likely to be delayed, then I’m more likely to miss my appointment. But what we encode in this Bayesian network are just what we might consider to be more direct relationships. So the train has a direct influence on the appointment. And given that I know whether the train is on time or delayed, knowing whether there’s track maintenance isn’t going to give me any additional information that I didn’t already have. That if I know train, these other nodes that are up above isn’t really going to influence the result. And so here we might represent it using another conditional probability distribution that looks a little something like this. The train can take on two possible values. Either my train is on time or my train is delayed. And for each of those two possible values, I have a distribution for what are the odds that I’m able to attend the meeting and what are the odds that I missed the meeting. And obviously, if my train is on time, I’m much more likely to be able to attend the meeting than if my train is delayed, in which case I’m more likely to miss that meeting. So all of these nodes put all together here represent this Bayesian network, this network of random variables whose values I ultimately care about, and that have some sort of relationship between them, some sort of dependence where these arrows from one node to another indicate some dependence, that I can calculate the probability of some node given the parents that happen to exist there. So now that we’ve been able to describe the structure of this Bayesian network and the relationships between each of these nodes by associating each of the nodes in the network with a probability distribution, whether that’s an unconditional probability distribution in the case of this root node here, like rain, and a conditional probability distribution in the case of all of the other nodes whose probabilities are dependent upon the values of their parents, we can begin to do some computation and calculation using the information inside of that table. So let’s imagine, for example, that I just wanted to compute something simple like the probability of light rain. How would I get the probability of light rain? Well, light rain, rain here is a root node. And so if I wanted to calculate that probability, I could just look at the probability distribution for rain and extract from it the probability of light rains, just a single value that I already have access to. But we could also imagine wanting to compute more complex joint probabilities, like the probability that there is light rain and also no track maintenance. This is a joint probability of two values, light rain and no track maintenance. And the way I might do that is first by starting by saying, all right, well, let me get the probability of light rain. But now I also want the probability of no track maintenance. But of course, this node is dependent upon the value of rain. So what I really want is the probability of no track maintenance, given that I know that there was light rain. And so the expression for calculating this idea that the probability of light rain and no track maintenance is really just the probability of light rain and the probability that there is no track maintenance, given that I know that there already is light rain. So I take the unconditional probability of light rain, multiply it by the conditional probability of no track maintenance, given that I know there is light rain. And you can continue to do this again and again for every variable that you want to add into this joint probability that I might want to calculate. If I wanted to know the probability of light rain and no track maintenance and a delayed train, well, that’s going to be the probability of light rain, multiplied by the probability of no track maintenance, given light rain, multiplied by the probability of a delayed train, given light rain and no track maintenance. Because whether the train is on time or delayed is dependent upon both of these other two variables. And so I have two pieces of evidence that go into the calculation of that conditional probability. And each of these three values is just a value that I can look up by looking at one of these individual probability distributions that is encoded into my Bayesian network. And if I wanted a joint probability over all four of the variables, something like the probability of light rain and no track maintenance and a delayed train and I miss my appointment, well, that’s going to be multiplying four different values, one from each of these individual nodes. It’s going to be the probability of light rain, then of no track maintenance given light rain, then of a delayed train, given light rain and no track maintenance. And then finally, for this node here, for whether I make it to my appointment or not, it’s not dependent upon these two variables, given that I know whether or not the train is on time. I only need to care about the conditional probability that I miss my train, or that I miss my appointment, given that the train happens to be delayed. And so that’s represented here by four probabilities, each of which is located inside of one of these probability distributions for each of the nodes, all multiplied together. And so I can take a variable like that and figure out what the joint probability is by multiplying a whole bunch of these individual probabilities from the Bayesian network. But of course, just as with last time, where what I really wanted to do was to be able to get new pieces of information, here, too, this is what we’re going to want to do with our Bayesian network. In the context of knowledge, we talked about the problem of inference. Given things that I know to be true, can I draw conclusions, make deductions about other facts about the world that I also know to be true? And what we’re going to do now is apply the same sort of idea to probability. Using information about which I have some knowledge, whether some evidence or some probabilities, can I figure out not other variables for certain, but can I figure out the probabilities of other variables taking on particular values? And so here, we introduce the problem of inference in a probabilistic setting, in a case where variables might not necessarily be true for sure, but they might be random variables that take on different values with some probability. So how do we formally define what exactly this inference problem actually is? Well, the inference problem has a couple of parts to it. We have some query, some variable x that we want to compute the distribution for. Maybe I want the probability that I miss my train, or I want the probability that there is track maintenance, something that I want information about. And then I have some evidence variables. Maybe it’s just one piece of evidence. Maybe it’s multiple pieces of evidence. But I’ve observed certain variables for some sort of event. So for example, I might have observed that it is raining. This is evidence that I have. I know that there is light rain, or I know that there is heavy rain. And that is evidence I have. And using that evidence, I want to know what is the probability that my train is delayed, for example. And that is a query that I might want to ask based on this evidence. So I have a query, some variable. Evidence, which are some other variables that I have observed inside of my Bayesian network. And of course, that does leave some hidden variables. Why? These are variables that are not evidence variables and not query variables. So you might imagine in the case where I know whether or not it’s raining, and I want to know whether my train is going to be delayed or not, the hidden variable, the thing I don’t have access to, is something like, is there maintenance on the track? Or am I going to make or not make my appointment, for example? These are variables that I don’t have access to. They’re hidden because they’re not things I observed, and they’re also not the query, the thing that I’m asking. And so ultimately, what we want to calculate is I want to know the probability distribution of x given e, the event that I observed. So given that I observed some event, I observed that it is raining, I would like to know what is the distribution over the possible values of the train random variable. Is it on time? Is it delayed? What’s the likelihood it’s going to be there? And it turns out we can do this calculation just using a lot of the probability rules that we’ve already seen in action. And ultimately, we’re going to take a look at the math at a little bit of a high level, at an abstract level. But ultimately, we can allow computers and programming libraries that already exist to begin to do some of this math for us. But it’s good to get a general sense for what’s actually happening when this inference process takes place. Let’s imagine, for example, that I want to compute the probability distribution of the appointment random variable given some evidence, given that I know that there was light rain and no track maintenance. So there’s my evidence, these two variables that I observe the values of. I observe the value of rain. I know there’s light rain. And I know that there is no track maintenance going on today. And what I care about knowing, my query, is this random variable appointment. I want to know the distribution of this random variable appointment, like what is the chance that I’m able to attend my appointment? What is the chance that I miss my appointment given this evidence? And the hidden variable, the information that I don’t have access to, is this variable train. This is information that is not part of the evidence that I see, not something that I observe. But it is also not the query that I’m asking for. And so what might this inference procedure look like? Well, if you recall back from when we were defining conditional probability and doing math with conditional probabilities, we know that a conditional probability is proportional to the joint probability. And we remembered this by recalling that the probability of A given B is just some constant factor alpha multiplied by the probability of A and B. That constant factor alpha turns out to be like dividing over the probability of B. But the important thing is that it’s just some constant multiplied by the joint distribution, the probability that all of these individual things happen. So in this case, I can take the probability of the appointment random variable given light rain and no track maintenance and say that is just going to be proportional, some constant alpha, multiplied by the joint probability, the probability of a particular value for the appointment random variable and light rain and no track maintenance. Well, all right, how do I calculate this, probability of appointment and light rain and no track maintenance, when what I really care about is knowing I need all four of these values to be able to calculate a joint distribution across everything because in a particular appointment depends upon the value of train? Well, in order to do that, here I can begin to use that marginalization trick, that there are only two ways I can get any configuration of an appointment, light rain, and no track maintenance. Either this particular setting of variables happens and the train is on time, or this particular setting of variables happens and the train is delayed. Those are two possible cases that I would want to consider. And if I add those two cases up, well, then I get the result just by adding up all of the possibilities for the hidden variable or variables that there are multiple. But since there’s only one hidden variable here, train, all I need to do is iterate over all the possible values for that hidden variable train and add up their probabilities. So this probability expression here becomes probability distribution over appointment, light, no rain, and train is on time, and the probability distribution over the appointment, light rain, no track maintenance, and that the train is delayed, for example. So I take both of the possible values for train, go ahead and add them up. These are just joint probabilities that we saw earlier, how to calculate just by going parent, parent, parent, parent, and calculating those probabilities and multiplying them together. And then you’ll need to normalize them at the end, speaking at a high level, to make sure that everything adds up to the number 1. So the formula for how you do this in a process known as inference by enumeration looks a little bit complicated, but ultimately it looks like this. And let’s now try to distill what it is that all of these symbols actually mean. Let’s start here. What I care about knowing is the probability of x, my query variable, given some sort of evidence. What do I know about conditional probabilities? Well, a conditional probability is proportional to the joint probability. So it is some alpha, some normalizing constant, multiplied by this joint probability of x and evidence. And how do I calculate that? Well, to do that, I’m going to marginalize over all of the hidden variables, all the variables that I don’t directly observe the values for. I’m basically going to iterate over all of the possibilities that it could happen and just sum them all up. And so I can translate this into a sum over all y, which ranges over all the possible hidden variables and the values that they could take on, and adds up all of those possible individual probabilities. And that is going to allow me to do this process of inference by enumeration. Now, ultimately, it’s pretty annoying if we as humans have to do all this math for ourselves. But turns out this is where computers and AI can be particularly helpful, that we can program a computer to understand a Bayesian network, to be able to understand these inference procedures, and to be able to do these calculations. And using the information you’ve seen here, you could implement a Bayesian network from scratch yourself. But turns out there are a lot of libraries, especially written in Python, that allow us to make it easier to do this sort of probabilistic inference, to be able to take a Bayesian network and do these sorts of calculations, so that you don’t need to know and understand all of the underlying math, though it’s helpful to have a general sense for how it works. But you just need to be able to describe the structure of the network and make queries in order to be able to produce the result. And so let’s take a look at an example of that right now. It turns out that there are a lot of possible libraries that exist in Python for doing this sort of inference. It doesn’t matter too much which specific library you use. They all behave in fairly similar ways. But the library I’m going to use here is one known as pomegranate. And here inside of model.py, I have defined a Bayesian network, just using the structure and the syntax that the pomegranate library expects. And what I’m effectively doing is just, in Python, creating nodes to represent each of the nodes of the Bayesian network that you saw me describe a moment ago. So here on line four, after I’ve imported pomegranate, I’m defining a variable called rain that is going to represent a node inside of my Bayesian network. It’s going to be a node that follows this distribution, where there are three possible values, none for no rain, light for light rain, heavy for heavy rain. And these are the probabilities of each of those taking place. 0.7 is the likelihood of no rain, 0.2 for light rain, 0.1 for heavy rain. Then after that, we go to the next variable, the variable for track maintenance, for example, which is dependent upon that rain variable. And this, instead of being an unconditional distribution, is a conditional distribution, as indicated by a conditional probability table here. And the idea is that I’m following this is conditional on the distribution of rain. So if there is no rain, then the chance that there is, yes, track maintenance is 0.4. If there’s no rain, the chance that there is no track maintenance is 0.6. Likewise, for light rain, I have a distribution. For heavy rain, I have a distribution as well. But I’m effectively encoding the same information you saw represented graphically a moment ago. But I’m telling this Python program that the maintenance node obeys this particular conditional probability distribution. And we do the same thing for the other random variables as well. Train was a node inside my distribution that was a conditional probability table with two parents. It was dependent not only on rain, but also on track maintenance. And so here I’m saying something like, given that there is no rain and, yes, track maintenance, the probability that my train is on time is 0.8. And the probability that it’s delayed is 0.2. And likewise, I can do the same thing for all of the other possible values of the parents of the train node inside of my Bayesian network by saying, for all of those possible values, here is the distribution that the train node should follow. Then I do the same thing for an appointment based on the distribution of the variable train. Then at the end, what I do is actually construct this network by describing what the states of the network are and by adding edges between the dependent nodes. So I create a new Bayesian network, add states to it, one for rain, one for maintenance, one for the train, one for the appointment. And then I add edges connecting the related pieces. Rain has an arrow to maintenance because rain influences track maintenance. Rain also influences the train. Maintenance also influences the train. And train influences whether I make it to my appointment and bake just finalizes the model and does some additional computation. So the specific syntax of this is not really the important part. Pomegranate just happens to be one of several different libraries that can all be used for similar purposes. And you could describe and define a library for yourself that implemented similar things. But the key idea here is that someone can design a library for a general Bayesian network that has nodes that are based upon its parents. And then all a programmer needs to do using one of those libraries is to define what those nodes and what those probability distributions are. And we can begin to do some interesting logic based on it. So let’s try doing that conditional or joint probability calculation that we saw us do by hand before by going into likelihood.py, where here I’m importing the model that I just defined a moment ago. And here I’d just like to calculate model.probability, which calculates the probability for a given observation. And I’d like to calculate the probability of no rain, no track maintenance, my train is on time, and I’m able to attend the meeting. So sort of the optimal scenario that there is no rain and no maintenance on the track, my train is on time, and I’m able to attend the meeting. What is the probability that all of that actually happens? And I can calculate that using the library and just print out its probability. And so I’ll go ahead and run python of likelihood.py. And I see that, OK, the probability is about 0.34. So about a third of the time, everything goes right for me in this case. No rain, no track maintenance, train is on time, and I’m able to attend the meeting. But I could experiment with this, try and calculate other probabilities as well. What’s the probability that everything goes right up until the train, but I still miss my meeting? So no rain, no track maintenance, train is on time, but I miss the appointment. Let’s calculate that probability. And all right, that has a probability of about 0.04. So about 4% of the time, the train will be on time, there won’t be any rain, no track maintenance, and yet I’ll still miss the meeting. And so this is really just an implementation of the calculation of the joint probabilities that we did before. What this library is likely doing is first figuring out the probability of no rain, then figuring out the probability of no track maintenance given no rain, then the probability that my train is on time given both of these values, and then the probability that I miss my appointment given that I know that the train was on time. So this, again, is the calculation of that joint probability. And turns out we can also begin to have our computer solve inference problems as well, to begin to infer, based on information, evidence that we see, what is the likelihood of other variables also being true. So let’s go into inference.py, for example. We’re here, I’m again importing that exact same model from before, importing all the nodes and all the edges and the probability distribution that is encoded there as well. And now there’s a function for doing some sort of prediction. And here, into this model, I pass in the evidence that I observe. So here, I’ve encoded into this Python program the evidence that I have observed. I have observed the fact that the train is delayed. And that is the value for one of the four random variables inside of this Bayesian network. And using that information, I would like to be able to draw inspiration and figure out inferences about the values of the other random variables that are inside of my Bayesian network. I would like to make predictions about everything else. So all of the actual computational logic is happening in just these three lines, where I’m making this call to this prediction. Down below, I’m just iterating over all of the states and all the predictions and just printing them out so that we can visually see what the results are. But let’s find out, given the train is delayed, what can I predict about the values of the other random variables? Let’s go ahead and run python inference.py. I run that, and all right, here is the result that I get. Given the fact that I know that the train is delayed, this is evidence that I have observed. Well, given that there is a 45% chance or a 46% chance that there was no rain, a 31% chance there was light rain, a 23% chance there was heavy rain, I can see a probability distribution of a track maintenance and a probability distribution over whether I’m able to attend or miss my appointment. Now, we know that whether I attend or miss the appointment, that is only dependent upon the train being delayed or not delayed. It shouldn’t depend on anything else. So let’s imagine, for example, that I knew that there was heavy rain. That shouldn’t affect the distribution for making the appointment. And indeed, if I go up here and add some evidence, say that I know that the value of rain is heavy. That is evidence that I now have access to. I now have two pieces of evidence. I know that the rain is heavy, and I know that my train is delayed. I can calculate the probability by running this inference procedure again and seeing the result. I know that the rain is heavy. I know my train is delayed. The probability distribution for track maintenance changed. Given that I know that there’s heavy rain, now it’s more likely that there is no track maintenance, 88%, as opposed to 64% from here before. And now, what is the probability that I make the appointment? Well, that’s the same as before. It’s still going to be attend the appointment with probability 0.6, missed the appointment with probability 0.4, because it was only dependent upon whether or not my train was on time or delayed. And so this here is implementing that idea of that inference algorithm to be able to figure out, based on the evidence that I have, what can we infer about the values of the other variables that exist as well. So inference by enumeration is one way of doing this inference procedure, just looping over all of the values the hidden variables could take on and figuring out what the probability is. Now, it turns out this is not particularly efficient. And there are definitely optimizations you can make by avoiding repeated work. If you’re calculating the same sort of probability multiple times, there are ways of optimizing the program to avoid having to recalculate the same probabilities again and again. But even then, as the number of variables get large, as the number of possible values of variables could take on, get large, we’re going to start to have to do a lot of computation, a lot of calculation, to be able to do this inference. And at that point, it might start to get unreasonable, in terms of the amount of time that it would take to be able to do this sort of exact inference. And it’s for that reason that oftentimes, when it comes towards probability and things we’re not entirely sure about, we don’t always care about doing exact inference and knowing exactly what the probability is. But if we can approximate the inference procedure, do some sort of approximate inference, that that can be pretty good as well. That if I don’t know the exact probability, but I have a general sense for the probability that I can get increasingly accurate with more time, that that’s probably pretty good, especially if I can get that to happen even faster. So how could I do approximate inference inside of a Bayesian network? Well, one method is through a procedure known as sampling. In the process of sampling, I’m going to take a sample of all of the variables inside of this Bayesian network here. And how am I going to sample? Well, I’m going to sample one of the values from each of these nodes according to their probability distribution. So how might I take a sample of all these nodes? Well, I’ll start at the root. I’ll start with rain. Here’s the distribution for rain. And I’ll go ahead and, using a random number generator or something like it, randomly pick one of these three values. I’ll pick none with probability 0.7, light with probability 0.2, and heavy with probability 0.1. So I’ll randomly just pick one of them according to that distribution. And maybe in this case, I pick none, for example. Then I do the same thing for the other variable. Maintenance also has a probability distribution. And I’m going to sample. Now, there are three probability distributions here. But I’m only going to sample from this first row here, because I’ve observed already in my sample that the value of rain is none. So given that rain is none, I’m going to sample from this distribution to say, all right, what should the value of maintenance be? And in this case, maintenance is going to be, let’s just say yes, which happens 40% of the time in the event that there is no rain, for example. And we’ll sample all of the rest of the nodes in this way as well, that I want to sample from the train distribution. And I’ll sample from this first row here, where there is no rain, but there is track maintenance. And I’ll sample 80% of the time. I’ll say the train is on time. 20% of the time, I’ll say the train is delayed. And finally, we’ll do the same thing for whether I make it to my appointment or not. Did I attend or miss the appointment? We’ll sample based on this distribution and maybe say that in this case, I attend the appointment, which happens 90% of the time when the train is actually on time. So by going through these nodes, I can very quickly just do some sampling and get a sample of the possible values that could come up from going through this entire Bayesian network according to those probability distributions. And where this becomes powerful is if I do this not once, but I do this thousands or tens of thousands of times and generate a whole bunch of samples all using this distribution. I get different samples. Maybe some of them are the same. But I get a value for each of the possible variables that could come up. And so then if I’m ever faced with a question, a question like, what is the probability that the train is on time, you could do an exact inference procedure. This is no different than the inference problem we had before where I could just marginalize, look at all the possible other values of the variables, and do the computation of inference by enumeration to find out this probability exactly. But I could also, if I don’t care about the exact probability, just sample it, approximate it to get close. And this is a powerful tool in AI where we don’t need to be right 100% of the time or we don’t need to be exactly right. If we just need to be right with some probability, we can often do so more effectively, more efficiently. And so if here now are all of those possible samples, I’ll highlight the ones where the train is on time. I’m ignoring the ones where the train is delayed. And in this case, there’s like six out of eight of the samples have the train is arriving on time. And so maybe in this case, I can say that in six out of eight cases, that’s the likelihood that the train is on time. And with eight samples, that might not be a great prediction. But if I had thousands upon thousands of samples, then this could be a much better inference procedure to be able to do these sorts of calculations. So this is a direct sampling method to just do a bunch of samples and then figure out what the probability of some event is. Now, this from before was an unconditional probability. What is the probability that the train is on time? And I did that by looking at all the samples and figuring out, right, here are the ones where the train is on time. But sometimes what I want to calculate is not an unconditional probability, but rather a conditional probability, something like what is the probability that there is light rain, given that the train is on time, something to that effect. And to do that kind of calculation, well, what I might do is here are all the samples that I have. And I want to calculate a probability distribution, given that I know that the train is on time. So to be able to do that, I can kind of look at the two cases where the train was delayed and ignore or reject them, sort of exclude them from the possible samples that I’m considering. And now I want to look at these remaining cases where the train is on time. Here are the cases where there is light rain. And I say, OK, these are two out of the six possible cases. That can give me an approximation for the probability of light rain, given the fact that I know the train was on time. And I did that in almost exactly the same way, just by adding an additional step, by saying that, all right, when I take each sample, let me reject all of the samples that don’t match my evidence and only consider the samples that do match what it is that I have in my evidence that I want to make some sort of calculation about. And it turns out, using the libraries that we’ve had for Bayesian networks, we can begin to implement this same sort of idea, like implement rejection sampling, which is what this method is called, to be able to figure out some probability, not via direct inference, but instead by sampling. So what I have here is a program called sample.py. Imports the exact same model. And what I define first is a program to generate a sample. And the way I generate a sample is just by looping over all of the states. The states need to be in some sort of order to make sure I’m looping in the correct order. But effectively, if it is a conditional distribution, I’m going to sample based on the parents. And otherwise, I’m just going to directly sample the variable, like rain, which has no parents. It’s just an unconditional distribution and keep track of all those parent samples and return the final sample. The exact syntax of this, again, not particularly important. It just happens to be part of the implementation details of this particular library. The interesting logic is down below. Now that I have the ability to generate a sample, if I want to know the distribution of the appointment random variable, given that the train is delayed, well, then I can begin to do calculations like this. Let me take 10,000 samples and assemble all my results in this list called data. I’ll go ahead and loop n times, in this case, 10,000 times. I’ll generate a sample. And I want to know the distribution of appointment, given that the train is delayed. So according to rejection sampling, I’m only going to consider samples where the train is delayed. If the train is not delayed, I’m not going to consider those values at all. So I’m going to say, all right, if I take the sample, look at the value of the train random variable, if the train is delayed, well, let me go ahead and add to my data that I’m collecting the value of the appointment random variable that it took on in this particular sample. So I’m only considering the samples where the train is delayed. And for each of those samples, considering what the value of appointment is, and then at the end, I’m using a Python class called counter, which quickly counts up all the values inside of a data set. So I can take this list of data and figure out how many times was my appointment made and how many times was my appointment missed. And so this here, with just a couple lines of code, is an implementation of rejection sampling. And I can run it by going ahead and running Python sample.py. And when I do that, here is the result I get. This is the result of the counter. 1,251 times, I was able to attend the meeting. And 856 times, I was able to miss the meeting. And you can imagine, by doing more and more samples, I’ll be able to get a better and better, more accurate result. And this is a randomized process. It’s going to be an approximation of the probability. If I run it a different time, you’ll notice the numbers are similar, 12, 72, and 905. But they’re not identical because there’s some randomization, some likelihood that things might be higher or lower. And so this is why we generally want to try and use more samples so that we can have a greater amount of confidence in our result, be more sure about the result that we’re getting of whether or not it accurately reflects or represents the actual underlying probabilities that are inherent inside of this distribution. And so this, then, was an instance of rejection sampling. And it turns out there are a number of other sampling methods that you could use to begin to try to sample. One problem that rejection sampling has is that if the evidence you’re looking for is a fairly unlikely event, well, you’re going to be rejecting a lot of samples. Like if I’m looking for the probability of x given some evidence e, if e is very unlikely to occur, like occurs maybe one every 1,000 times, then I’m only going to be considering 1 out of every 1,000 samples that I do, which is a pretty inefficient method for trying to do this sort of calculation. I’m throwing away a lot of samples. And it takes computational effort to be able to generate those samples. So I’d like to not have to do something like that. So there are other sampling methods that can try and address this. One such sampling method is called likelihood weighting. In likelihood weighting, we follow a slightly different procedure. And the goal is to avoid needing to throw out samples that didn’t match the evidence. And so what we’ll do is we’ll start by fixing the values for the evidence variables. Rather than sample everything, we’re going to fix the values of the evidence variables and not sample those. Then we’re going to sample all the other non-evidence variables in the same way, just using the Bayesian network looking at the probability distributions, sampling all the non-evidence variables. But then what we need to do is weight each sample by its likelihood. If our evidence is really unlikely, we want to make sure that we’ve taken into account how likely was the evidence to actually show up in the sample. If I have a sample where the evidence was much more likely to show up than another sample, then I want to weight the more likely one higher. So we’re going to weight each sample by its likelihood, where likelihood is just defined as the probability of all the evidence. Given all the evidence we have, what is the probability that it would happen in that particular sample? So before, all of our samples were weighted equally. They all had a weight of 1 when we were calculating the overall average. In this case, we’re going to weight each sample, multiply each sample by its likelihood in order to get the more accurate distribution. So what would this look like? Well, if I ask the same question, what is the probability of light rain, given that the train is on time, when I do the sampling procedure and start by trying to sample, I’m going to start by fixing the evidence variable. I’m already going to have in my sample the train is on time. That way, I don’t have to throw out anything. I’m only sampling things where I know the value of the variables that are my evidence are what I expect them to be. So I’ll go ahead and sample from rain. And maybe this time, I sample light rain instead of no rain. Then I’ll sample from track maintenance and say, maybe, yes, there’s track maintenance. Then for train, well, I’ve already fixed it in place. Train was an evidence variable. So I’m not going to bother sampling again. I’ll just go ahead and move on. I’ll move on to appointment and go ahead and sample from appointment as well. So now I’ve generated a sample. I’ve generated a sample by fixing this evidence variable and sampling the other three. And the last step is now weighting the sample. How much weight should it have? And the weight is based on how probable is it that the train was actually on time, this evidence actually happened, given the values of these other variables, light rain and the fact that, yes, there was track maintenance. Well, to do that, I can just go back to the train variable and say, all right, if there was light rain and track maintenance, the likelihood of my evidence, the likelihood that my train was on time, is 0.6. And so this particular sample would have a weight of 0.6. And I could repeat the sampling procedure again and again. Each time every sample would be given a weight according to the probability of the evidence that I see associated with it. And there are other sampling methods that exist as well, but all of them are designed to try and get it the same idea, to approximate the inference procedure of figuring out the value of a variable. So we’ve now dealt with probability as it pertains to particular variables that have these discrete values. But what we haven’t really considered is how values might change over time. That we’ve considered something like a variable for rain, where rain can take on values of none or light rain or heavy rain. But in practice, usually when we consider values for variables like rain, we like to consider it for over time, how do the values of these variables change? What do we do with when we’re dealing with uncertainty over a period of time, which can come up in the context of weather, for example, if I have sunny days and I have rainy days. And I’d like to know not just what is the probability that it’s raining now, but what is the probability that it rains tomorrow, or the day after that, or the day after that. And so to do this, we’re going to introduce a slightly different kind of model. But here, we’re going to have a random variable, not just one for the weather, but for every possible time step. And you can define time step however you like. A simple way is just to use days as your time step. And so we can define a variable called x sub t, which is going to be the weather at time t. So x sub 0 might be the weather on day 0. x sub 1 might be the weather on day 1, so on and so forth. x sub 2 is the weather on day 2. But as you can imagine, if we start to do this over longer and longer periods of time, there’s an incredible amount of data that might go into this. If you’re keeping track of data about the weather for a year, now suddenly you might be trying to predict the weather tomorrow, given 365 days of previous pieces of evidence. And that’s a lot of evidence to have to deal with and manipulate and calculate. Probably nobody knows what the exact conditional probability distribution is for all of those combinations of variables. And so when we’re trying to do this inference inside of a computer, when we’re trying to reasonably do this sort of analysis, it’s helpful to make some simplifying assumptions, some assumptions about the problem that we can just assume are true, to make our lives a little bit easier. Even if they’re not totally accurate assumptions, if they’re close to accurate or approximate, they’re usually pretty good. And the assumption we’re going to make is called the Markov assumption, which is the assumption that the current state depends only on a finite fixed number of previous states. So the current day’s weather depends not on all the previous day’s weather for the rest of all of history, but the current day’s weather I can predict just based on yesterday’s weather, or just based on the last two days weather, or the last three days weather. But oftentimes, we’re going to deal with just the one previous state that helps to predict this current state. And by putting a whole bunch of these random variables together, using this Markov assumption, we can create what’s called a Markov chain, where a Markov chain is just some sequence of random variables where each of the variables distribution follows that Markov assumption. And so we’ll do an example of this where the Markov assumption is, I can predict the weather. Is it sunny or rainy? And we’ll just consider those two possibilities for now, even though there are other types of weather. But I can predict each day’s weather just on the prior day’s weather, using today’s weather, I can come up with a probability distribution for tomorrow’s weather. And here’s what this weather might look like. It’s formatted in terms of a matrix, as you might describe it, as rows and columns of values, where on the left-hand side, I have today’s weather, represented by the variable x sub t. And over here in the columns, I have tomorrow’s weather, represented by the variable x sub t plus 1, t plus 1 day’s weather instead. And what this matrix is saying is, if today is sunny, well, then it’s more likely than not that tomorrow is also sunny. Oftentimes, the weather stays consistent for multiple days in a row. And for example, let’s say that if today is sunny, our model says that tomorrow, with probability 0.8, it will also be sunny. And with probability 0.2, it will be raining. And likewise, if today is raining, then it’s more likely than not that tomorrow is also raining. With probability 0.7, it’ll be raining. With probability 0.3, it will be sunny. So this matrix, this description of how it is we transition from one state to the next state is what we’re going to call the transition model. And using the transition model, you can begin to construct this Markov chain by just predicting, given today’s weather, what’s the likelihood of tomorrow’s weather happening. And you can imagine doing a similar sampling procedure, where you take this information, you sample what tomorrow’s weather is going to be. Using that, you sample the next day’s weather. And the result of that is you can form this Markov chain of like x0, time and time, day zero is sunny, the next day is sunny, maybe the next day it changes to raining, then raining, then raining. And the pattern that this Markov chain follows, given the distribution that we had access to, this transition model here, is that when it’s sunny, it tends to stay sunny for a little while. The next couple of days tend to be sunny too. And when it’s raining, it tends to be raining as well. And so you get a Markov chain that looks like this, and you can do analysis on this. You can say, given that today is raining, what is the probability that tomorrow is raining? Or you can begin to ask probability questions like, what is the probability of this sequence of five values, sun, sun, rain, rain, rain, and answer those sorts of questions too. And it turns out there are, again, many Python libraries for interacting with models like this of probabilities that have distributions and random variables that are based on previous variables according to this Markov assumption. And pomegranate2 has ways of dealing with these sorts of variables. So I’ll go ahead and go into the chain directory, where I have some information about Markov chains. And here, I’ve defined a file called model.py, where I’ve defined in a very similar syntax. And again, the exact syntax doesn’t matter so much as the idea that I’m encoding this information into a Python program so that the program has access to these distributions. I’ve here defined some starting distribution. So every Markov model begins at some point in time, and I need to give it some starting distribution. And so we’ll just say, you know at the start, you can pick 50-50 between sunny and rainy. We’ll say it’s sunny 50% of the time, rainy 50% of the time. And then down below, I’ve here defined the transition model, how it is that I transition from one day to the next. And here, I’ve encoded that exact same matrix from before, that if it was sunny today, then with probability 0.8, it will be sunny tomorrow. And it’ll be rainy tomorrow with probability 0.2. And I likewise have another distribution for if it was raining today instead. And so that alone defines the Markov model. You can begin to answer questions using that model. But one thing I’ll just do is sample from the Markov chain. It turns out there is a method built into this Markov chain library that allows me to sample 50 states from the chain, basically just simulating like 50 instances of weather. And so let me go ahead and run this. Python model.py. And when I run it, what I get is that it’s going to sample from this Markov chain 50 states, 50 days worth of weather that it’s just going to randomly sample. And you can imagine sampling many times to be able to get more data, to be able to do more analysis. But here, for example, it’s sunny two days in a row, rainy a whole bunch of days in a row before it changes back to sun. And so you get this model that follows the distribution that we originally described, that follows the distribution of sunny days tend to lead to more sunny days. Rainy days tend to lead to more rainy days. And that then is a Markov model. And Markov models rely on us knowing the values of these individual states. I know that today is sunny or that today is raining. And using that information, I can draw some sort of inference about what tomorrow is going to be like. But in practice, this often isn’t the case. It often isn’t the case that I know for certain what the exact state of the world is. Oftentimes, the state of the world is exactly unknown. But I’m able to somehow sense some information about that state, that a robot or an AI doesn’t have exact knowledge about the world around it. But it has some sort of sensor, whether that sensor is a camera or sensors that detect distance or just a microphone that is sensing audio, for example. It is sensing data. And using that data, that data is somehow related to the state of the world, even if it doesn’t actually know, our AI doesn’t know, what the underlying true state of the world actually is. And for that, we need to get into the world of sensor models, the way of describing how it is that we translate what the hidden state, the underlying true state of the world, is with what the observation, what it is that the AI knows or the AI has access to, actually is. And so for example, a hidden state might be a robot’s position. If a robot is exploring new uncharted territory, the robot likely doesn’t know exactly where it is. But it does have an observation. It has robot sensor data, where it can sense how far away are possible obstacles around it. And using that information, using the observed information that it has, it can infer something about the hidden state. Because what the true hidden state is influences those observations. Whatever the robot’s true position is affects or has some effect upon what the sensor data of the robot is able to collect is, even if the robot doesn’t actually know for certain what its true position is. Likewise, if you think about a voice recognition or a speech recognition program that listens to you and is able to respond to you, something like Alexa or what Apple and Google are doing with their voice recognition as well, that you might imagine that the hidden state, the underlying state, is what words are actually spoken. The true nature of the world contains you saying a particular sequence of words, but your phone or your smart home device doesn’t know for sure exactly what words you said. The only observation that the AI has access to is some audio waveforms. And those audio waveforms are, of course, dependent upon this hidden state. And you can infer, based on those audio waveforms, what the words spoken likely were. But you might not know with 100% certainty what that hidden state actually is. And it might be a task to try and predict, given this observation, given these audio waveforms, can you figure out what the actual words spoken are. And likewise, you might imagine on a website, true user engagement. Might be information you don’t directly have access to. But you can observe data, like website or app analytics, about how often was this button clicked or how often are people interacting with a page in a particular way. And you can use that to infer things about your users as well. So this type of problem comes up all the time when we’re dealing with AI and trying to infer things about the world. That often AI doesn’t really know the hidden true state of the world. All the AI has access to is some observation that is related to the hidden true state. But it’s not direct. There might be some noise there. The audio waveform might have some additional noise that might be difficult to parse. The sensor data might not be exactly correct. There’s some noise that might not allow you to conclude with certainty what the hidden state is, but can allow you to infer what it might be. And so the simple example we’ll take a look at here is imagining the hidden state as the weather, whether it’s sunny or rainy or not. And imagine you are programming an AI inside of a building that maybe has access to just a camera to inside the building. And all you have access to is an observation as to whether or not employees are bringing an umbrella into the building or not. You can detect whether it’s an umbrella or not. And so you might have an observation as to whether or not an umbrella is brought into the building or not. And using that information, you want to predict whether it’s sunny or rainy, even if you don’t know what the underlying weather is. So the underlying weather might be sunny or rainy. And if it’s raining, obviously people are more likely to bring an umbrella. And so whether or not people bring an umbrella, your observation, tells you something about the hidden state. And of course, this is a bit of a contrived example, but the idea here is to think about this more broadly in terms of more generally, any time you observe something, it having to do with some underlying hidden state. And so to try and model this type of idea where we have these hidden states and observations, rather than just use a Markov model, which has state, state, state, state, each of which is connected by that transition matrix that we described before, we’re going to use what we call a hidden Markov model. Very similar to a Markov model, but this is going to allow us to model a system that has hidden states that we don’t directly observe, along with some observed event that we do actually see. And so in addition to that transition model that we still need of saying, given the underlying state of the world, if it’s sunny or rainy, what’s the probability of tomorrow’s weather? We also need another model that, given some state, is going to give us an observation of green, yes, someone brings an umbrella into the office, or red, no, nobody brings umbrellas into the office. And so the observation might be that if it’s sunny, then odds are nobody is going to bring an umbrella to the office. But maybe some people are just being cautious, and they do bring an umbrella to the office anyways. And if it’s raining, then with much higher probability, then people are going to bring umbrellas into the office. But maybe if the rain was unexpected, people didn’t bring an umbrella. And so it might have some other probability as well. And so using the observations, you can begin to predict with reasonable likelihood what the underlying state is, even if you don’t actually get to observe the underlying state, if you don’t get to see what the hidden state is actually equal to. This here we’ll often call the sensor model. It’s also often called the emission probabilities, because the state, the underlying state, emits some sort of emission that you then observe. And so that can be another way of describing that same idea. And the sensor Markov assumption that we’re going to use is this assumption that the evidence variable, the thing we observe, the emission that gets produced, depends only on the corresponding state, meaning it can predict whether or not people will bring umbrellas or not entirely dependent just on whether it is sunny or rainy today. Of course, again, this assumption might not hold in practice, that in practice, it might depend whether or not people bring umbrellas, might depend not just on today’s weather, but also on yesterday’s weather and the day before. But for simplification purposes, it can be helpful to apply this sort of assumption just to allow us to be able to reason about these probabilities a little more easily. And if we’re able to approximate it, we can still often get a very good answer. And so what these hidden Markov models end up looking like is a little something like this, where now, rather than just have one chain of states, like sun, sun, rain, rain, rain, we instead have this upper level, which is the underlying state of the world. Is it sunny or is it rainy? And those are connected by that transition matrix we described before. But each of these states produces an emission, produces an observation that I see, that on this day, it was sunny and people didn’t bring umbrellas. And on this day, it was sunny, but people did bring umbrellas. And on this day, it was raining and people did bring umbrellas, and so on and so forth. And so each of these underlying states represented by x sub t for x sub 1, 0, 1, 2, so on and so forth, produces some sort of observation or emission, which is what the e stands for, e sub 0, e sub 1, e sub 2, so on and so forth. And so this, too, is a way of trying to represent this idea. And what you want to think about is that these underlying states are the true nature of the world, the robot’s position as it moves over time, and that produces some sort of sensor data that might be observed, or what people are actually saying and using the emission data of what audio waveforms do you detect in order to process that data and try and figure it out. And there are a number of possible tasks that you might want to do given this kind of information. And one of the simplest is trying to infer something about the future or the past or about these sort of hidden states that might exist. And so the tasks that you’ll often see, and we’re not going to go into the mathematics of these tasks, but they’re all based on the same idea of conditional probabilities and using the probability distributions we have to draw these sorts of conclusions. One task is called filtering, which is given observations from the start until now, calculate the distribution for the current state, meaning given information about from the beginning of time until now, on which days do people bring an umbrella or not bring an umbrella, can I calculate the probability of the current state that today, is it sunny or is it raining? Another task that might be possible is prediction, which is looking towards the future. Given observations about people bringing umbrellas from the beginning of when we started counting time until now, can I figure out the distribution that tomorrow is it sunny or is it raining? And you can also go backwards as well by a smoothing, where I can say given observations from start until now, calculate the distributions for some past state. Like I know that today people brought umbrellas and tomorrow people brought umbrellas. And so given two days worth of data of people bringing umbrellas, what’s the probability that yesterday it was raining? And that I know that people brought umbrellas today, that might inform that decision as well. It might influence those probabilities. And there’s also a most likely explanation task, in addition to other tasks that might exist as well, which is combining some of these given observations from the start up until now, figuring out the most likely sequence of states. And this is what we’re going to take a look at now, this idea that if I have all these observations, umbrella, no umbrella, umbrella, no umbrella, can I calculate the most likely states of sun, rain, sun, rain, and whatnot that actually represented the true weather that would produce these observations? And this is quite common when you’re trying to do something like voice recognition, for example, that you have these emissions of the audio waveforms, and you would like to calculate based on all of the observations that you have, what is the most likely sequence of actual words, or syllables, or sounds that the user actually made when they were speaking to this particular device, or other tasks that might come up in that context as well. And so we can try this out by going ahead and going into the HMM directory, HMM for Hidden Markov Model. And here, what I’ve done is I’ve defined a model where this model first defines my possible state, sun, and rain, along with their emission probabilities, the observation model, or the emission model, where here, given that I know that it’s sunny, the probability that I see people bring an umbrella is 0.2, the probability of no umbrella is 0.8. And likewise, if it’s raining, then people are more likely to bring an umbrella. Umbrella has probability 0.9, no umbrella has probability 0.1. So the actual underlying hidden states, those states are sun and rain, but the things that I observe, the observations that I can see, are either umbrella or no umbrella as the things that I observe as a result. So this then, I also need to add to it a transition matrix, same as before, saying that if today is sunny, then tomorrow is more likely to be sunny. And if today is rainy, then tomorrow is more likely to be raining. As of before, I give it some starting probabilities, saying at first, 50-50 chance for whether it’s sunny or rainy. And then I can create the model based on that information. Again, the exact syntax of this is not so important, so much as it is the data that I am now encoding into a program, such that now I can begin to do some inference. So I can give my program, for example, a list of observations, umbrella, umbrella, no umbrella, umbrella, umbrella, so on and so forth, no umbrella, no umbrella. And I would like to calculate, I would like to figure out the most likely explanation for these observations. What is likely is whether rain, rain, is this rain, or is it more likely that this was actually sunny, and then it switched back to it being rainy? And that’s an interesting question. We might not be sure, because it might just be that it just so happened on this rainy day, people decided not to bring an umbrella. Or it could be that it switched from rainy to sunny back to rainy, which doesn’t seem too likely, but it certainly could happen. And using the data we give to the hidden Markov model, our model can begin to predict these answers, can begin to figure it out. So we’re going to go ahead and just predict these observations. And then for each of those predictions, go ahead and print out what the prediction is. And this library just so happens to have a function called predict that does this prediction process for me. So I’ll run python sequence.py. And the result I get is this. This is the prediction based on the observations of what all of those states are likely to be. And it’s likely to be rain and rain. In this case, it thinks that what most likely happened is that it was sunny for a day and then went back to being rainy. But in different situations, if it was rainy for longer maybe, or if the probabilities were slightly different, you might imagine that it’s more likely that it was rainy all the way through. And it just so happened on one rainy day, people decided not to bring umbrellas. And so here, too, Python libraries can begin to allow for the sort of inference procedure. And by taking what we know and by putting it in terms of these tasks that already exist, these general tasks that work with hidden Markov models, then any time we can take an idea and formulate it as a hidden Markov model, formulate it as something that has hidden states and observed emissions that result from those states, then we can take advantage of these algorithms that are known to exist for trying to do this sort of inference. So now we’ve seen a couple of ways that AI can begin to deal with uncertainty. We’ve taken a look at probability and how we can use probability to describe numerically things that are likely or more likely or less likely to happen than other events or other variables. And using that information, we can begin to construct these standard types of models, things like Bayesian networks and Markov chains and hidden Markov models that all allow us to be able to describe how particular events relate to other events or how the values of particular variables relate to other variables, not for certain, but with some sort of probability distribution. And by formulating things in terms of these models that already exist, we can take advantage of Python libraries that implement these sort of models already and allow us just to be able to use them to produce some sort of resulting effect. So all of this then allows our AI to begin to deal with these sort of uncertain problems so that our AI doesn’t need to know things for certain but can infer based on information it doesn’t know. Next time, we’ll take a look at additional types of problems that we can solve by taking advantage of AI-related algorithms, even beyond the world of the types of problems we’ve already explored. We’ll see you next time. OK. Welcome back, everyone, to an introduction to artificial intelligence with Python. And now, so far, we’ve taken a look at a couple of different types of problems. We’ve seen classical search problems where we’re trying to get from an initial state to a goal by figuring out some optimal path. We’ve taken a look at adversarial search where we have a game-playing agent that is trying to make the best move. We’ve seen knowledge-based problems where we’re trying to use logic and inference to be able to figure out and draw some additional conclusions. And we’ve seen some probabilistic models as well where we might not have certain information about the world, but we want to use the knowledge about probabilities that we do have to be able to draw some conclusions. Today, we’re going to turn our attention to another category of problems generally known as optimization problems, where optimization is really all about choosing the best option from a set of possible options. And we’ve already seen optimization in some contexts, like game-playing, where we’re trying to create an AI that chooses the best move out of a set of possible moves. But what we’ll take a look at today is a category of types of problems and algorithms to solve them that can be used in order to deal with a broader range of potential optimization problems. And the first of the algorithms that we’ll take a look at is known as a local search. And local search differs from search algorithms we’ve seen before in the sense that the search algorithms we’ve looked at so far, which are things like breadth-first search or A-star search, for example, generally maintain a whole bunch of different paths that we’re simultaneously exploring, and we’re looking at a bunch of different paths at once trying to find our way to the solution. On the other hand, in local search, this is going to be a search algorithm that’s really just going to maintain a single node, looking at a single state. And we’ll generally run this algorithm by maintaining that single node and then moving ourselves to one of the neighboring nodes throughout this search process. And this is generally useful in context not like these problems, which we’ve seen before, like a maze-solving situation where we’re trying to find our way from the initial state to the goal by following some path. But local search is most applicable when we really don’t care about the path at all, and all we care about is what the solution is. And in the case of solving a maze, the solution was always obvious. You could point to the solution. You know exactly what the goal is, and the real question is, what is the path to get there? But local search is going to come up in cases where figuring out exactly what the solution is, exactly what the goal looks like, is actually the heart of the challenge. And to give an example of one of these kinds of problems, we’ll consider a scenario where we have two types of buildings, for example. We have houses and hospitals. And our goal might be in a world that’s formatted as this grid, where we have a whole bunch of houses, a house here, house here, two houses over there, maybe we want to try and find a way to place two hospitals on this map. So maybe a hospital here and a hospital there. And the problem now is we want to place two hospitals on the map, but we want to do so with some sort of objective. And our objective in this case is to try and minimize the distance of any of the houses from a hospital. So you might imagine, all right, what’s the distance from each of the houses to their nearest hospital? There are a number of ways we could calculate that distance. But one way is using a heuristic we’ve looked at before, which is the Manhattan distance, this idea of how many rows and columns would you have to move inside of this grid layout in order to get to a hospital, for example. And it turns out, if you take each of these four houses and figure out, all right, how close are they to their nearest hospital, you get something like this, where this house is three away from a hospital, this house is six away, and these two houses are each four away. And if you add all those numbers up together, you get a total cost of 17, for example. So for this particular configuration of hospitals, a hospital here and a hospital there, that state, we might say, has a cost of 17. And the goal of this problem now that we would like to apply a search algorithm to figure out is, can you solve this problem to find a way to minimize that cost? Minimize the total amount if you sum up all of the distances from all the houses to the nearest hospital. How can we minimize that final value? And if we think about this problem a little bit more abstractly, abstracting away from this specific problem and thinking more generally about problems like it, you can often formulate these problems by thinking about them as a state-space landscape, as we’ll soon call it. Here in this diagram of a state-space landscape, each of these vertical bars represents a particular state that our world could be in. So for example, each of these vertical bars represents a particular configuration of two hospitals. And the height of this vertical bar is generally going to represent some function of that state, some value of that state. So maybe in this case, the height of the vertical bar represents what is the cost of this particular configuration of hospitals in terms of what is the sum total of all the distances from all of the houses to their nearest hospital. And generally speaking, when we have a state-space landscape, we want to do one of two things. We might be trying to maximize the value of this function, trying to find a global maximum, so to speak, of this state-space landscape, a single state whose value is higher than all of the other states that we could possibly choose from. And generally in this case, when we’re trying to find a global maximum, we’ll call the function that we’re trying to optimize some objective function, some function that measures for any given state how good is that state, such that we can take any state, pass it into the objective function, and get a value for how good that state is. And ultimately, what our goal is is to find one of these states that has the highest possible value for that objective function. An equivalent but reversed problem is the problem of finding a global minimum, some state that has a value after you pass it into this function that is lower than all of the other possible values that we might choose from. And generally speaking, when we’re trying to find a global minimum, we call the function that we’re calculating a cost function. Generally, each state has some sort of cost, whether that cost is a monetary cost, or a time cost, or in the case of the houses and hospitals, we’ve been looking at just now, a distance cost in terms of how far away each of the houses is from a hospital. And we’re trying to minimize the cost, find the state that has the lowest possible value of that cost. So these are the general types of ideas we might be trying to go for within a state space landscape, trying to find a global maximum, or trying to find a global minimum. And how exactly do we do that? We’ll recall that in local search, we generally operate this algorithm by maintaining just a single state, just some current state represented inside of some node, maybe inside of a data structure, where we’re keeping track of where we are currently. And then ultimately, what we’re going to do is from that state, move to one of its neighbor states. So in this case, represented in this one-dimensional space by just the state immediately to the left or to the right of it. But for any different problem, you might define what it means for there to be a neighbor of a particular state. In the case of a hospital, for example, that we were just looking at, a neighbor might be moving one hospital one space to the left or to the right or up or down. Some state that is close to our current state, but slightly different, and as a result, might have a slightly different value in terms of its objective function or in terms of its cost function. So this is going to be our general strategy in local search, to be able to take a state, maintaining some current node, and move where we’re looking at in the state space landscape in order to try to find a global maximum or a global minimum somehow. And perhaps the simplest of algorithms that we could use to implement this idea of local search is an algorithm known as hill climbing. And the basic idea of hill climbing is, let’s say I’m trying to maximize the value of my state. I’m trying to figure out where the global maximum is. I’m going to start at a state. And generally, what hill climbing is going to do is it’s going to consider the neighbors of that state, that from this state, all right, I could go left or I could go right, and this neighbor happens to be higher and this neighbor happens to be lower. And in hill climbing, if I’m trying to maximize the value, I’ll generally pick the highest one I can between the state to the left and right of me. This one is higher. So I’ll go ahead and move myself to consider that state instead. And then I’ll repeat this process, continually looking at all of my neighbors and picking the highest neighbor, doing the same thing, looking at my neighbors, picking the highest of my neighbors, until I get to a point like right here, where I consider both of my neighbors and both of my neighbors have a lower value than I do. This current state has a value that is higher than any of its neighbors. And at that point, the algorithm terminates. And I can say, all right, here I have now found the solution. And the same thing works in exactly the opposite way for trying to find a global minimum. But the algorithm is fundamentally the same. If I’m trying to find a global minimum and say my current state starts here, I’ll continually look at my neighbors, pick the lowest value that I possibly can, until I eventually, hopefully, find that global minimum, a point at which when I look at both of my neighbors, they each have a higher value. And I’m trying to minimize the total score or cost or value that I get as a result of calculating some sort of cost function. So we can formulate this graphical idea in terms of pseudocode. And the pseudocode for hill climbing might look like this. We define some function called hill climb that takes as input the problem that we’re trying to solve. And generally, we’re going to start in some sort of initial state. So I’ll start with a variable called current that is keeping track of my initial state, like an initial configuration of hospitals. And maybe some problems lend themselves to an initial state, some place where you begin. In other cases, maybe not, in which case we might just randomly generate some initial state, just by choosing two locations for hospitals at random, for example, and figuring out from there how we might be able to improve. But that initial state, we’re going to store inside of current. And now, here comes our loop, some repetitive process we’re going to do again and again until the algorithm terminates. And what we’re going to do is first say, let’s figure out all of the neighbors of the current state. From my state, what are all of the neighboring states for some definition of what it means to be a neighbor? And I’ll go ahead and choose the highest value of all of those neighbors and save it inside of this variable called neighbor. So keep track of the highest-valued neighbor. This is in the case where I’m trying to maximize the value. In the case where I’m trying to minimize the value, you might imagine here, you’ll pick the neighbor with the lowest possible value. But these ideas are really fundamentally interchangeable. And it’s possible, in some cases, there might be multiple neighbors that each have an equally high value or an equally low value in the minimizing case. And in that case, we can just choose randomly from among them. Choose one of them and save it inside of this variable neighbor. And then the key question to ask is, is this neighbor better than my current state? And if the neighbor, the best neighbor that I was able to find, is not better than my current state, well, then the algorithm is over. And I’ll just go ahead and return the current state. If none of my neighbors are better, then I may as well stay where I am, is the general logic of the hill climbing algorithm. But otherwise, if the neighbor is better, then I may as well move to that neighbor. So you might imagine setting current equal to neighbor, where the general idea is if I’m at a current state and I see a neighbor that is better than me, then I’ll go ahead and move there. And then I’ll repeat the process, continually moving to a better neighbor until I reach a point at which none of my neighbors are better than I am. And at that point, we’d say the algorithm can just terminate there. So let’s take a look at a real example of this with these houses and hospitals. So we’ve seen now that if we put the hospitals in these two locations, that has a total cost of 17. And now we need to define, if we’re going to implement this hill climbing algorithm, what it means to take this particular configuration of hospitals, this particular state, and get a neighbor of that state. And a simple definition of neighbor might be just, let’s pick one of the hospitals and move it by one square, the left or right or up or down, for example. And that would mean we have six possible neighbors from this particular configuration. We could take this hospital and move it to any of these three possible squares, or we take this hospital and move it to any of those three possible squares. And each of those would generate a neighbor. And what I might do is say, all right, here’s the locations and the distances between each of the houses and their nearest hospital. Let me consider all of the neighbors and see if any of them can do better than a cost of 17. And it turns out there are a couple of ways that we could do that. And it doesn’t matter if we randomly choose among all the ways that are the best. But one such possible way is by taking a look at this hospital here and considering the directions in which it might move. If we hold this hospital constant, if we take this hospital and move it one square up, for example, that doesn’t really help us. It gets closer to the house up here, but it gets further away from the house down here. And it doesn’t really change anything for the two houses along the left-hand side. But if we take this hospital on the right and move it one square down, it’s the opposite problem. It gets further away from the house up above, and it gets closer to the house down below. The real idea, the goal should be to be able to take this hospital and move it one square to the left. By moving it one square to the left, we move it closer to both of these houses on the right without changing anything about the houses on the left. For them, this hospital is still the closer one, so they aren’t affected. So we’re able to improve the situation by picking a neighbor that results in a decrease in our total cost. And so we might do that. Move ourselves from this current state to a neighbor by just taking that hospital and moving it. And at this point, there’s not a whole lot that can be done with this hospital. But there’s still other optimizations we can make, other neighbors we can move to that are going to have a better value. If we consider this hospital, for example, we might imagine that right now it’s a bit far up, that both of these houses are a little bit lower. So we might be able to do better by taking this hospital and moving it one square down, moving it down so that now instead of a cost of 15, we’re down to a cost of 13 for this particular configuration. And we can do even better by taking the hospital and moving it one square to the left. Now instead of a cost of 13, we have a cost of 11, because this house is one away from the hospital. This one is four away. This one is three away. And this one is also three away. So we’ve been able to do much better than that initial cost that we had using the initial configuration. Just by taking every state and asking ourselves the question, can we do better by just making small incremental changes, moving to a neighbor, moving to a neighbor, and moving to a neighbor after that? And now at this point, we can potentially see that at this point, the algorithm is going to terminate. There’s actually no neighbor we can move to that is going to improve the situation, get us a cost that is less than 11. Because if we take this hospital and move it upper to the right, well, that’s going to make it further away. If we take it and move it down, that doesn’t really change the situation. It gets further away from this house but closer to that house. And likewise, the same story was true for this hospital. Any neighbor we move it to, up, left, down, or right, is either going to make it further away from the houses and increase the cost, or it’s going to have no effect on the cost whatsoever. And so the question we might now ask is, is this the best we could do? Is this the best placement of the hospitals we could possibly have? And it turns out the answer is no, because there’s a better way that we could place these hospitals. And in particular, there are a number of ways you could do this. But one of the ways is by taking this hospital here and moving it to this square, for example, moving it diagonally by one square, which was not part of our definition of neighbor. We could only move left, right, up, or down. But this is, in fact, better. It has a total cost of 9. It is now closer to both of these houses. And as a result, the total cost is less. But we weren’t able to find it, because in order to get there, we had to go through a state that actually wasn’t any better than the current state that we had been on previously. And so this appears to be a limitation, or a concern you might have as you go about trying to implement a hill climbing algorithm, is that it might not always give you the optimal solution. If we’re trying to maximize the value of any particular state, we’re trying to find the global maximum, a concern might be that we could get stuck at one of the local maxima, highlighted here in blue, where a local maxima is any state whose value is higher than any of its neighbors. If we ever find ourselves at one of these two states when we’re trying to maximize the value of the state, we’re not going to make any changes. We’re not going to move left or right. We’re not going to move left here, because those states are worse. But yet, we haven’t found the global optimum. We haven’t done as best as we could do. And likewise, in the case of the hospitals, what we’re ultimately trying to do is find a global minimum, find a value that is lower than all of the others. But we have the potential to get stuck at one of the local minima, any of these states whose value is lower than all of its neighbors, but still not as low as the local minima. And so the takeaway here is that it’s not always going to be the case that when we run this naive hill climbing algorithm, that we’re always going to find the optimal solution. There are things that could go wrong. If we started here, for example, and tried to maximize our value as much as possible, we might move to the highest possible neighbor, move to the highest possible neighbor, move to the highest possible neighbor, and stop, and never realize that there’s actually a better state way over there that we could have gone to instead. And other problems you might imagine just by taking a look at this state space landscape are these various different types of plateaus, something like this flat local maximum here, where all six of these states each have the exact same value. And so in the case of the algorithm we showed before, none of the neighbors are better, so we might just get stuck at this flat local maximum. And even if you allowed yourself to move to one of the neighbors, it wouldn’t be clear which neighbor you would ultimately move to, and you could get stuck here as well. And there’s another one over here. This one is called a shoulder. It’s not really a local maximum, because there’s still places where we can go higher, not a local minimum, because we can go lower. So we can still make progress, but it’s still this flat area, where if you have a local search algorithm, there’s potential to get lost here, unable to make some upward or downward progress, depending on whether we’re trying to maximize or minimize it, and therefore another potential for us to be able to find a solution that might not actually be the optimal solution. And so because of this potential, the potential that hill climbing has to not always find us the optimal result, it turns out there are a number of different varieties and variations on the hill climbing algorithm that help to solve the problem better depending on the context, and depending on the specific type of problem, some of these variants might be more applicable than others. What we’ve taken a look at so far is a version of hill climbing generally called steepest ascent hill climbing, where the idea of steepest ascent hill climbing is we are going to choose the highest valued neighbor, in the case where we’re trying to maximize or the lowest valued neighbor in cases where we’re trying to minimize. But generally speaking, if I have five neighbors and they’re all better than my current state, I will pick the best one of those five. Now, sometimes that might work pretty well. It’s sort of a greedy approach of trying to take the best operation at any particular time step, but it might not always work. There might be cases where actually I want to choose an option that is slightly better than me, but maybe not the best one because that later on might lead to a better outcome ultimately. So there are other variants that we might consider of this basic hill climbing algorithm. One is known as stochastic hill climbing. And in this case, we choose randomly from all of our higher value neighbors. So if I’m at my current state and there are five neighbors that are all better than I am, rather than choosing the best one, as steep as the set would do, stochastic will just choose randomly from one of them, thinking that if it’s better, then it’s better. And maybe there’s a potential to make forward progress, even if it is not locally the best option I could possibly choose. First choice hill climbing ends up just choosing the very first highest valued neighbor that it follows, behaving on a similar idea, rather than consider all of the neighbors. As soon as we find a neighbor that is better than our current state, we’ll go ahead and move there. There may be some efficiency improvements there and maybe has the potential to find a solution that the other strategies weren’t able to find. And with all of these variants, we still suffer from the same potential risk, this risk that we might end up at a local minimum or a local maximum. And we can reduce that risk by repeating the process multiple times. So one variant of hill climbing is random restart hill climbing, where the general idea is we’ll conduct hill climbing multiple times. If we apply steepest descent hill climbing, for example, we’ll start at some random state, try and figure out how to solve the problem and figure out what is the local maximum or local minimum we get to. And then we’ll just randomly restart and try again, choose a new starting configuration, try and figure out what the local maximum or minimum is, and do this some number of times. And then after we’ve done it some number of times, we can pick the best one out of all of the ones that we’ve taken a look at. So there’s another option we have access to as well. And then, although I said that generally local search will usually just keep track of a single node and then move to one of its neighbors, there are variants of hill climbing that are known as local beam searches, where rather than keep track of just one current best state, we’re keeping track of k highest valued neighbors, such that rather than starting at one random initial configuration, I might start with 3 or 4 or 5, randomly generate all the neighbors, and then pick the 3 or 4 or 5 best of all of the neighbors that I find, and continually repeat this process, with the idea being that now I have more options that I’m considering, more ways that I could potentially navigate myself to the optimal solution that might exist for a particular problem. So let’s now take a look at some actual code that can implement some of these kinds of ideas, something like steepest ascent hill climbing, for example, for trying to solve this hospital problem. So I’m going to go ahead and go into my hospitals directory, where I’ve actually set up the basic framework for solving this type of problem. I’ll go ahead and go into hospitals.py, and we’ll take a look at the code we’ve created here. I’ve defined a class that is going to represent the state space. So the space has a height, and a width, and also some number of hospitals. So you can configure how big is your map, how many hospitals should go here. We have a function for adding a new house to the state space, and then some functions that are going to get me all of the available spaces for if I want to randomly place hospitals in particular locations. And here now is the hill climbing algorithm. So what are we going to do in the hill climbing algorithm? Well, we’re going to start by randomly initializing where the hospitals are going to go. We don’t know where the hospitals should actually be, so let’s just randomly place them. So here I’m running a loop for each of the hospitals that I have. I’m going to go ahead and add a new hospital at some random location. So I basically get all of the available spaces, and I randomly choose one of them as where I would like to add this particular hospital. I have some logging output and generating some images, which we’ll take a look at a little bit later. But here is the key idea. So I’m going to just keep repeating this algorithm. I could specify a maximum of how many times I want it to run, or I could just run it up until it hits a local maximum or local minimum. And now we’ll basically consider all of the hospitals that could potentially move. So consider each of the two hospitals or more hospitals if they’re more than that. And consider all of the places where that hospital could move to, some neighbor of that hospital that we can move the neighbor to. And then see, is this going to be better than where we were currently? So if it is going to be better, then we’ll go ahead and update our best neighbor and keep track of this new best neighbor that we found. And then afterwards, we can ask ourselves the question, if best neighbor cost is greater than or equal to the cost of the current set of hospitals, meaning if the cost of our best neighbor is greater than the current cost, meaning our best neighbor is worse than our current state, well, then we shouldn’t make any changes at all. And we should just go ahead and return the current set of hospitals. But otherwise, we can update our hospitals in order to change them to one of the best neighbors. And if there are multiple that are all equivalent, I’m here using random.choice to say go ahead and choose one randomly. So this is really just a Python implementation of that same idea that we were just talking about, this idea of taking a current state, some current set of hospitals, generating all of the neighbors, looking at all of the ways we could take one hospital and move it one square to the left or right or up or down, and then figuring out, based on all of that information, which is the best neighbor or the set of all the best neighbors, and then choosing from one of those. And each time, we go ahead and generate an image in order to do that. And so now what we’re doing is if we look down at the bottom, I’m going to randomly generate a space with height 10 and width 20. And I’ll say go ahead and put three hospitals somewhere in the space. I’ll randomly generate 15 houses that I just go ahead and add in random locations. And now I’m going to run this hill climbing algorithm in order to try and figure out where we should place those hospitals. So we’ll go ahead and run this program by running Python hospitals. And we see that we started. Our initial state had a cost of 72, but we were able to continually find neighbors that were able to decrease that cost, decrease to 69, 66, 63, so on and so forth, all the way down to 53, as the best neighbor we were able to ultimately find. And we can take a look at what that looked like by just opening up these files. So here, for example, was the initial configuration. We randomly selected a location for each of these 15 different houses and then randomly selected locations for one, two, three hospitals that were just located somewhere inside of the state space. And if you add up all the distances from each of the houses to their nearest hospital, you get a total cost of about 72. And so now the question is, what neighbors can we move to that improve the situation? And it looks like the first one the algorithm found was by taking this house that was over there on the right and just moving it to the left. And that probably makes sense because if you look at the houses in that general area, really these five houses look like they’re probably the ones that are going to be closest to this hospital over here. Moving it to the left decreases the total distance, at least to most of these houses, though it does increase that distance for one of them. And so we’re able to make these improvements to the situation by continually finding ways that we can move these hospitals around until we eventually settle at this particular state that has a cost of 53, where we figured out a position for each of the hospitals. And now none of the neighbors that we could move to are actually going to improve the situation. We can take this hospital and this hospital and that hospital and look at each of the neighbors. And none of those are going to be better than this particular configuration. And again, that’s not to say that this is the best we could do. There might be some other configuration of hospitals that is a global minimum. And this might just be a local minimum that is the best of all of its neighbors, but maybe not the best in the entire possible state space. And you could search through the entire state space by considering all of the possible configurations for hospitals. But ultimately, that’s going to be very time intensive, especially as our state space gets bigger and there might be more and more possible states. It’s going to take quite a long time to look through all of them. And so being able to use these sort of local search algorithms can often be quite good for trying to find the best solution we can do. And especially if we don’t care about doing the best possible and we just care about doing pretty good and finding a pretty good placement of those hospitals, then these methods can be particularly powerful. But of course, we can try and mitigate some of this concern by instead of using hill climbing to use random restart, this idea of rather than just hill climb one time, we can hill climb multiple times and say, try hill climbing a whole bunch of times on the exact same map and figure out what is the best one that we’ve been able to find. And so I’ve here implemented a function for random restart that restarts some maximum number of times. And what we’re going to do is repeat that number of times this process of just go ahead and run the hill climbing algorithm, figure out what the cost is of getting from all the houses to the hospitals, and then figure out is this better than we’ve done so far. So I can try this exact same idea where instead of running hill climbing, I’ll go ahead and run random restart. And I’ll randomly restart maybe 20 times, for example. And we’ll go ahead and now I’ll remove all the images and then rerun the program. And now we started by finding a original state. When we initially ran hill climbing, the best cost we were able to find was 56. Each of these iterations is a different iteration of the hill climbing algorithm. We’re running hill climbing not one time, but 20 times here, each time going until we find a local minimum in this case. And we look and see each time did we do better than we did the best time we’ve done so far. So we went from 56 to 46. This one was greater, so we ignored it. This one was 41, which was less, so we went ahead and kept that one. And for all of the remaining 16 times that we tried to implement hill climbing and we tried to run the hill climbing algorithm, we couldn’t do any better than that 41. Again, maybe there is a way to do better that we just didn’t find, but it looks like that way ended up being a pretty good solution to the problem. That was attempt number three, starting from counting at zero. So we can take a look at that, open up number three. And this was the state that happened to have a cost of 41, that after running the hill climbing algorithm on some particular random initial configuration of hospitals, this is what we found was the local minimum in terms of trying to minimize the cost. And it looks like we did pretty well. This hospital is pretty close to this region. This one is pretty close to these houses here. This hospital looks about as good as we can do for trying to capture those houses over on that side. And so these sorts of algorithms can be quite useful for trying to solve these problems. But the real problem with many of these different types of hill climbing, steepest of sense, stochastic, first choice, and so forth, is that they never make a move that makes our situation worse. They’re always going to take ourselves in our current state, look at the neighbors, and consider can we do better than our current state and move to one of those neighbors. Which of those neighbors we choose might vary among these various different types of algorithms, but we never go from a current position to a position that is worse than our current position. And ultimately, that’s what we’re going to need to do if we want to be able to find a global maximum or a global minimum. Because sometimes if we get stuck, we want to find some way of dislodging ourselves from our local maximum or local minimum in order to find the global maximum or the global minimum or increase the probability that we do find it. And so the most popular technique for trying to approach the problem from that angle is a technique known as simulated annealing, simulated because it’s modeling after a real physical process of annealing, where you can think about this in terms of physics, a physical situation where you have some system of particles. And you might imagine that when you heat up a particular physical system, there’s a lot of energy there. Things are moving around quite randomly. But over time, as the system cools down, it eventually settles into some final position. And that’s going to be the general idea of simulated annealing. We’re going to simulate that process of some high temperature system where things are moving around randomly quite frequently, but over time decreasing that temperature until we eventually settle at our ultimate solution. And the idea is going to be if we have some state space landscape that looks like this and we begin at its initial state here, if we’re looking for a global maximum and we’re trying to maximize the value of the state, our traditional hill climbing algorithms would just take the state and look at the two neighbor ones and always pick the one that is going to increase the value of the state. But if we want some chance of being able to find the global maximum, we can’t always make good moves. We have to sometimes make bad moves and allow ourselves to make a move in a direction that actually seems for now to make our situation worse such that later we can find our way up to that global maximum in terms of trying to solve that problem. Of course, once we get up to this global maximum, once we’ve done a whole lot of the searching, then we probably don’t want to be moving to states that are worse than our current state. And so this is where this metaphor for annealing starts to come in, where we want to start making more random moves and over time start to make fewer of those random moves based on a particular temperature schedule. So the basic outline looks something like this. Early on in simulated annealing, we have a higher temperature state. And what we mean by a higher temperature state is that we are more likely to accept neighbors that are worse than our current state. We might look at our neighbors. And if one of our neighbors is worse than the current state, especially if it’s not all that much worse, if it’s pretty close but just slightly worse, then we might be more likely to accept that and go ahead and move to that neighbor anyways. But later on as we run simulated annealing, we’re going to decrease that temperature. And at a lower temperature, we’re going to be less likely to accept neighbors that are worse than our current state. Now to formalize this and put a little bit of pseudocode to it, here is what that algorithm might look like. We have a function called simulated annealing that takes as input the problem we’re trying to solve and also potentially some maximum number of times we might want to run the simulated annealing process, how many different neighbors we’re going to try and look for. And that value is going to vary based on the problem you’re trying to solve. We’ll, again, start with some current state that will be equal to the initial state of the problem. But now we need to repeat this process over and over for max number of times. Repeat some process some number of times where we’re first going to calculate a temperature. And this temperature function takes the current time t starting at 1 going all the way up to max and then gives us some temperature that we can use in our computation, where the idea is that this temperature is going to be higher early on and it’s going to be lower later on. So there are a number of ways this temperature function could often work. One of the simplest ways is just to say it is like the proportion of time that we still have remaining. Out of max units of time, how much time do we have remaining? You start off with a lot of that time remaining. And as time goes on, the temperature is going to decrease because you have less and less of that remaining time still available to you. So we calculate a temperature for the current time. And then we pick a random neighbor of the current state. No longer are we going to be picking the best neighbor that we possibly can or just one of the better neighbors that we can. We’re going to pick a random neighbor. It might be better. It might be worse. But we’re going to calculate that. We’re going to calculate delta E, E for energy in this case, which is just how much better is the neighbor than the current state. So if delta E is positive, that means the neighbor is better than our current state. If delta E is negative, that means the neighbor is worse than our current state. And so we can then have a condition that looks like this. If delta E is greater than 0, that means the neighbor state is better than our current state. And if ever that situation arises, we’ll just go ahead and update current to be that neighbor. Same as before, move where we are currently to be the neighbor because the neighbor is better than our current state. We’ll go ahead and accept that. But now the difference is that whereas before, we never, ever wanted to take a move that made our situation worse, now we sometimes want to make a move that is actually going to make our situation worse because sometimes we’re going to need to dislodge ourselves from a local minimum or local maximum to increase the probability that we’re able to find the global minimum or the global maximum a little bit later. And so how do we do that? How do we decide to sometimes accept some state that might actually be worse? Well, we’re going to accept a worse state with some probability. And that probability needs to be based on a couple of factors. It needs to be based in part on the temperature, where if the temperature is higher, we’re more likely to move to a worse neighbor. And if the temperature is lower, we’re less likely to move to a worse neighbor. But it also, to some degree, should be based on delta E. If the neighbor is much worse than the current state, we probably want to be less likely to choose that than if the neighbor is just a little bit worse than the current state. So again, there are a couple of ways you could calculate this. But it turns out one of the most popular is just to calculate E to the power of delta E over T, where E is just a constant. Delta E over T are based on delta E and T here. We calculate that value. And that’ll be some value between 0 and 1. And that is the probability with which we should just say, all right, let’s go ahead and move to that neighbor. And it turns out that if you do the math for this value, when delta E is such that the neighbor is not that much worse than the current state, that’s going to be more likely that we’re going to go ahead and move to that state. And likewise, when the temperature is lower, we’re going to be less likely to move to that neighboring state as well. So now this is the big picture for simulated annealing, this process of taking the problem and going ahead and generating random neighbors will always move to a neighbor if it’s better than our current state. But even if the neighbor is worse than our current state, we’ll sometimes move there depending on how much worse it is and also based on the temperature. And as a result, the hope, the goal of this whole process is that as we begin to try and find our way to the global maximum or the global minimum, we can dislodge ourselves if we ever get stuck at a local maximum or local minimum in order to eventually make our way to exploring the part of the state space that is going to be the best. And then as the temperature decreases, eventually we settle there without moving around too much from what we’ve found to be the globally best thing that we can do thus far. So at the very end, we just return whatever the current state happens to be. And that is the conclusion of this algorithm. We’ve been able to figure out what the solution is. And these types of algorithms have a lot of different applications. Any time you can take a problem and formulate it as something where you can explore a particular configuration and then ask, are any of the neighbors better than this current configuration and have some way of measuring that, then there is an applicable case for these hill climbing, simulated annealing types of algorithms. So sometimes it can be for facility location type problems, like for when you’re trying to plan a city and figure out where the hospitals should be. But there are definitely other applications as well. And one of the most famous problems in computer science is the traveling salesman problem. Traveling salesman problem generally is formulated like this. I have a whole bunch of cities here indicated by these dots. And what I’d like to do is find some route that takes me through all of the cities and ends up back where I started. So some route that starts here, goes through all these cities, and ends up back where I originally started. And what I might like to do is minimize the total distance that I have to travel or the total cost of taking this entire path. And you can imagine this is a problem that’s very applicable in situations like when delivery companies are trying to deliver things to a whole bunch of different houses, they want to figure out, how do I get from the warehouse to all these various different houses and get back again, all using as minimal time and distance and energy as possible. So you might want to try to solve these sorts of problems. But it turns out that solving this particular kind of problem is very computationally difficult. It is a very computationally expensive task to be able to figure it out. This falls under the category of what are known as NP-complete problems, problems that there is no known efficient way to try and solve these sorts of problems. And so what we ultimately have to do is come up with some approximation, some ways of trying to find a good solution, even if we’re not going to find the globally best solution that we possibly can, at least not in a feasible or tractable amount of time. And so what we could do is take the traveling salesman problem and try to formulate it using local search and ask a question like, all right, I can pick some state, some configuration, some route between all of these nodes. And I can measure the cost of that state, figure out what the distance is. And I might now want to try to minimize that cost as much as possible. And then the only question now is, what does it mean to have a neighbor of this state? What does it mean to take this particular route and have some neighboring route that is close to it but slightly different and such that it might have a different total distance? And there are a number of different definitions for what a neighbor of a traveling salesman configuration might look like. But one way is just to say, a neighbor is what happens if we pick two of these edges between nodes and switch them effectively. So for example, I might pick these two edges here, these two that just happened across this node goes here, this node goes there, and go ahead and switch them. And what that process will generally look like is removing both of these edges from the graph, taking this node, and connecting it to the node it wasn’t connected to. So connecting it up here instead. We’ll need to take these arrows that were originally going this way and reverse them, so move them going the other way, and then just fill in that last remaining blank, add an arrow that goes in that direction instead. So by taking two edges and just switching them, I have been able to consider one possible neighbor of this particular configuration. And it looks like this neighbor is actually better. It looks like this probably travels a shorter distance in order to get through all the cities through this route than the current state did. And so you could imagine implementing this idea inside of a hill climbing or simulated annealing algorithm, where we repeat this process to try and take a state of this traveling salesman problem, look at all the neighbors, and then move to the neighbors if they’re better, or maybe even move to the neighbors if they’re worse, until we eventually settle upon some best solution that we’ve been able to find. And it turns out that these types of approximation algorithms, even if they don’t always find the very best solution, can often do pretty well at trying to find solutions that are helpful too. So that then was a look at local search, a particular category of algorithms that can be used for solving a particular type of problem, where we don’t really care about the path to the solution. I didn’t care about the steps I took to decide where the hospitals should go. I just cared about the solution itself. I just care about where the hospitals should be, or what the route through the traveling salesman journey really ought to be. Another type of algorithm that might come up are known as these categories of linear programming types of problems. And linear programming often comes up in the context where we’re trying to optimize for some mathematical function. But oftentimes, linear programming will come up when we might have real numbered values. So it’s not just discrete fixed values that we might have, but any decimal values that we might want to be able to calculate. And so linear programming is a family of types of problems where we might have a situation that looks like this, where the goal of linear programming is to minimize a cost function. And you can invert the numbers and say try and maximize it, but often we’ll frame it as trying to minimize a cost function that has some number of variables, x1, x2, x3, all the way up to xn, just some number of variables that are involved, things that I want to know the values to. And this cost function might have coefficients in front of those variables. And this is what we would call a linear equation, where we just have all of these variables that might be multiplied by a coefficient and then add it together. We’re not going to square anything or cube anything, because that’ll give us different types of equations. With linear programming, we’re just dealing with linear equations in addition to linear constraints, where a constraint is going to look something like if we sum up this particular equation that is just some linear combination of all of these variables, it is less than or equal to some bound b. And we might have a whole number of these various different constraints that we might place onto our linear programming exercise. And likewise, just as we can have constraints that are saying this linear equation is less than or equal to some bound b, it might also be equal to something. That if you want some sum of some combination of variables to be equal to a value, you can specify that. And we can also maybe specify that each variable has lower and upper bounds, that it needs to be a positive number, for example, or it needs to be a number that is less than 50, for example. And there are a number of other choices that we can make there for defining what the bounds of a variable are. But it turns out that if you can take a problem and formulate it in these terms, formulate the problem as your goal is to minimize a cost function, and you’re minimizing that cost function subject to particular constraints, subjects to equations that are of the form like this of some sequence of variables is less than a bound or is equal to some particular value, then there are a number of algorithms that already exist for solving these sorts of problems. So let’s go ahead and take a look at an example. Here’s an example of a problem that might come up in the world of linear programming. Often, this is going to come up when we’re trying to optimize for something. And we want to be able to do some calculations, and we have constraints on what we’re trying to optimize. And so it might be something like this. In the context of a factory, we have two machines, x1 and x2. x1 costs $50 an hour to run. x2 costs $80 an hour to run. And our goal, what we’re trying to do, our objective, is to minimize the total cost. So that’s what we’d like to do. But we need to do so subject to certain constraints. So there might be a labor constraint that x1 requires five units of labor per hour, x2 requires two units of labor per hour, and we have a total of 20 units of labor that we have to spend. So this is a constraint. We have no more than 20 units of labor that we can spend, and we have to spend it across x1 and x2, each of which requires a different amount of labor. And we might also have a constraint like this that tells us x1 is going to produce 10 units of output per hour, x2 is going to produce 12 units of output per hour, and the company needs 90 units of output. So we have some goal, something we need to achieve. We need to achieve 90 units of output, but there are some constraints that x1 can only produce 10 units of output per hour, x2 produces 12 units of output per hour. These types of problems come up quite frequently, and you can start to notice patterns in these types of problems, problems where I am trying to optimize for some goal, minimizing cost, maximizing output, maximizing profits, or something like that. And there are constraints that are placed on that process. And so now we just need to formulate this problem in terms of linear equations. So let’s start with this first point. Two machines, x1 and x2, x costs $50 an hour, x2 costs $80 an hour. Here we can come up with an objective function that might look like this. This is our cost function, rather. 50 times x1 plus 80 times x2, where x1 is going to be a variable representing how many hours do we run machine x1 for, x2 is going to be a variable representing how many hours are we running machine x2 for. And what we’re trying to minimize is this cost function, which is just how much it costs to run each of these machines per hour summed up. This is an example of a linear equation, just some combination of these variables plus coefficients that are placed in front of them. And I would like to minimize that total value. But I need to do so subject to these constraints. x1 requires 50 units of labor per hour, x2 requires 2, and we have a total of 20 units of labor to spend. And so that gives us a constraint of this form. 5 times x1 plus 2 times x2 is less than or equal to 20. 20 is the total number of units of labor we have to spend. And that’s spent across x1 and x2, each of which requires a different number of units of labor per hour, for example. And finally, we have this constraint here. x1 produces 10 units of output per hour, x2 produces 12, and we need 90 units of output. And so this might look something like this. That 10×1 plus 12×2, this is amount of output per hour, it needs to be at least 90. We can do better or great, but it needs to be at least 90. And if you recall from my formulation before, I said that generally speaking in linear programming, we deal with equals constraints or less than or equal to constraints. So we have a greater than or equal to sign here. That’s not a problem. Whenever we have a greater than or equal to sign, we can just multiply the equation by negative 1, and that’ll flip it around to a less than or equals negative 90, for example, instead of a greater than or equal to 90. And that’s going to be an equivalent expression that we can use to represent this problem. So now that we have this cost function and these constraints that it’s subject to, it turns out there are a number of algorithms that can be used in order to solve these types of problems. And these problems go a little bit more into geometry and linear algebra than we’re really going to get into. But the most popular of these types of algorithms are simplex, which was one of the first algorithms discovered for trying to solve linear programs. And later on, a class of interior point algorithms can be used to solve this type of problem as well. The key is not to understand exactly how these algorithms work, but to realize that these algorithms exist for efficiently finding solutions any time we have a problem of this particular form. And so we can take a look, for example, at the production directory here, where here I have a file called production.py, where here I’m using scipy, which was the library for a lot of science-related functions within Python. And I can go ahead and just run this optimization function in order to run a linear program. .linprog here is going to try and solve this linear program for me, where I provide to this expression, to this function call, all of the data about my linear program. So it needs to be in a particular format, which might be a little confusing at first. But this first argument to scipy.optimize.linprogramming is the cost function, which is in this case just an array or a list that has 50 and 80, because my original cost function was 50 times x1 plus 80 times x2. So I just tell Python, 50 and 80, those are the coefficients that I am now trying to optimize for. And then I provide all of the constraints. So the constraints, and I wrote them up above in comments, is the constraint 1 is 5×1 plus 2×2 is less than or equal to 20. And constraint 2 is negative 10×1 plus negative 12×2 is less than or equal to negative 90. And so scipy expects these constraints to be in a particular format. It first expects me to provide all of the coefficients for the upper bound equations, ub just for upper bound, where the coefficients of the first equation are 5 and 2, because we have 5×1 and 2×2. And the coefficients for the second equation are negative 10 and negative 12, because I have negative 10×1 plus negative 12×2. And then here, we provide it as a separate argument, just to keep things separate, what the actual bound is. What is the upper bound for each of these constraints? Well, for the first constraint, the upper bound is 20. That was constraint number 1. And then for constraint number 2, the upper bound is 90. So a bit of a cryptic way of representing it. It’s not quite as simple as just writing the mathematical equations. What really is being expected here are all of the coefficients and all of the numbers that are in these equations by first providing the coefficients for the cost function, then providing all the coefficients for the inequality constraints, and then providing all of the upper bounds for those inequality constraints. And once all of that information is there, then we can run any of these interior point algorithms or the simplex algorithm. Even if you don’t understand how it works, you can just run the function and figure out what the result should be. And here, I said if the result is a success, we were able to solve this problem. Go ahead and print out what the value of x1 and x2 should be. Otherwise, go ahead and print out no solution. And so if I run this program by running python production.py, it takes a second to calculate. But then we see here is what the optimal solution should be. x1 should run for 1.5 hours. x2 should run for 6.25 hours. And we were able to do this by just formulating the problem as a linear equation that we were trying to optimize, some cost that we were trying to minimize, and then some constraints that were placed on that. And many, many problems fall into this category of problems that you can solve if you can just figure out how to use equations and use these constraints to represent that general idea. And that’s a theme that’s going to come up a couple of times today, where we want to be able to take some problem and reduce it down to some problem we know how to solve in order to begin to find a solution and to use existing methods that we can use in order to find a solution more effectively or more efficiently. And it turns out that these types of problems, where we have constraints, show up in other ways too. And there’s an entire class of problems that’s more generally just known as constraint satisfaction problems. And we’re going to now take a look at how you might formulate a constraint satisfaction problem and how you might go about solving a constraint satisfaction problem. But the basic idea of a constraint satisfaction problem is we have some number of variables that need to take on some values. And we need to figure out what values each of those variables should take on. But those variables are subject to particular constraints that are going to limit what values those variables can actually take on. So let’s take a look at a real world example, for example. Let’s look at exam scheduling, that I have four students here, students 1, 2, 3, and 4. Each of them is taking some number of different classes. Classes here are going to be represented by letters. So student 1 is enrolled in courses A, B, and C. Student 2 is enrolled in courses B, D, and E, so on and so forth. And now, say university, for example, is trying to schedule exams for all of these courses. But there are only three exam slots on Monday, Tuesday, and Wednesday. And we have to schedule an exam for each of these courses. But the constraint now, the constraint we have to deal with with the scheduling, is that we don’t want anyone to have to take two exams on the same day. We would like to try and minimize that or eliminate it if at all possible. So how do we begin to represent this idea? How do we structure this in a way that a computer with an AI algorithm can begin to try and solve the problem? Well, let’s in particular just look at these classes that we might take and represent each of the courses as some node inside of a graph. And what we’ll do is we’ll create an edge between two nodes in this graph if there is a constraint between those two nodes. So what does this mean? Well, we can start with student 1, who’s enrolled in courses A, B, and C. What that means is that A and B can’t have an exam at the same time. A and C can’t have an exam at the same time. And B and C also can’t have an exam at the same time. And I can represent that in this graph by just drawing edges. One edge between A and B, one between B and C, and then one between C and A. And that encodes now the idea that between those nodes, there is a constraint. And in particular, the constraint happens to be that these two can’t be equal to each other, though there are other types of constraints that are possible, depending on the type of problem that you’re trying to solve. And then we can do the same thing for each of the other students. So for student 2, who’s enrolled in courses B, D, and E, well, that means B, D, and E, those all need to have edges that connect each other as well. Student 3 is enrolled in courses C, E, and F. So we’ll go ahead and take C, E, and F and connect those by drawing edges between them too. And then finally, student 4 is enrolled in courses E, F, and G. And we can represent that by drawing edges between E, F, and G, although E and F already had an edge between them. We don’t need another one, because this constraint is just encoding the idea that course E and course F cannot have an exam on the same day. So this then is what we might call the constraint graph. There’s some graphical representation of all of my variables, so to speak, and the constraints between those possible variables. Where in this particular case, each of the constraints represents an inequality constraint, that an edge between B and D means whatever value the variable B takes on cannot be the value that the variable D takes on as well. So what then actually is a constraint satisfaction problem? Well, a constraint satisfaction problem is just some set of variables, x1 all the way through xn, some set of domains for each of those variables. So every variable needs to take on some values. Maybe every variable has the same domain, but maybe each variable has a slightly different domain. And then there’s a set of constraints, and we’ll just call a set C, that is some constraints that are placed upon these variables, like x1 is not equal to x2. But there could be other forms too, like maybe x1 equals x2 plus 1 if these variables are taking on numerical values in their domain, for example. The types of constraints are going to vary based on the types of problems. And constraint satisfaction shows up all over the place as well, in any situation where we have variables that are subject to particular constraints. So one popular game is Sudoku, for example, this 9 by 9 grid where you need to fill in numbers in each of these cells, but you want to make sure there’s never a duplicate number in any row, or in any column, or in any grid of 3 by 3 cells, for example. So what might this look like as a constraint satisfaction problem? Well, my variables are all of the empty squares in the puzzle. So represented here is just like an x comma y coordinate, for example, as all of the squares where I need to plug in a value, where I don’t know what value it should take on. The domain is just going to be all of the numbers from 1 through 9, any value that I could fill in to one of these cells. So that is going to be the domain for each of these variables. And then the constraints are going to be of the form, like this cell can’t be equal to this cell, can’t be equal to this cell, can’t be, and all of these need to be different, for example, and same for all of the rows, and the columns, and the 3 by 3 squares as well. So those constraints are going to enforce what values are actually allowed. And we can formulate the same idea in the case of this exam scheduling problem, where the variables we have are the different courses, a up through g. The domain for each of these variables is going to be Monday, Tuesday, and Wednesday. Those are the possible values each of the variables can take on, that in this case just represent when is the exam for that class. And then the constraints are of this form, a is not equal to b, a is not equal to c, meaning a and b can’t have an exam on the same day, a and c can’t have an exam on the same day. Or more formally, these two variables cannot take on the same value within their domain. So that then is this formulation of a constraint satisfaction problem that we can begin to use to try and solve this problem. And constraints can come in a number of different forms. There are hard constraints, which are constraints that must be satisfied for a correct solution. So something like in the Sudoku puzzle, you cannot have this cell and this cell that are in the same row take on the same value. That is a hard constraint. But problems can also have soft constraints, where these are constraints that express some notion of preference, that maybe a and b can’t have an exam on the same day, but maybe someone has a preference that a’s exam is earlier than b’s exam. It doesn’t need to be the case with some expression that some solution is better than another solution. And in that case, you might formulate the problem as trying to optimize for maximizing people’s preferences. You want people’s preferences to be satisfied as much as possible. In this case, though, we’ll mostly just deal with hard constraints, constraints that must be met in order to have a correct solution to the problem. So we want to figure out some assignment of these variables to their particular values that is ultimately going to give us a solution to the problem by allowing us to assign some day to each of the classes such that we don’t have any conflicts between classes. So it turns out that we can classify the constraints in a constraint satisfaction problem into a number of different categories. The first of those categories are perhaps the simplest of the types of constraints, which are known as unary constraints, where unary constraint is a constraint that just involves a single variable. For example, a unary constraint might be something like, a does not equal Monday, meaning Course A cannot have its exam on Monday. If for some reason the instructor for the course isn’t available on Monday, you might have a constraint in your problem that looks like this, something that just has a single variable a in it, and maybe says a is not equal to Monday, or a is equal to something, or in the case of numbers greater than or less than something, a constraint that just has one variable, we consider to be a unary constraint. And this is in contrast to something like a binary constraint, which is a constraint that involves two variables, for example. So this would be a constraint like the ones we were looking at before. Something like a does not equal b is an example of a binary constraint, because it is a constraint that has two variables involved in it, a and b. And we represented that using some arc or some edge that connects variable a to variable b. And using this knowledge of, OK, what is a unary constraint? What is a binary constraint? There are different types of things we can say about a particular constraint satisfaction problem. And one thing we can say is we can try and make the problem node consistent. So what does node consistency mean? Node consistency means that we have all of the values in a variable’s domain satisfying that variable’s unary constraints. So for each of the variables inside of our constraint satisfaction problem, if all of the values satisfy the unary constraints for that particular variable, we can say that the entire problem is node consistent, or we can even say that a particular variable is node consistent if we just want to make one node consistent within itself. So what does that actually look like? Let’s look at now a simplified example, where instead of having a whole bunch of different classes, we just have two classes, a and b, each of which has an exam on either Monday or Tuesday or Wednesday. So this is the domain for the variable a, and this is the domain for the variable b. And now let’s imagine we have these constraints, a not equal to Monday, b not equal to Tuesday, b not equal to Monday, a not equal to b. So those are the constraints that we have on this particular problem. And what we can now try to do is enforce node consistency. And node consistency just means we make sure that all of the values for any variable’s domain satisfy its unary constraints. And so we could start by trying to make node a node consistent. Is it consistent? Does every value inside of a’s domain satisfy its unary constraints? Well, initially, we’ll see that Monday does not satisfy a’s unary constraints, because we have a constraint, a unary constraint here, that a is not equal to Monday. But Monday is still in a’s domain. And so this is something that is not node consistent, because we have Monday in the domain. But this is not a valid value for this particular node. And so how do we make this node consistent? Well, to make the node consistent, what we’ll do is we’ll just go ahead and remove Monday from a’s domain. Now a can only be on Tuesday or Wednesday, because we had this constraint that said a is not equal to Monday. And at this point now, a is node consistent. For each of the values that a can take on, Tuesday and Wednesday, there is no constraint that is a unary constraint that conflicts with that idea. There is no constraint that says that a can’t be Tuesday. There is no unary constraint that says that a cannot be on Wednesday. And so now we can turn our attention to b. b also has a domain, Monday, Tuesday, and Wednesday. And we can begin to see whether those variables satisfy the unary constraints as well. Well, here is a unary constraint, b is not equal to Tuesday. And that does not appear to be satisfied by this domain of Monday, Tuesday, and Wednesday, because Tuesday, this possible value that the variable b could take on is not consistent with this unary constraint, that b is not equal to Tuesday. So to solve that problem, we’ll go ahead and remove Tuesday from b’s domain. Now b’s domain only contains Monday and Wednesday. But as it turns out, there’s yet another unary constraint that we placed on the variable b, which is here. b is not equal to Monday. And that means that this value, Monday, inside of b’s domain, is not consistent with b’s unary constraints, because we have a constraint that says the b cannot be Monday. And so we can remove Monday from b’s domain. And now we’ve made it through all of the unary constraints. We’ve not yet considered this constraint, which is a binary constraint. But we’ve considered all of the unary constraints, all of the constraints that involve just a single variable. And we’ve made sure that every node is consistent with those unary constraints. So we can say that now we have enforced node consistency, that for each of these possible nodes, we can pick any of these values in the domain. And there won’t be a unary constraint that is violated as a result of it. So node consistency is fairly easy to enforce. We just take each node, make sure the values in the domain satisfy the unary constraints. Where things get a little bit more interesting is when we consider different types of consistency, something like arc consistency, for example. And arc consistency refers to when all of the values in a variable’s domain satisfy the variable’s binary constraints. So when we’re looking at trying to make a arc consistent, we’re no longer just considering the unary constraints that involve a. We’re trying to consider all of the binary constraints that involve a as well. So any edge that connects a to another variable inside of that constraint graph that we were taking a look at before. Put a little bit more formally, arc consistency. And arc really is just another word for an edge that connects two of these nodes inside of our constraint graph. We can define arc consistency a little more precisely like this. In order to make some variable x arc consistent with respect to some other variable y, we need to remove any element from x’s domain to make sure that every choice for x, every choice in x’s domain, has a possible choice for y. So put another way, if I have a variable x and I want to make x an arc consistent, then I’m going to look at all of the possible values that x can take on and make sure that for all of those possible values, there is still some choice that I can make for y, if there’s some arc between x and y, to make sure that y has a possible option that I can choose as well. So let’s look at an example of that going back to this example from before. We enforced node consistency already by saying that a can only be on Tuesday or Wednesday because we knew that a could not be on Monday. And we also said that b’s only domain only consists of Wednesday because we know that b does not equal Tuesday and also b does not equal Monday. So now let’s begin to consider arc consistency. Let’s try and make a arc consistent with b. And what that means is to make a arc consistent with respect to b means that for any choice we make in a’s domain, there is some choice we can make in b’s domain that is going to be consistent. And we can try that. For a, we can choose Tuesday as a possible value for a. If I choose Tuesday for a, is there a value for b that satisfies the binary constraint? Well, yes, b Wednesday would satisfy this constraint that a does not equal b because Tuesday does not equal Wednesday. However, if we chose Wednesday for a, well, then there is no choice in b’s domain that satisfies this binary constraint. There is no way I can choose something for b that satisfies a does not equal b because I know b must be Wednesday. And so if ever I run into a situation like this where I see that here is a possible value for a such that there is no choice of value for b that satisfies the binary constraint, well, then this is not arc consistent. And to make it arc consistent, I would need to take Wednesday and remove it from a’s domain. Because Wednesday was not going to be a possible choice I can make for a because it wasn’t consistent with this binary constraint for b. There was no way I could choose Wednesday for a and still have an available solution by choosing something for b as well. So here now, I’ve been able to enforce arc consistency. And in doing so, I’ve actually solved this entire problem, that given these constraints where a and b can have exams on either Monday or Tuesday or Wednesday, the only solution, as it would appear, is that a’s exam must be on Tuesday and b’s exam must be on Wednesday. And that is the only option available to me. So if we want to apply our consistency to a larger graph, not just looking at one particular pair of our consistency, there are ways we can do that too. And we can begin to formalize what the pseudocode would look like for trying to write an algorithm that enforces arc consistency. And we’ll start by defining a function called revise. Revise is going to take as input a CSP, otherwise known as a constraint satisfaction problem, and also two variables, x and y. And what revise is going to do is it is going to make x arc consistent with respect to y, meaning remove anything from x’s domain that doesn’t allow for a possible option for y. How does this work? Well, we’ll go ahead and first keep track of whether or not we’ve made a revision. Revise is ultimately going to return true or false. It’ll return true in the event that we did make a revision to x’s domain. It’ll return false if we didn’t make any change to x’s domain. And we’ll see in a moment why that’s going to be helpful. But we start by saying revised equals false. We haven’t made any changes. Then we’ll say, all right, let’s go ahead and loop over all of the possible values in x’s domain. So loop over x’s domain for each little x in x’s domain. I want to make sure that for each of those choices, I have some available choice in y that satisfies the binary constraints that are defined inside of my CSP, inside of my constraint satisfaction problem. So if ever it’s the case that there is no value y in y’s domain that satisfies the constraint for x and y, well, if that’s the case, that means that this value x shouldn’t be in x’s domain. So we’ll go ahead and delete x from x’s domain. And I’ll set revised equal to true because I did change x’s domain. I changed x’s domain by removing little x. And I removed little x because it wasn’t art consistent. There was no way I could choose a value for y that would satisfy this xy constraint. So in this case, we’ll go ahead and set revised equal true. And we’ll do this again and again for every value in x’s domain. Sometimes it might be fine. In other cases, it might not allow for a possible choice for y, in which case we need to remove this value from x’s domain. And at the end, we just return revised to indicate whether or not we actually made a change. So this function, then, this revised function is effectively an implementation of what you saw me do graphically a moment ago. And it makes one variable, x, arc consistent with another variable, in this case, y. But generally speaking, when we want to enforce our consistency, we’ll often want to enforce our consistency not just for a single arc, but for the entire constraint satisfaction problem. And it turns out there’s an algorithm to do that as well. And that algorithm is known as AC3. AC3 takes a constraint satisfaction problem. And it enforces our consistency across the entire problem. How does it do that? Well, it’s going to basically maintain a queue or basically just a line of all of the arcs that it needs to make consistent. And over time, we might remove things from that queue as we begin dealing with our consistency. And we might need to add things to that queue as well if there are more things we need to make arc consistent. So we’ll go ahead and start with a queue that contains all of the arcs in the constraint satisfaction problem, all of the edges that connect two nodes that have some sort of binary constraint between them. And now, as long as the queue is non-empty, there is work to be done. The queue is all of the things that we need to make arc consistent. So as long as the queue is non-empty, there’s still things we have to do. What do we have to do? Well, we’ll start by de-queuing from the queue, remove something from the queue. And strictly speaking, it doesn’t need to be a queue, but a queue is a traditional way of doing this. We’ll de-queue from the queue, and that’ll give us an arc, x and y, these two variables where I would like to make x arc consistent with y. So how do we make x arc consistent with y? Well, we can go ahead and just use that revise function that we talked about a moment ago. We called the revise function, passing as input the constraint satisfaction problem, and also these variables x and y, because I want to make x arc consistent with y. In other words, remove any values from x’s domain that don’t leave an available option for y. And recall, what does revised return? Well, it returns true if we actually made a change, if we removed something from x’s domain, because there wasn’t an available option for y, for example. And it returns false if we didn’t make any change to x’s domain at all. And it turns out if revised returns false, if we didn’t make any changes, well, then there’s not a whole lot more work to be done here for this arc. We can just move ahead to the next arc that’s in the queue. But if we did make a change, if we did reduce x’s domain by removing values from x’s domain, well, then what we might realize is that this creates potential problems later on, that it might mean that some arc that was arc consistent with x, that node might no longer be arc consistent with x, because while there used to be an option that we could choose for x, now there might not be, because now we might have removed something from x that was necessary for some other arc to be arc consistent. And so if ever we did revise x’s domain, we’re going to need to add some things to the queue, some additional arcs that we might want to check. How do we do that? Well, first thing we want to check is to make sure that x’s domain is not 0. If x’s domain is 0, that means there are no available options for x at all. And that means that there’s no way you can solve the constraint satisfaction problem. If we’ve removed everything from x’s domain, we’ll go ahead and just return false here to indicate there’s no way to solve the problem, because there’s nothing left in x’s domain. But otherwise, if there are things left in x’s domain, but fewer things than before, well, then what we’ll do is we’ll loop over each variable z that is in all of x’s neighbors, except for y, y we already handled. But we’ll consider all of x’s other’s neighbors and ask ourselves, all right, will that arc from each of those z’s to x, that arc might no longer be arc consistent, because while for each z, there might have been a possible option we could choose for x to correspond with each of z’s possible values, now there might not be, because we removed some elements from x’s domain. And so what we’ll do here is we’ll go ahead and enqueue, adding something to the queue, this arc zx for all of those neighbors z. So we need to add back some arcs to the queue in order to continue to enforce arc consistency. At the very end, if we make it through all this process, then we can return true. But this now is AC3, this algorithm for enforcing arc consistency on a constraint satisfaction problem. And the big idea is really just keep track of all of the arcs that we might need to make arc consistent, make it arc consistent by calling the revise function. And if we did revise it, then there are some new arcs that might need to be added to the queue in order to make sure that everything is still arc consistent, even after we’ve removed some of the elements from a particular variable’s domain. So what then would happen if we tried to enforce arc consistency on a graph like this, on a graph where each of these variables has a domain of Monday, Tuesday, and Wednesday? Well, it turns out that by enforcing arc consistency on this graph, well, it can solve some types of problems. Nothing actually changes here. For any particular arc, just considering two variables, there’s always a way for me to just, for any of the choices I make for one of them, make a choice for the other one, because there are three options, and I just need the two to be different from each other. So this is actually quite easy to just take an arc and just declare that it is arc consistent, because if I pick Monday for D, then I just pick something that isn’t Monday for B. In arc consistency, we only consider consistency between a binary constraint between two nodes, and we’re not really considering all of the rest of the nodes yet. So just using AC3, the enforcement of arc consistency, that can sometimes have the effect of reducing domains to make it easier to find solutions, but it will not always actually solve the problem. We might still need to somehow search to try and find a solution. And we can use classical traditional search algorithms to try to do so. You’ll recall that a search problem generally consists of these parts. We have some initial state, some actions, a transition model that takes me from one state to another state, a goal test to tell me have I satisfied my objective correctly, and then some path cost function, because in the case of like maze solving, I was trying to get to my goal as quickly as possible. So you could formulate a CSP, or a constraint satisfaction problem, as one of these types of search problems. The initial state will just be an empty assignment, where an assignment is just a way for me to assign any particular variable to any particular value. So if an empty assignment is no variables that are assigned to any values yet, then the action I can take is adding some new variable equals value pair to that assignment, saying for this assignment, let me add a new value for this variable. And the transition model just defines what happens when you take that action. You get a new assignment that has that variable equal to that value inside of it. The goal test is just checking to make sure all the variables have been assigned and making sure all the constraints have been satisfied. And the path cost function is sort of irrelevant. I don’t really care about what the path really is. I just care about finding some assignment that actually satisfies all of the constraints. So really, all the paths have the same cost. I don’t really care about the path to the goal. I just care about the solution itself, much as we’ve talked about now before. The problem here, though, is that if we just implement this naive search algorithm just by implementing like breadth-first search or depth-first search, this is going to be very, very inefficient. And there are ways we can take advantage of efficiencies in the structure of a constraint satisfaction problem itself. And one of the key ideas is that we can really just order these variables. And it doesn’t matter what order we assign variables in. The assignment a equals 2 and then b equals 8 is identical to the assignment of b equals 8 and then a equals 2. Switching the order doesn’t really change anything about the fundamental nature of that assignment. And so there are some ways that we can try and revise this idea of a search algorithm to apply it specifically for a problem like a constraint satisfaction problem. And it turns out the search algorithm we’ll generally use when talking about constraint satisfaction problems is something known as backtracking search. And the big idea of backtracking search is we’ll go ahead and make assignments from variables to values. And if ever we get stuck, we arrive at a place where there is no way we can make any forward progress while still preserving the constraints that we need to enforce, we’ll go ahead and backtrack and try something else instead. So the very basic sketch of what backtracking search looks like is it looks like this. Function called backtrack that takes as input an assignment and a constraint satisfaction problem. So initially, we don’t have any assigned variables. So when we begin backtracking search, this assignment is just going to be the empty assignment with no variables inside of it. But we’ll see later this is going to be a recursive function. So backtrack takes as input the assignment and the problem. If the assignment is complete, meaning all of the variables have been assigned, we just return that assignment. That, of course, won’t be true initially, because we start with an empty assignment. But over time, we might add things to that assignment. So if ever the assignment actually is complete, then we’re done. Then just go ahead and return that assignment. But otherwise, there is some work to be done. So what we’ll need to do is select an unassigned variable for this particular problem. So we need to take the problem, look at the variables that have already been assigned, and pick a variable that has not yet been assigned. And I’ll go ahead and take that variable. And then I need to consider all of the values in that variable’s domain. So we’ll go ahead and call this domain values function. We’ll talk a little more about that later, that takes a variable and just gives me back an ordered list of all of the values in its domain. So I’ve taken a random unselected variable. I’m going to loop over all of the possible values. And the idea is, let me just try all of these values as possible values for the variable. So if the value is consistent with the assignment so far, it doesn’t violate any of the constraints, well then let’s go ahead and add variable equals value to the assignment because it’s so far consistent. And now let’s recursively call backtrack to try and make the rest of the assignments also consistent. So I’ll go ahead and call backtrack on this new assignment that I’ve added the variable equals value to. And now I recursively call backtrack and see what the result is. And if the result isn’t a failure, well then let me just return that result. And otherwise, what else could happen? Well, if it turns out the result was a failure, well then that means this value was probably a bad choice for this particular variable because when I assigned this variable equal to that value, eventually down the road I ran into a situation where I violated constraints. There was nothing more I could do. So now I’ll remove variable equals value from the assignment, effectively backtracking to say, all right, that value didn’t work. Let’s try another value instead. And then at the very end, if we were never able to return a complete assignment, we’ll just go ahead and return failure because that means that none of the values worked for this particular variable. This now is the idea for backtracking search, to take each of the variables, try values for them, and recursively try backtracking search, see if we can make progress. And if ever we run into a dead end, we run into a situation where there is no possible value we can choose that satisfies the constraints, we return failure. And that propagates up, and eventually we make a different choice by going back and trying something else instead. So let’s put this algorithm into practice. Let’s actually try and use backtracking search to solve this problem now, where I need to figure out how to assign each of these courses to an exam slot on Monday or Tuesday or Wednesday in such a way that it satisfies these constraints, that each of these edges mean those two classes cannot have an exam on the same day. So I can start by just starting at a node. It doesn’t really matter which I start with, but in this case, I’ll just start with A. And I’ll ask the question, all right, let me loop over the values in the domain. And maybe in this case, I’ll just start with Monday and say, all right, let’s go ahead and assign A to Monday. We’ll just go and order Monday, Tuesday, Wednesday. And now let’s consider node B. So I’ve made an assignment to A, so I recursively call backtrack with this new part of the assignment. And now I’m looking to pick another unassigned variable like B. And I’ll say, all right, maybe I’ll start with Monday, because that’s the very first value in B’s domain. And I ask, all right, does Monday violate any constraints? And it turns out, yes, it does. It violates this constraint here between A and B, because A and B are now both on Monday, and that doesn’t work, because B can’t be on the same day as A. So that doesn’t work. So we might instead try Tuesday, try the next value in B’s domain. And is that consistent with the assignment so far? Well, yeah, B, Tuesday, A, Monday, that is consistent so far, because they’re not on the same day. So that’s good. Now we can recursively call backtrack. Try again. Pick another unassigned variable, something like D, and say, all right, let’s go through its possible values. Is Monday consistent with this assignment? Well, yes, it is. B and D are on different days, Monday versus Tuesday. And A and B are also on different days, Monday versus Tuesday. So that’s fine so far, too. We’ll go ahead and try again. Maybe we’ll go to this variable here, E. Say, can we make that consistent? Let’s go through the possible values. We’ve recursively called backtrack. We might start with Monday and say, all right, that’s not consistent, because D and E now have exams on the same day. So we might try Tuesday instead, going to the next one. Ask, is that consistent? Well, no, it’s not, because B and E, those have exams on the same day. And so we try, all right, is Wednesday consistent? And in turn, it’s like, all right, yes, it is. Wednesday is consistent, because D and E now have exams on different days. B and E now have exams on different days. All seems to be well so far. I recursively call backtrack, select another unassigned variable, we’ll say maybe choose C this time, and say, all right, let’s try the values that C could take on. Let’s start with Monday. And it turns out that’s not consistent, because now A and C both have exams on the same day. So I try Tuesday and say, that’s not consistent either, because B and C now have exams on the same day. And then I say, all right, let’s go ahead and try Wednesday. But that’s not consistent either, because C and E each have exams on the same day too. So now we’ve gone through all the possible values for C, Monday, Tuesday, and Wednesday. And none of them are consistent. There is no way we can have a consistent assignment. Backtrack, in this case, will return a failure. And so then we’d say, all right, we have to backtrack back to here. Well, now for E, we’ve tried all of Monday, Tuesday, and Wednesday. And none of those work, because Wednesday, which seemed to work, turned out to be a failure. So that means there’s no possible way we can assign E. So that’s a failure too. We have to go back up to D, which means that Monday assignment to D, that must be wrong. We must try something else. So we can try, all right, what if instead of Monday, we try Tuesday? Tuesday, it turns out, is not consistent, because B and D now have an exam on the same day. But Wednesday, as it turns out, works. And now we can begin to mix and forward progress again. We go back to E and say, all right, which of these values works? Monday turns out to work by not violating any constraints. Then we go up to C now. Monday doesn’t work, because it violates a constraint. Violates two, actually. Tuesday doesn’t work, because it violates a constraint as well. But Wednesday does work. Then we can go to the next variable, F, and say, all right, does Monday work? We’ll know. It violates a constraint. But Tuesday does work. And then finally, we can look at the last variable, G, recursively calling backtrack one more time. Monday is inconsistent. That violates a constraint. Tuesday also violates a constraint. But Wednesday, that doesn’t violate a constraint. And so now at this point, we recursively call backtrack one last time. We now have a satisfactory assignment of all of the variables. And at this point, we can say that we are now done. We have now been able to successfully assign a variable or a value to each one of these variables in such a way that we’re not violating any constraints. We’re going to go ahead and have classes A and E have their exams on Monday. Classes B and F can have their exams on Tuesday. And classes C, D, and G can have their exams on Wednesday. And there’s no violated constraints that might come up there. So that then was a graphical look at how this might work. Let’s now take a look at some code we could use to actually try and solve this problem as well. So here I’ll go ahead and go into the scheduling directory. We’re here now. We’ll start by looking at schedule0.py. We’re here. I define a list of variables, A, B, C, D, E, F, G. Those are all different classes. Then underneath that, I define my list of constraints. So constraint A and B. That is a constraint because they can’t be on the same day. Likewise, A and C, B and C, so on and so forth, enforcing those exact same constraints. And here then is what the backtracking function might look like. First, if the assignment is complete, if I’ve made an assignment of every variable to a value, go ahead and just return that assignment. Then we’ll select an unassigned variable from that assignment. Then for each of the possible values in the domain, Monday, Tuesday, Wednesday, let’s go ahead and create a new assignment that assigns the variable to that value. I’ll call this consistent function, which I’ll show you in a moment, that just checks to make sure this new assignment is consistent. But if it is consistent, we’ll go ahead and call backtrack to go ahead and continue trying to run backtracking search. And as long as the result is not none, meaning it wasn’t a failure, we can go ahead and return that result. But if we make it through all the values and nothing works, then it is a failure. There’s no solution. We go ahead and return none here. What do these functions do? Select unassigned variable is just going to choose a variable not yet assigned. So it’s going to loop over all the variables. And if it’s not already assigned, we’ll go ahead and just return that variable. And what does the consistent function do? Well, the consistent function goes through all the constraints. And if we have a situation where we’ve assigned both of those values to variables, but they are the same, well, then that is a violation of the constraint, in which case we’ll return false. But if nothing is inconsistent, then the assignment is consistent and will return true. And then all the program does is it calls backtrack on an empty assignment, an empty dictionary that has no variable assigned and no values yet, save that inside a solution, and then print out that solution. So by running this now, I can run Python schedule0.py. And what I get as a result of that is an assignment of all these variables to values. And it turns out we assign a to Monday as we would expect, b to Tuesday, c to Wednesday, exactly the same type of thing we were talking about before, an assignment of each of these variables to values that doesn’t violate any constraints. And I had to do a fair amount of work in order to implement this idea myself. I had to write the backtrack function that went ahead and went through this process of recursively trying to do this backtracking search. But it turns out the constraint satisfaction problems are so popular that there exist many libraries that already implement this type of idea. Again, as with before, the specific library is not as important as the fact that libraries do exist. This is just one example of a Python constraint library, where now, rather than having to do all the work from scratch inside of schedule1.py, I’m just taking advantage of a library that implements a lot of these ideas already. So here, I create a new problem, add variables to it with particular domains. I add a whole bunch of these individual constraints, where I call addConstraint and pass in a function describing what the constraint is. And the constraint basically says the function that takes two variables, x and y, and makes sure that x is not equal to y, enforcing the idea that these two classes cannot have exams on the same day. And then, for any constraint satisfaction problem, I can call getSolutions to get all the solutions to that problem. And then, for each of those solutions, print out what that solution happens to be. And if I run python schedule1.py, and now see, there are actually a number of different solutions that can be used to solve the problem. There are, in fact, six different solutions, assignments of variables to values that will give me a satisfactory answer to this constraint satisfaction problem. So this then was an implementation of a very basic backtracking search method, where really we just went through each of the variables, picked one that wasn’t assigned, tried the possible values the variable could take on. And then, if it worked, if it didn’t violate any constraints, then we kept trying other variables. And if ever we hit a dead end, we had to backtrack. But ultimately, we might be able to be a little bit more intelligent about how we do this in order to improve the efficiency of how we solve these sorts of problems. And one thing we might imagine trying to do is going back to this idea of inference, using the knowledge we know to be able to draw conclusions in order to make the rest of the problem solving process a little bit easier. And let’s now go back to where we got stuck in this problem the first time. When we were solving this constraint satisfaction problem, we dealt with B. And then we went on to D. And we went ahead and just assigned D to Monday, because that seemed to work with the assignment so far. It didn’t violate any constraints. But it turned out that later on that choice turned out to be a bad one, that that choice wasn’t consistent with the rest of the values that we could take on here. And the question is, is there anything we could do to avoid getting into a situation like this, avoid trying to go down a path that’s ultimately not going to lead anywhere by taking advantage of knowledge that we have initially? And it turns out we do have that kind of knowledge. We can look at just the structure of this graph so far. And we can say that right now C’s domain, for example, contains values Monday, Tuesday, and Wednesday. And based on those values, we can say that this graph is not arc consistent. Recall that arc consistency is all about making sure that for every possible value for a particular node, that there is some other value that we are able to choose. And as we can see here, Monday and Tuesday are not going to be possible values that we can choose for C. They’re not going to be consistent with a node like B, for example, because B is equal to Tuesday, which means that C cannot be Tuesday. And because A is equal to Monday, C also cannot be Monday. So using that information, by making C arc consistent with A and B, we could remove Monday and Tuesday from C’s domain and just leave C with Wednesday, for example. And if we continued to try and enforce arc consistency, we’d see there are some other conclusions we can draw as well. We see that B’s only option is Tuesday and C’s only option is Wednesday. And so if we want to make E arc consistent, well, E can’t be Tuesday, because that wouldn’t be arc consistent with B. And E can’t be Wednesday, because that wouldn’t be arc consistent with C. So we can go ahead and say E and just set that equal to Monday, for example. And then we can begin to do this process again and again, that in order to make D arc consistent with B and E, then D would have to be Wednesday. That’s the only possible option. And likewise, we can make the same judgments for F and G as well. And it turns out that without having to do any additional search, just by enforcing arc consistency, we were able to actually figure out what the assignment of all the variables should be without needing to backtrack at all. And the way we did that is by interleaving this search process and the inference step, by this step of trying to enforce arc consistency. And the algorithm to do this is often called just the maintaining arc consistency algorithm, which just enforces arc consistency every time we make a new assignment of a value to an existing variable. So sometimes we can enforce our consistency using that AC3 algorithm at the very beginning of the problem before we even begin searching in order to limit the domain of the variables in order to make it easier to search. But we can also take advantage of the interleaving of enforcing our consistency with search such that every time in the search process we make a new assignment, we go ahead and enforce arc consistency as well to make sure that we’re just eliminating possible values from domains whenever possible. And how do we do this? Well, this is really equivalent to just every time we make a new assignment to a variable x. We’ll go ahead and call our AC3 algorithm, this algorithm that enforces arc consistency on a constraint satisfaction problem. And we go ahead and call that, starting it with a Q, not of all of the arcs, which we did originally, but just of all of the arcs that we want to make arc consistent with x, this thing that we have just made an assignment to. So all arcs yx, where y is a neighbor of x, something that shares a constraint with x, for example. And by maintaining arc consistency in the backtracking search process, we can ultimately make our search process a little bit more efficient. And so this is the revised version of this backtrack function. Same as before, the changes here are highlighted in yellow. Every time we add a new variable equals value to our assignment, we’ll go ahead and run this inference procedure, which might do a number of different things. But one thing it could do is call the maintaining arc consistency algorithm to make sure we’re able to enforce arc consistency on the problem. And we might be able to draw new inferences as a result of that process. Get new guarantees of this variable needs to be equal to that value, for example. That might happen one time. It might happen many times. And so long as those inferences are not a failure, as long as they don’t lead to a situation where there is no possible way to make forward progress, well, then we can go ahead and add those inferences, those new knowledge, that new pieces of knowledge I know about what variables should be assigned to what values, I can add those to the assignment in order to more quickly make forward progress by taking advantage of information that I can just deduce, information I know based on the rest of the structure of the constraint satisfaction problem. And the only other change I’ll need to make now is if it turns out this value doesn’t work, well, then down here, I’ll go ahead and need to remove not only variable equals value, but also any of those inferences that I made, remove that from the assignment as well. So here, then, we’re often able to solve the problem by backtracking less than we might originally have needed to, just by taking advantage of the fact that every time we make a new assignment of one variable to one value, that might reduce the domains of other variables as well. And we can use that information to begin to more quickly draw conclusions in order to try and solve the problem more efficiently as well. And it turns out there are other heuristics we can use to try and improve the efficiency of our search process as well. And it really boils down to a couple of these functions that I’ve talked about, but we haven’t really talked about how they’re working. And one of them is this function here, select unassigned variable, where we’re selecting some variable in the constraint satisfaction problem that has not yet been assigned. So far, I’ve sort of just been selecting variables randomly, just like picking one variable and one unassigned variable in order to decide, all right, this is the variable that we’re going to assign next, and then going from there. But it turns out that by being a little bit intelligent, by following certain heuristics, we might be able to make the search process much more efficient just by choosing very carefully which variable we should explore next. So some of those heuristics include the minimum remaining values, or MRV heuristic, which generally says that if I have a choice between which variable I should select, I should select the variable with the smallest domain, the variable that has the fewest number of remaining values left. With the idea being, if there are only two remaining values left, well, I may as well prune one of them very quickly in order to get to the other, because one of those two has got to be the solution, if a solution does exist. Sometimes minimum remaining values might not give a conclusive result if all the nodes have the same number of remaining values, for example. And in that case, another heuristic that can be helpful to look at is the degree heuristic. The degree of a node is the number of nodes that are attached to that node, the number of nodes that are constrained by that particular node. And if you imagine which variable should I choose, should I choose a variable that has a high degree that is connected to a lot of different things, or a variable with a low degree that is not connected to a lot of different things, well, it can often make sense to choose the variable that has the highest degree that is connected to the most other nodes as the thing you would search first. Why is that the case? Well, it’s because by choosing a variable with a high degree, that is immediately going to constrain the rest of the variables more, and it’s more likely to be able to eliminate large sections of the state space that you don’t need to search through at all. So what could this actually look like? Let’s go back to this search problem here. In this particular case, I’ve made an assignment here. I’ve made an assignment here. And the question is, what should I look at next? And according to the minimum remaining values heuristic, what I should choose is the variable that has the fewest remaining possible values. And in this case, that’s this node here, node C, that only has one variable left in this domain, which in this case is Wednesday, which is a very reasonable choice of a next assignment to make, because I know it’s the only option, for example. I know that the only possible option for C is Wednesday, so I may as well make that assignment and then potentially explore the rest of the space after that. But meanwhile, at the very start of the problem, when I didn’t have any knowledge of what nodes should have what values yet, I still had to pick what node should be the first one that I try and assign a value to. And I arbitrarily just chose the one at the top, node A originally. But we can be more intelligent about that. We can look at this particular graph. All of them have domains of the same size, domain of size 3. So minimum remaining values doesn’t really help us there. But we might notice that node E has the highest degree. It is connected to the most things. And so perhaps it makes sense to begin our search, rather than starting at node A at the very top, start with the node with the highest degree. Start by searching from node E, because from there, that’s going to much more easily allow us to enforce the constraints that are nearby, eliminating large portions of the search space that I might not need to search through. And in fact, by starting with E, we can immediately then assign other variables. And following that, we can actually assign the rest of the variables without needing to do any backtracking at all, even if I’m not using this inference procedure. Just by starting with a node that has a high degree, that is going to very quickly restrict the possible values that other nodes can take on. So that then is how we can go about selecting an unassigned variable in a particular order. Rather than randomly picking a variable, if we’re a little bit intelligent about how we choose it, we can make our search process much, much more efficient by making sure we don’t have to search through portions of the search space that ultimately aren’t going to matter. The other variable we haven’t really talked about, the other function here, is this domain values function. This domain values function that takes a variable and gives me back a sequence of all of the values inside of that variable’s domain. The naive way to approach it is what we did before, which is just go in order, go Monday, then Tuesday, then Wednesday. But the problem is that going in that order might not be the most efficient order to search in, that sometimes it might be more efficient to choose values that are likely to be solutions first and then go to other values. Now, how do you assess whether a value is likelier to lead to a solution or less likely to lead to a solution? Well, one thing you can take a look at is how many constraints get added, how many things get removed from domains as you make this new assignment of a variable to this particular value. And the heuristic we can use here is the least constraining value heuristic, which is the idea that we should return variables in order based on the number of choices that are ruled out for neighboring values. And I want to start with the least constraining value, the value that rules out the fewest possible options. And the idea there is that if all I care about doing is finding a solution, if I start with a value that rules out a lot of other choices, I’m ruling out a lot of possibilities that maybe is going to make it less likely that this particular choice leads to a solution. Whereas on the other hand, if I have a variable and I start by choosing a value that doesn’t rule out very much, well, then I still have a lot of space where there might be a solution that I could ultimately find. And this might seem a little bit counterintuitive and a little bit at odds with what we were talking about before, where I said, when you’re picking a variable, you should pick the variable that is going to have the fewest possible values remaining. But here, I want to pick the value for the variable that is the least constraining. But the general idea is that when I am picking a variable, I would like to prune large portions of the search space by just choosing a variable that is going to allow me to quickly eliminate possible options. Whereas here, within a particular variable, as I’m considering values that that variable could take on, I would like to just find a solution. And so what I want to do is ultimately choose a value that still leaves open the possibility of me finding a solution to be as likely as possible. By not ruling out many options, I leave open the possibility that I can still find a solution without needing to go back later and backtrack. So an example of that might be in this particular situation here, if I’m trying to choose a variable for a value for node C here, that C is equal to either Tuesday or Wednesday. We know it can’t be Monday because it conflicts with this domain here, where we already know that A is Monday, so C must be Tuesday or Wednesday. And the question is, should I try Tuesday first, or should I try Wednesday first? And if I try Tuesday, what gets ruled out? Well, one option gets ruled out here, a second option gets ruled out here, and a third option gets ruled out here. So choosing Tuesday would rule out three possible options. And what about choosing Wednesday? Well, choosing Wednesday would rule out one option here, and it would rule out one option there. And so I have two choices. I can choose Tuesday that rules out three options, or Wednesday that rules out two options. And according to the least constraining value heuristic, what I should probably do is go ahead and choose Wednesday, the one that rules out the fewest number of possible options, leaving open as many chances as possible for me to eventually find the solution inside of the state space. And ultimately, if you continue this process, we will find the solution, an assignment of variables, two values, that allows us to give each of these exams, each of these classes, an exam date that doesn’t conflict with anyone that happens to be enrolled in two classes at the same time. So the big takeaway now with all of this is that there are a number of different ways we can formulate a problem. The ways we’ve looked at today are we can formulate a problem as a local search problem, a problem where we’re looking at a current node and moving to a neighbor based on whether that neighbor is better or worse than the current node that we are looking at. We looked at formulating problems as linear programs, where just by putting things in terms of equations and constraints, we’re able to solve problems a little bit more efficiently. And we saw formulating a problem as a constraint satisfaction problem, creating this graph of all of the constraints that connect two variables that have some constraint between them, and using that information to be able to figure out what the solution should be. And so the takeaway of all of this now is that if we have some problem in artificial intelligence that we would like to use AI to be able to solve them, whether that’s trying to figure out where hospitals should be or trying to solve the traveling salesman problem, trying to optimize productions and costs and whatnot, or trying to figure out how to satisfy certain constraints, whether that’s in a Sudoku puzzle, or whether that’s in trying to figure out how to schedule exams for a university, or any number of a wide variety of types of problems, if we can formulate that problem as one of these sorts of problems, then we can use these known algorithms, these algorithms for enforcing art consistency and backtracking search, these hill climbing and simulated annealing algorithms, these simplex algorithms and interior point algorithms that can be used to solve linear programs, that we can use those techniques to begin to solve a whole wide variety of problems all in this world of optimization inside of artificial intelligence. This was an introduction to artificial intelligence with Python for today. We will see you next time. [” All right. Welcome back, everyone, to an introduction to artificial intelligence with Python. Now, so far in this class, we’ve used AI to solve a number of different problems, giving AI instructions for how to search for a solution, or how to satisfy certain constraints in order to find its way from some input point to some output point in order to solve some sort of problem. Today, we’re going to turn to the world of learning, in particular the idea of machine learning, which generally refers to the idea where we are not going to give the computer explicit instructions for how to perform a task, but rather we are going to give the computer access to information in the form of data, or patterns that it can learn from, and let the computer try and figure out what those patterns are, try and understand that data to be able to perform a task on its own. Now, machine learning comes in a number of different forms, and it’s a very wide field. So today, we’ll explore some of the foundational algorithms and ideas that are behind a lot of the different areas within machine learning. And one of the most popular is the idea of supervised machine learning, or just supervised learning. And supervised learning is a particular type of task. It refers to the task where we give the computer access to a data set, where that data set consists of input-output pairs. And what we would like the computer to do is we would like our AI to be able to figure out some function that maps inputs to outputs. So we have a whole bunch of data that generally consists of some kind of input, some evidence, some information that the computer will have access to. And we would like the computer, based on that input information, to predict what some output is going to be. And we’ll give it some data so that the computer can train its model on and begin to understand how it is that this information works and how it is that the inputs and outputs relate to each other. But ultimately, we hope that our computer will be able to figure out some function that, given those inputs, is able to get those outputs. There are a couple of different tasks within supervised learning. The one we’ll focus on and start with is known as classification. And classification is the problem where, if I give you a whole bunch of inputs, you need to figure out some way to map those inputs into discrete categories, where you can decide what those categories are, and it’s the job of the computer to predict what those categories are going to be. So that might be, for example, I give you information about a bank note, like a US dollar, and I’m asking you to predict for me, does it belong to the category of authentic bank notes, or does it belong to the category of counterfeit bank notes? You need to categorize the input, and we want to train the computer to figure out some function to be able to do that calculation. Another example might be the case of weather, someone we’ve talked about a little bit so far in this class, where we would like to predict on a given day, is it going to rain on that day? Is it going to be cloudy on that day? And before we’ve seen how we could do this, if we really give the computer all the exact probabilities for if these are the conditions, what’s the probability of rain? Oftentimes, we don’t have access to that information, though. But what we do have access to is a whole bunch of data. So if we wanted to be able to predict something like, is it going to rain or is it not going to rain, we would give the computer historical information about days when it was raining and days when it was not raining and ask the computer to look for patterns in that data. So what might that data look like? Well, we could structure that data in a table like this. This might be what our table looks like, where for any particular day, going back, we have information about that day’s humidity, that day’s air pressure, and then importantly, we have a label, something where the human has said that on this particular day, it was raining or it was not raining. So you could fill in this table with a whole bunch of data. And what makes this what we would call a supervised learning exercise is that a human has gone in and labeled each of these data points, said that on this day, when these were the values for the humidity and pressure, that day was a rainy day and this day was a not rainy day. And what we would like the computer to be able to do then is to be able to figure out, given these inputs, given the humidity and the pressure, can the computer predict what label should be associated with that day? Does that day look more like it’s going to be a day that rains or does it look more like a day when it’s not going to rain? Put a little bit more mathematically, you can think of this as a function that takes two inputs, the inputs being the data points that our computer will have access to, things like humidity and pressure. So we could write a function f that takes as input both humidity and pressure. And then the output is going to be what category we would ascribe to these particular input points, what label we would associate with that input. So we’ve seen a couple of example data points here, where given this value for humidity and this value for pressure, we predict, is it going to rain or is it not going to rain? And that’s information that we just gathered from the world. We measured on various different days what the humidity and pressure were. We observed whether or not we saw rain or no rain on that particular day. And this function f is what we would like to approximate. Now, the computer and we humans don’t really know exactly how this function f works. It’s probably quite a complex function. So what we’re going to do instead is attempt to estimate it. We would like to come up with a hypothesis function. h, which is going to try to approximate what f does. We want to come up with some function h that will also take the same inputs and will also produce an output, rain or no rain. And ideally, we’d like these two functions to agree as much as possible. So the goal then of the supervised learning classification tasks is going to be to figure out, what does that function h look like? How can we begin to estimate, given all of this information, all of this data, what category or what label should be assigned to a particular data point? So where could you begin doing this? Well, a reasonable thing to do, especially in this situation, I have two numerical values, is I could try to plot this on a graph that has two axes, an x-axis and a y-axis. And in this case, we’re just going to be using two numerical values as input. But these same types of ideas scale as you add more and more inputs as well. We’ll be plotting things in two dimensions. But as we soon see, you could add more inputs and just imagine things in multiple dimensions. And while we humans have trouble conceptualizing anything really beyond three dimensions, at least visually, a computer has no problem with trying to imagine things in many, many more dimensions, that for a computer, each dimension is just some separate number that it is keeping track of. So it wouldn’t be unreasonable for a computer to think in 10 dimensions or 100 dimensions to be able to try to solve a problem. But for now, we’ve got two inputs. So we’ll graph things along two axes, an x-axis, which will here represent humidity, and a y-axis, which here represents pressure. And what we might do is say, let’s take all of the days that were raining and just try to plot them on this graph and see where they fall on this graph. And here might be all of the rainy days, where each rainy day is one of these blue dots here that corresponds to a particular value for humidity and a particular value for pressure. And then I might do the same thing with the days that were not rainy. So take all the not rainy days, figure out what their values were for each of these two inputs, and go ahead and plot them on this graph as well. And I’ve here plotted them in red. So blue here stands for a rainy day. Red here stands for a not rainy day. And this then is the input that my computer has access to all of this input. And what I would like the computer to be able to do is to train a model such that if I’m ever presented with a new input that doesn’t have a label associated with it, something like this white dot here, I would like to predict, given those values for each of the two inputs, should we classify it as a blue dot, a rainy day, or should we classify it as a red dot, a not rainy day? And if you’re just looking at this picture graphically, trying to say, all right, this white dot, does it look like it belongs to the blue category, or does it look like it belongs to the red category, I think most people would agree that it probably belongs to the blue category. And why is that? Well, it looks like it’s close to other blue dots. And that’s not a very formal notion, but it’s a notion that we’ll formalize in just a moment. That because it seems to be close to this blue dot here, nothing else is closer to it, then we might say that it should be categorized as blue. It should fall into that category of, I think that day is going to be a rainy day based on that input. Might not be totally accurate, but it’s a pretty good guess. And this type of algorithm is actually a very popular and common machine learning algorithm known as nearest neighbor classification. It’s an algorithm for solving these classification-type problems. And in nearest neighbor classification, it’s going to perform this algorithm. What it will do is, given an input, it will choose the class of the nearest data point to that input. By class, we just here mean category, like rain or no rain, counterfeit or not counterfeit. And we choose the category or the class based on the nearest data point. So given all that data, we just looked at, is the nearest data point a blue point or is it a red point? And depending on the answer to that question, we were able to make some sort of judgment. We were able to say something like, we think it’s going to be blue or we think it’s going to be red. So likewise, we could apply this to other data points that we encounter as well. If suddenly this data point comes about, well, its nearest data is red. So we would go ahead and classify this as a red point, not raining. Things get a little bit trickier, though, when you look at a point like this white point over here and you ask the same sort of question. Should it belong to the category of blue points, the rainy days? Or should it belong to the category of red points, the not rainy days? Now, nearest neighbor classification would say the way you solve this problem is look at which point is nearest to that point. You look at this nearest point and say it’s red. It’s a not rainy day. And therefore, according to nearest neighbor classification, I would say that this unlabeled point, well, that should also be red. It should also be classified as a not rainy day. But your intuition might think that that’s a reasonable judgment to make, that it’s the closest thing is a not rainy day. So may as well guess that it’s a not rainy day. But it’s probably also reasonable to look at the bigger picture of things to say, yes, it is true that the nearest point to it was a red point. But it’s surrounded by a whole bunch of other blue points. So looking at the bigger picture, there’s potentially an argument to be made that this point should actually be blue. And with only this data, we actually don’t know for sure. We are given some input, something we’re trying to predict. And we don’t necessarily know what the output is going to be. So in this case, which one is correct is difficult to say. But oftentimes, considering more than just a single neighbor, considering multiple neighbors can sometimes give us a better result. And so there’s a variant on the nearest neighbor classification algorithm that is known as the K nearest neighbor classification algorithm, where K is some parameter, some number that we choose, for how many neighbors are we going to look at. So one nearest neighbor classification is what we saw before. Just pick the one nearest neighbor and use that category. But with K nearest neighbor classification, where K might be 3, or 5, or 7, to say look at the 3, or 5, or 7 closest neighbors, closest data points to that point, works a little bit differently. This algorithm, we’ll give it an input. Choose the most common class out of the K nearest data points to that input. So if we look at the five nearest points, and three of them say it’s raining, and two of them say it’s not raining, we’ll go with the three instead of the two, because each one effectively gets one vote towards what they believe the category ought to be. And ultimately, you choose the category that has the most votes as a consequence of that. So K nearest neighbor classification, fairly straightforward one to understand intuitively. You just look at the neighbors and figure out what the answer might be. And it turns out this can work very, very well for solving a whole variety of different types of classification problems. But not every model is going to work under every situation. And so one of the things we’ll take a look at today, especially in the context of supervised machine learning, is that there are a number of different approaches to machine learning, a number of different algorithms that we can apply, all solving the same type of problem, all solving some kind of classification problem where we want to take inputs and organize it into different categories. And no one algorithm is necessarily always going to be better than some other algorithm. They each have their trade-offs. And maybe depending on the data, one type of algorithm is going to be better suited to trying to model that information than some other algorithm. And so this is what a lot of machine learning research ends up being about, that when you’re trying to apply machine learning techniques, you’re often looking not just at one particular algorithm, but trying multiple different algorithms, trying to see what is going to give you the best results for trying to predict some function that maps inputs to outputs. So what then are the drawbacks of K nearest neighbor classification? Well, there are a couple. One might be that in a naive approach, at least, it could be fairly slow to have to go through and measure the distance between a point and every single one of these points that exist here. Now, there are ways of trying to get around that. There are data structures that can help to make it more quickly to be able to find these neighbors. There are also techniques you can use to try and prune some of this data, remove some of the data points so that you’re only left with the relevant data points just to make it a little bit easier. But ultimately, what we might like to do is come up with another way of trying to do this classification. And one way of trying to do the classification was looking at what are the neighboring points. But another way might be to try to look at all of the data and see if we can come up with some decision boundary, some boundary that will separate the rainy days from the not rainy days. And in the case of two dimensions, we can do that by drawing a line, for example. So what we might want to try to do is just find some line, find some separator that divides the rainy days, the blue points over here, from the not rainy days, the red points over there. We’re now trying a different approach in contrast with the nearest neighbor approach, which just looked at local data around the input data point that we cared about. Now what we’re doing is trying to use a technique known as linear regression to find some sort of line that will separate the two halves from each other. Now sometimes it’ll actually be possible to come up with some line that perfectly separates all the rainy days from the not rainy days. Realistically, though, this is probably cleaner than many data sets will actually be. Oftentimes, data is messier. There are outliers. There’s random noise that happens inside of a particular system. And what we’d like to do is still be able to figure out what a line might look like. So in practice, the data will not always be linearly separable. Or linearly separable refers to some data set where I could draw a line just to separate the two halves of it perfectly. Instead, you might have a situation like this, where there are some rainy points that are on this side of the line and some not rainy points that are on that side of the line. And there may not be a line that perfectly separates what path of the inputs from the other half, that perfectly separates all the rainy days from the not rainy days. But we can still say that this line does a pretty good job. And we’ll try to formalize a little bit later what we mean when we say something like this line does a pretty good job of trying to make that prediction. But for now, let’s just say we’re looking for a line that does as good of a job as we can at trying to separate one category of things from another category of things. So let’s now try to formalize this a little bit more mathematically. We want to come up with some sort of function, some way we can define this line. And our inputs are things like humidity and pressure in this case. So our inputs we might call x1 is going to represent humidity, and x2 is going to represent pressure. These are inputs that we are going to provide to our machine learning algorithm. And given those inputs, we would like for our model to be able to predict some sort of output. And we are going to predict that using our hypothesis function, which we called h. Our hypothesis function is going to take as input x1 and x2, humidity and pressure in this case. And you can imagine if we didn’t just have two inputs, we had three or four or five inputs or more, we could have this hypothesis function take all of those as input. And we’ll see examples of that a little bit later as well. And now the question is, what does this hypothesis function do? Well, it really just needs to measure, is this data point on one side of the boundary, or is it on the other side of the boundary? And how do we formalize that boundary? Well, the boundary is generally going to be a linear combination of these input variables, at least in this particular case. So what we’re trying to do when we say linear combination is take each of these inputs and multiply them by some number that we’re going to have to figure out. We’ll generally call that number a weight for how important should these variables be in trying to determine the answer. So we’ll weight each of these variables with some weight, and we might add a constant to it just to try and make the function a little bit different. And the result, we just need to compare. Is it greater than 0, or is it less than 0 to say, does it belong on one side of the line or the other side of the line? So what that mathematical expression might look like is this. We would take each of my variables, x1 and x2, multiply them by some weight. I don’t yet know what that weight is, but it’s going to be some number, weight 1 and weight 2. And maybe we just want to add some other weight 0 to it, because the function might require us to shift the entire value up or down by a certain amount. And then we just compare. If we do all this math, is it greater than or equal to 0? If so, we might categorize that data point as a rainy day. And otherwise, we might say, no rain. So the key here, then, is that this expression is how we are going to calculate whether it’s a rainy day or not. We’re going to do a bunch of math where we take each of the variables, multiply them by a weight, maybe add an extra weight to it, see if the result is greater than or equal to 0. And using that result of that expression, we’re able to determine whether it’s raining or not raining. This expression here is in this case going to refer to just some line. If you were to plot that graphically, it would just be some line. And what the line actually looks like depends upon these weights. x1 and x2 are the inputs, but these weights are really what determine the shape of that line, the slope of that line, and what that line actually looks like. So we then would like to figure out what these weights should be. We can choose whatever weights we want, but we want to choose weights in such a way that if you pass in a rainy day’s humidity and pressure, then you end up with a result that is greater than or equal to 0. And we would like it such that if we passed into our hypothesis function a not rainy day’s inputs, then the output that we get should be not raining. So before we get there, let’s try and formalize this a little bit more mathematically just to get a sense for how it is that you’ll often see this if you ever go further into supervised machine learning and explore this idea. One thing is that generally for these categories, we’ll sometimes just use the names of the categories like rain and not rain. Often mathematically, if we’re trying to do comparisons between these things, it’s easier just to deal in the world of numbers. So we could just say 1 and 0, 1 for raining, 0 for not raining. So we do all this math. And if the result is greater than or equal to 0, we’ll go ahead and say our hypothesis function outputs 1, meaning raining. And otherwise, it outputs 0, meaning not raining. And oftentimes, this type of expression will instead express using vector mathematics. And all a vector is, if you’re not familiar with the term, is it refers to a sequence of numerical values. You could represent that in Python using a list of numerical values or a tuple with numerical values. And here, we have a couple of sequences of numerical values. One of our vectors, one of our sequences of numerical values, are all of these individual weights, w0, w1, and w2. So we could construct what we’ll call a weight vector, and we’ll see why this is useful in a moment, called w, generally represented using a boldface w, that is just a sequence of these three weights, weight 0, weight 1, and weight 2. And to be able to calculate, based on those weights, whether we think a day is raining or not raining, we’re going to multiply each of those weights by one of our input variables. That w2, this weight, is going to be multiplied by input variable x2. w1 is going to be multiplied by input variable x1. And w0, well, it’s not being multiplied by anything. But to make sure the vectors are the same length, and we’ll see why that’s useful in just a second, we’ll just go ahead and say w0 is being multiplied by 1. Because you can multiply by something by 1, and you end up getting the exact same number. So in addition to the weight vector w, we’ll also have an input vector that we’ll call x that has three values, 1, again, because we’re just multiplying w0 by 1 eventually, and then x1 and x2. So here, then, we’ve represented two distinct vectors, a vector of weights that we need to somehow learn. The goal of our machine learning algorithm is to learn what this weight vector is supposed to be. We could choose any arbitrary set of numbers, and it would produce a function that tries to predict rain or not rain, but it probably wouldn’t be very good. What we want to do is come up with a good choice of these weights so that we’re able to do the accurate predictions. And then this input vector represents a particular input to the function, a data point for which we would like to estimate, is that day a rainy day, or is that day a not rainy day? And so that’s going to vary just depending on what input is provided to our function, what it is that we are trying to estimate. And then to do the calculation, we want to calculate this expression here, and it turns out that expression is what we would call the dot product of these two vectors. The dot product of two vectors just means taking each of the terms in the vectors and multiplying them together, w0 multiply it by 1, w1 multiply it by x1, w2 multiply it by x2, and that’s why these vectors need to be the same length. And then we just add all of the results together. So the dot product of w and x, our weight vector and our input vector, that’s just going to be w0 times 1, or just w0, plus w1 times x1, multiplying these two terms together, plus w2 times x2, multiplying those terms together. So we have our weight vector, which we need to figure out. We need our machine learning algorithm to figure out what the weights should be. We have the input vector representing the data point that we’re trying to predict a category for, predict a label for. And we’re able to do that calculation by taking this dot product, which you’ll often see represented in vector form. But if you haven’t seen vectors before, you can think of it as identical to just this mathematical expression, just doing the multiplication, adding the results together, and then seeing whether the result is greater than or equal to 0 or not. This expression here is identical to the expression that we’re calculating to see whether or not that answer is greater than or equal to 0 in this case. And so for that reason, you’ll often see the hypothesis function written as something like this, a simpler representation where the hypothesis takes as input some input vector x, some humidity and pressure for some day. And we want to predict an output like rain or no rain or 1 or 0 if we choose to represent things numerically. And the way we do that is by taking the dot product of the weights and our input. If it’s greater than or equal to 0, we’ll go ahead and say the output is 1. Otherwise, the output is going to be 0. And this hypothesis, we say, is parameterized by the weights. Depending on what weights we choose, we’ll end up getting a different hypothesis. If we choose the weights randomly, we’re probably not going to get a very good hypothesis function. We’ll get a 1 or a 0. But it’s probably not accurately going to reflect whether we think a day is going to be rainy or not rainy. But if we choose the weights right, we can often do a pretty good job of trying to estimate whether we think the output of the function should be a 1 or a 0. And so the question, then, is how to figure out what these weights should be, how to be able to tune those parameters. And there are a number of ways you can do that. One of the most common is known as the perceptron learning rule. And we’ll see more of this later. But the idea of the perceptron learning rule, and we’re not going to get too deep into the mathematics, we’ll mostly just introduce it more conceptually, is to say that given some data point that we would like to learn from, some data point that has an input x and an output y, where y is like 1 for rain or 0 for not rain, then we’re going to update the weights. And we’ll look at the formula in just a moment. But the big picture idea is that we can start with random weights, but then learn from the data. Take the data points one at a time. And for each one of the data points, figure out, all right, what parameters do we need to change inside of the weights in order to better match that input point. And so that is the value of having access to a lot of data in the supervised machine learning algorithm, is that you take each of the data points and maybe look at them multiple times and constantly try and figure out whether you need to shift your weights in order to better create some weight vector that is able to correctly or more accurately try to estimate what the output should be, whether we think it’s going to be raining or whether we think it’s not going to be raining. So what does that weight update look like? Without going into too much of the mathematics, we’re going to update each of the weights to be the result of the original weight plus some additional expression. And to understand this expression, y, well, y is what the actual output is. And hypothesis of x, the input, that’s going to be what we thought the input was. And so I can replace this by saying what the actual value was minus what our estimate was. And based on the difference between the actual value and what our estimate was, we might want to change our hypothesis, change the way that we do that estimation. If the actual value and the estimate were the same thing, meaning we were correctly able to predict what category this data point belonged to, well, then actual value minus estimate, that’s just going to be 0, which means this whole term on the right-hand side goes to be 0, and the weight doesn’t change. Weight i, where i is like weight 1 or weight 2 or weight 0, weight i just stays at weight i. And none of the weights change if we were able to correctly predict what category the input belonged to. But if our hypothesis didn’t correctly predict what category the input belonged to, well, then maybe then we need to make some changes, adjust the weights so that we’re better able to predict this kind of data point in the future. And what is the way we might do that? Well, if the actual value was bigger than the estimate, then, and for now we’ll go ahead and assume that these x’s are positive values, then if the actual value was bigger than the estimate, well, that means we need to increase the weight in order to make it such that the output is bigger, and therefore we’re more likely to get to the right actual value. And so if the actual value is bigger than the estimate, then actual value minus estimate, that’ll be a positive number. And so you imagine we’re just adding some positive number to the weight just to increase it ever so slightly. And likewise, the inverse case is true, that if the actual value was less than the estimate, the actual value was 0, but we estimated 1, meaning it actually was not raining, but we predicted it was going to be raining. Well, then we want to decrease the value of the weight, because then in that case, we want to try and lower the total value of computing that dot product in order to make it less likely that we would predict that it would actually be raining. So no need to get too deep into the mathematics of that, but the general idea is that every time we encounter some data point, we can adjust these weights accordingly to try and make the weights better line up with the actual data that we have access to. And you can repeat this process with data point after data point until eventually, hopefully, your algorithm converges to some set of weights that do a pretty good job of trying to figure out whether a day is going to be rainy or not raining. And just as a final point about this particular equation, this value alpha here is generally what we’ll call the learning rate. It’s just some parameter, some number we choose for how quickly we’re actually going to be updating these weight values. So that if alpha is bigger, then we’re going to update these weight values by a lot. And if alpha is smaller, then we’ll update the weight values by less. And you can choose a value of alpha. Depending on the problem, different values might suit the situation better or worse than others. So after all of that, after we’ve done this training process of take all this data and using this learning rule, look at all the pieces of data and use each piece of data as an indication to us of do the weights stay the same, do we increase the weights, do we decrease the weights, and if so, by how much? What you end up with is effectively a threshold function. And we can look at what the threshold function looks like like this. On the x-axis here, we have the output of that function, taking the weights, taking the dot product of it with the input. And on the y-axis, we have what the output is going to be, 0, which in this case represented not raining, and 1, which in this case represented raining. And the way that our hypothesis function works is it calculates this value. And if it’s greater than 0 or greater than some threshold value, then we declare that it’s a rainy day. And otherwise, we declare that it’s a not rainy day. And this then graphically is what that function looks like, that initially when the value of this dot product is small, it’s not raining, it’s not raining, it’s not raining. But as soon as it crosses that threshold, we suddenly say, OK, now it’s raining, now it’s raining, now it’s raining. And the way to interpret this kind of representation is that anything on this side of the line, that would be the category of data points where we say, yes, it’s raining. Anything that falls on this side of the line are the data points where we would say, it’s not raining. And again, we want to choose some value for the weights that results in a function that does a pretty good job of trying to do this estimation. But one tricky thing with this type of hard threshold is that it only leaves two possible outcomes. We plug in some data as input. And the output we get is raining or not raining. And there’s no room for anywhere in between. And maybe that’s what you want. Maybe all you want is given some data point, you would like to be able to classify it into one or two or more of these various different categories. But it might also be the case that you care about knowing how strong that prediction is, for example. So if we go back to this instance here, where we have rainy days on this side of the line, not rainy days on that side of the line, you might imagine that let’s look now at these two white data points. This data point here that we would like to predict a label or a category for. And this data point over here that we would also like to predict a label or a category for. It seems likely that you could pretty confidently say that this data point, that should be a rainy day. Seems close to the other rainy days if we’re going by the nearest neighbor strategy. It’s on this side of the line if we’re going by the strategy of just saying, which side of the line does it fall on by figuring out what those weights should be. And if we’re using the line strategy of just which side of the line does it fall on, which side of this decision boundary, well, we’d also say that this point here is also a rainy day because it falls on the side of the line that corresponds to rainy days. But it’s likely that even in this case, we would know that we don’t feel nearly as confident about this data point on the left as compared to this data point on the right. That for this one on the right, we can feel very confident that yes, it’s a rainy day. This one, it’s pretty close to the line if we’re judging just by distance. And so you might be less sure. But our threshold function doesn’t allow for a notion of less sure or more sure about something. It’s what we would call a hard threshold. It’s once you’ve crossed this line, then immediately we say, yes, this is going to be a rainy day. Anywhere before it, we’re going to say it’s not a rainy day. And that may not be helpful in a number of cases. One, this is not a particularly easy function to deal with. As you get deeper into the world of machine learning and are trying to do things like taking derivatives of these curves with this type of function makes things challenging. But the other challenge is that we don’t really have any notion of gradation between things. We don’t have a notion of yes, this is a very strong belief that it’s going to be raining as opposed to it’s probably more likely than not that it’s going to be raining, but maybe not totally sure about that either. So what we can do by taking advantage of a technique known as logistic regression is instead of using this hard threshold type of function, we can use instead a logistic function, something we might call a soft threshold. And that’s going to transform this into looking something a little more like this, something that more nicely curves. And as a result, the possible output values are no longer just 0 and 1, 0 for not raining, 1 for raining. But you can actually get any real numbered value between 0 and 1. But if you’re way over on this side, then you get a value of 0. OK, it’s not going to be raining, and we’re pretty sure about that. And if you’re over on this side, you get a value of 1. And yes, we’re very sure that it’s going to be raining. But in between, you could get some real numbered value, where a value like 0.7 might mean we think it’s going to rain. It’s more probable that it’s going to rain than not based on the data. But we’re not as confident as some of the other data points might be. So one of the advantages of the soft threshold is that it allows us to have an output that could be some real number that potentially reflects some sort of probability, the likelihood that we think that this particular data point belongs to that particular category. And there are some other nice mathematical properties of that as well. So that then is two different approaches to trying to solve this type of classification problem. One is this nearest neighbor type of approach, where you just take a data point and look at the data points that are nearby to try and estimate what category we think it belongs to. And the other approach is the approach of saying, all right, let’s just try and use linear regression, figure out what these weights should be, adjust the weights in order to figure out what line or what decision boundary is going to best separate these two categories. It turns out that another popular approach, a very popular approach if you just have a data set and you want to start trying to do some learning on it, is what we call the support vector machine. And we’re not going to go too much into the mathematics of the support vector machine, but we’ll at least explore it graphically to see what it is that it looks like. And the idea or the motivation behind the support vector machine is the idea that there are actually a lot of different lines that we could draw, a lot of different decision boundaries that we could draw to separate two groups. So for example, I had the red data points over here and the blue data points over here. One possible line I could draw is a line like this, that this line here would separate the red points from the blue points. And it does so perfectly. All the red points are on one side of the line. All the blue points are on the other side of the line. But this should probably make you a little bit nervous. If you come up with a model and the model comes up with a line that looks like this. And the reason why is that you worry about how well it’s going to generalize to other data points that are not necessarily in the data set that we have access to. For example, if there was a point that fell like right here, for example, on the right side of the line, well, then based on that, we might want to guess that it is, in fact, a red point, but it falls on the side of the line where instead we would estimate that it’s a blue point instead. And so based on that, this line is probably not a great choice just because it is so close to these various data points. We might instead prefer like a diagonal line that just goes diagonally through the data set like we’ve seen before. But there too, there’s a lot of diagonal lines that we could draw as well. For example, I could draw this diagonal line here, which also successfully separates all the red points from all of the blue points. From the perspective of something like just trying to figure out some setting of weights that allows us to predict the correct output, this line will predict the correct output for this particular set of data every single time because the red points are on one side, the blue points are on the other. But yet again, you should probably be a little nervous because this line is so close to these red points, even though we’re able to correctly predict on the input data, if there was a point that fell somewhere in this general area, our algorithm, this model, would say that, yeah, we think it’s a blue point, when in actuality, it might belong to the red category instead just because it looks like it’s close to the other red points. What we really want to be able to say, given this data, how can you generalize this as best as possible, is to come up with a line like this that seems like the intuitive line to draw. And the reason why it’s intuitive is because it seems to be as far apart as possible from the red data and the blue data. So that if we generalize a little bit and assume that maybe we have some points that are different from the input but still slightly further away, we can still say that something on this side probably red, something on that side probably blue, and we can make those judgments that way. And that is what support vector machines are designed to do. They’re designed to try and find what we call the maximum margin separator, where the maximum margin separator is just some boundary that maximizes the distance between the groups of points rather than come up with some boundary that’s very close to one set or the other, where in the case before, we wouldn’t have cared. As long as we’re categorizing the input well, that seems all we need to do. The support vector machine will try and find this maximum margin separator, some way of trying to maximize that particular distance. And it does so by finding what we call the support vectors, which are the vectors that are closest to the line, and trying to maximize the distance between the line and those particular points. And it works that way in two dimensions. It also works in higher dimensions, where we’re not looking for some line that separates the two data points, but instead looking for what we generally call a hyperplane, some decision boundary, effectively, that separates one set of data from the other set of data. And this ability of support vector machines to work in higher dimensions actually has a number of other applications as well. But one is that it helpfully deals with cases where data may not be linearly separable. So we talked about linear separability before, this idea that you can take data and just draw a line or some linear combination of the inputs that allows us to perfectly separate the two sets from each other. There are some data sets that are not linearly separable. And some were even two. You would not be able to find a good line at all that would try to do that kind of separation. Something like this, for example. Or if you imagine here are the red points and the blue points around it. If you try to find a line that divides the red points from the blue points, it’s actually going to be difficult, if not impossible, to do that any line you choose, well, if you draw a line here, then you ignore all of these blue points that should actually be blue and not red. Anywhere else you draw a line, there’s going to be a lot of error, a lot of mistakes, a lot of what we’ll soon call loss to that line that you draw, a lot of points that you’re going to categorize incorrectly. What we really want is to be able to find a better decision boundary that may not be just a straight line through this two dimensional space. And what support vector machines can do is they can begin to operate in higher dimensions and be able to find some other decision boundary, like the circle in this case, that actually is able to separate one of these sets of data from the other set of data a lot better. So oftentimes in data sets where the data is not linearly separable, support vector machines by working in higher dimensions can actually figure out a way to solve that kind of problem effectively. So that then, three different approaches to trying to solve these sorts of problems. We’ve seen support vector machines. We’ve seen trying to use linear regression and the perceptron learning rule to be able to figure out how to categorize inputs and outputs. We’ve seen the nearest neighbor approach. No one necessarily better than any other again. It’s going to depend on the data set, the information you have access to. It’s going to depend on what the function looks like that you’re ultimately trying to predict. And this is where a lot of research and experimentation can be involved in trying to figure out how it is to best perform that kind of estimation. But classification is only one of the tasks that you might encounter in supervised machine learning. Because in classification, what we’re trying to predict is some discrete category. We’re trying to predict red or blue, rain or not rain, authentic or counterfeit. But sometimes what we want to predict is a real numbered value. And for that, we have a related problem, not classification, but instead known as regression. And regression is the supervised learning problem where we try and learn a function mapping inputs to outputs same as before. But instead of the outputs being discrete categories, things like rain or not rain, in a regression problem, the output values are generally continuous values, some real number that we would like to predict. This happens all the time as well. You might imagine that a company might take this approach if it’s trying to figure out, for instance, what the effect of its advertising is. How do advertising dollars spent translate into sales for the company’s product, for example? And so they might like to try to predict some function that takes as input the amount of money spent on advertising. And here, we’re just going to use one input. But again, you could scale this up to many more inputs as well if you have a lot of different kinds of data you have access to. And the goal is to learn a function that given this amount of spending on advertising, we’re going to get this amount in sales. And you might judge, based on having access to a whole bunch of data, like for every past month, here is how much we spent on advertising, and here is what sales were. And we would like to predict some sort of hypothesis function that, again, given the amount spent on advertising, we can predict, in this case, some real number, some number estimate of how much sales we expect that company to do in this month or in this quarter or whatever unit of time we’re choosing to measure things in. And so again, the approach to solving this type of problem, we could try using a linear regression type approach where we take this data and we just plot it. On the x-axis, we have advertising dollars spent. On the y-axis, we have sales. And we might just want to try and draw a line that does a pretty good job of trying to estimate this relationship between advertising and sales. And in this case, unlike before, we’re not trying to separate the data points into discrete categories. But instead, in this case, we’re just trying to find a line that approximates this relationship between advertising and sales so that if we want to figure out what the estimated sales are for a particular advertising budget, you just look it up in this line, figure out for this amount of advertising, we would have this amount of sales and just try and make the estimate that way. And so you can try and come up with a line, again, figuring out how to modify the weights using various different techniques to try and make it so that this line fits as well as possible. So with all of these approaches, then, to trying to solve machine learning style problems, the question becomes, how do we evaluate these approaches? How do we evaluate the various different hypotheses that we could come up with? Because each of these algorithms will give us some sort of hypothesis, some function that maps inputs to outputs, and we want to know, how well does that function work? And you can think of evaluating these hypotheses and trying to get a better hypothesis as kind of like an optimization problem. In an optimization problem, as you recall from before, we were either trying to maximize some objective function by trying to find a global maximum, or we were trying to minimize some cost function by trying to find some global minimum. And in the case of evaluating these hypotheses, one thing we might say is that this cost function, the thing we’re trying to minimize, we might be trying to minimize what we would call a loss function. And what a loss function is, is it is a function that is going to estimate for us how poorly our function performs. More formally, it’s like a loss of utility by whenever we predict something that is wrong, that is a loss of utility. That’s going to add to the output of our loss function. And you could come up with any loss function that you want, just some mathematical way of estimating, given each of these data points, given what the actual output is, and given what our projected output is, our estimate, you could calculate some sort of numerical loss for it. But there are a couple of popular loss functions that are worth discussing, just so that you’ve seen them before. When it comes to discrete categories, things like rain or not rain, counterfeit or not counterfeit, one approaches the 0, 1 loss function. And the way that works is for each of the data points, our loss function takes as input what the actual output is, like whether it was actually raining or not raining, and takes our prediction into account. Did we predict, given this data point, that it was raining or not raining? And if the actual value equals the prediction, well, then the 0, 1 loss function will just say the loss is 0. There was no loss of utility, because we were able to predict correctly. And otherwise, if the actual value was not the same thing as what we predicted, well, then in that case, our loss is 1. We lost something, lost some utility, because what we predicted was the output of the function, was not what it actually was. And the goal, then, in a situation like this would be to come up with some hypothesis that minimizes the total empirical loss, the total amount that we’ve lost, if you add up for all these data points what the actual output is and what your hypothesis would have predicted. So in this case, for example, if we go back to classifying days as raining or not raining, and we came up with this decision boundary, how would we evaluate this decision boundary? How much better is it than drawing the line here or drawing the line there? Well, we could take each of the input data points, and each input data point has a label, whether it was raining or whether it was not raining. And we could compare it to the prediction, whether we predicted it would be raining or not raining, and assign it a numerical value as a result. So for example, these points over here, they were all rainy days, and we predicted they would be raining, because they fall on the bottom side of the line. So they have a loss of 0, nothing lost from those situations. And likewise, same is true for some of these points over here, where it was not raining and we predicted it would not be raining either. Where we do have loss are points like this point here and that point there, where we predicted that it would not be raining, but in actuality, it’s a blue point. It was raining. Or likewise here, we predicted that it would be raining, but in actuality, it’s a red point. It was not raining. And so as a result, we miscategorized these data points that we were trying to train on. And as a result, there is some loss here. One loss here, there, here, and there, for a total loss of 4, for example, in this case. And that might be how we would estimate or how we would say that this line is better than a line that goes somewhere else or a line that’s further down, because this line might minimize the loss. So there is no way to do better than just these four points of loss if you’re just drawing a straight line through our space. So the 0, 1 loss function checks. Did we get it right? Did we get it wrong? If we got it right, the loss is 0, nothing lost. If we got it wrong, then our loss function for that data point says 1. And we add up all of those losses across all of our data points to get some sort of empirical loss, how much we have lost across all of these original data points that our algorithm had access to. There are other forms of loss as well that work especially well when we deal with more real valued cases, cases like the mapping between advertising budget and amount that we do in sales, for example. Because in that case, you care not just that you get the number exactly right, but you care how close you were to the actual value. If the actual value is you did like $2,800 in sales and you predicted that you would do $2,900 in sales, maybe that’s pretty good. That’s much better than if you had predicted you’d do $1,000 in sales, for example. And so we would like our loss function to be able to take that into account as well, take into account not just whether the actual value and the expected value are exactly the same, but also take into account how far apart they were. And so for that one approach is what we call L1 loss. L1 loss doesn’t just look at whether actual and predicted are equal to each other, but we take the absolute value of the actual value minus the predicted value. In other words, we just ask how far apart were the actual and predicted values, and we sum that up across all of the data points to be able to get what our answer ultimately is. So what might this actually look like for our data set? Well, if we go back to this representation where we had advertising along the x-axis, sales along the y-axis, our line was our prediction, our estimate for any given amount of advertising, what we predicted sales was going to be. And our L1 loss is just how far apart vertically along the sales axis our prediction was from each of the data points. So we could figure out exactly how far apart our prediction was from each of the data points and figure out as a result of that what our loss is overall for this particular hypothesis just by adding up all of these various different individual losses for each of these data points. And our goal then is to try and minimize that loss, to try and come up with some line that minimizes what the utility loss is by judging how far away our estimate amount of sales is from the actual amount of sales. And turns out there are other loss functions as well. One that’s quite popular is the L2 loss. The L2 loss, instead of just using the absolute value, like how far away the actual value is from the predicted value, it uses the square of actual minus predicted. So how far apart are the actual and predicted value? And it squares that value, effectively penalizing much more harshly anything that is a worse prediction. So you imagine if you have two data points that you predict as being one value away from their actual value, as opposed to one data point that you predict as being two away from its actual value, the L2 loss function will more harshly penalize that one that is two away, because it’s going to square, however, much the differences between the actual value and the predicted value. And depending on the situation, you might want to choose a loss function depending on what you care about minimizing. If you really care about minimizing the error on more outlier cases, then you might want to consider something like this. But if you’ve got a lot of outliers, and you don’t necessarily care about modeling them, then maybe an L1 loss function is preferable. But there are trade-offs here that you need to decide, based on a particular set of data. But what you do run the risk of with any of these loss functions, with anything that we’re trying to do, is a problem known as overfitting. And overfitting is a big problem that you can encounter in machine learning, which happens anytime a model fits too closely with a data set, and as a result, fails to generalize. We would like our model to be able to accurately predict data and inputs and output pairs for the data that we have access to. But the reason we wanted to do so is because we want our model to generalize well to data that we haven’t seen before. I would like to take data from the past year of whether it was raining or not raining, and use that data to generalize it towards the future. Say, in the future, is it going to be raining or not raining? Or if I have a whole bunch of data on what counterfeit and not counterfeit US dollar bills look like in the past when people have encountered them, I’d like to train a computer to be able to, in the future, generalize to other dollar bills that I might see as well. And the problem with overfitting is that if you try and tie yourself too closely to the data set that you’re training your model on, you can end up not generalizing very well. So what does this look like? Well, we might imagine the rainy day and not rainy day example again from here, where the blue points indicate rainy days and the red points indicate not rainy days. And we decided that we felt pretty comfortable with drawing a line like this as the decision boundary between rainy days and not rainy days. So we can pretty comfortably say that points on this side more likely to be rainy days, points on that side more likely to be not rainy days. But the loss, the empirical loss, isn’t zero in this particular case because we didn’t categorize everything perfectly. There was this one outlier, this one day that it wasn’t raining, but yet our model still predicts that it is raining. But that doesn’t necessarily mean our model is bad. It just means the model isn’t 100% accurate. If you really wanted to try and find a hypothesis that resulted in minimizing the loss, you could come up with a different decision boundary. It wouldn’t be a line, but it would look something like this. This decision boundary does separate all of the red points from all of the blue points because the red points fall on this side of this decision boundary, the blue points fall on the other side of the decision boundary. But this, we would probably argue, is not as good of a prediction. Even though it seems to be more accurate based on all of the available training data that we have for training this machine learning model, we might say that it’s probably not going to generalize well. That if there were other data points like here and there, we might still want to consider those to be rainy days because we think this was probably just an outlier. So if the only thing you care about is minimizing the loss on the data you have available to you, you run the risk of overfitting. And this can happen in the classification case. It can also happen in the regression case, that here we predicted what we thought was a pretty good line relating advertising to sales, trying to predict what sales were going to be for a given amount of advertising. But I could come up with a line that does a better job of predicting the training data, and it would be something that looks like this, just connecting all of the various different data points. And now there is no loss at all. Now I’ve perfectly predicted, given any advertising, what sales are. And for all the data available to me, it’s going to be accurate. But it’s probably not going to generalize very well. I have overfit my model on the training data that is available to me. And so in general, we want to avoid overfitting. We’d like strategies to make sure that we haven’t overfit our model to a particular data set. And there are a number of ways that you could try to do this. One way is by examining what it is that we’re optimizing for. In an optimization problem, all we do is we say, there is some cost, and I want to minimize that cost. And so far, we’ve defined that cost function, the cost of a hypothesis, just as being equal to the empirical loss of that hypothesis, like how far away are the actual data points, the outputs, away from what I predicted them to be based on that particular hypothesis. And if all you’re trying to do is minimize cost, meaning minimizing the loss in this case, then the result is going to be that you might overfit, that to minimize cost, you’re going to try and find a way to perfectly match all the input data. And that might happen as a result of overfitting on that particular input data. So in order to address this, you could add something to the cost function. What counts as cost will not just loss, but also some measure of the complexity of the hypothesis. The word the complexity of the hypothesis is something that you would need to define for how complicated does our line look. This is sort of an Occam’s razor-style approach where we want to give preference to a simpler decision boundary, like a straight line, for example, some simpler curve, as opposed to something far more complex that might represent the training data better but might not generalize as well. We’ll generally say that a simpler solution is probably the better solution and probably the one that is more likely to generalize well to other inputs. So we measure what the loss is, but we also measure the complexity. And now that all gets taken into account when we consider the overall cost, that yes, something might have less loss if it better predicts the training data, but if it’s much more complex, it still might not be the best option that we have. And we need to come up with some balance between loss and complexity. And for that reason, you’ll often see this represented as multiplying the complexity by some parameter that we have to choose, parameter lambda in this case, where we’re saying if lambda is a greater value, then we really want to penalize more complex hypotheses. Whereas if lambda is smaller, we’re going to penalize more complex hypotheses a little bit, and it’s up to the machine learning programmer to decide where they want to set that value of lambda for how much do I want to penalize a more complex hypothesis that might fit the data a little better. And again, there’s no one right answer to a lot of these things, but depending on the data set, depending on the data you have available to you and the problem you’re trying to solve, your choice of these parameters may vary, and you may need to experiment a little bit to figure out what the right choice of that is ultimately going to be. This process, then, of considering not only loss, but also some measure of the complexity is known as regularization. Regularization is the process of penalizing a hypothesis that is more complex in order to favor a simpler hypothesis that is more likely to generalize well, more likely to be able to apply to other situations that are dealing with other input points unlike the ones that we’ve necessarily seen before. So oftentimes, you’ll see us add some regularizing term to what we’re trying to minimize in order to avoid this problem of overfitting. Now, another way of making sure we don’t overfit is to run some experiments and to see whether or not we are able to generalize our model that we’ve created to other data sets as well. And it’s for that reason that oftentimes when you’re doing a machine learning experiment, when you’ve got some data and you want to try and come up with some function that predicts, given some input, what the output is going to be, you don’t necessarily want to do your training on all of the data you have available to you that you could employ a method known as holdout cross-validation, where in holdout cross-validation, we split up our data. We split up our data into a training set and a testing set. The training set is the set of data that we’re going to use to train our machine learning model. And the testing set is the set of data that we’re going to use in order to test to see how well our machine learning model actually performed. So the learning happens on the training set. We figure out what the parameters should be. We figure out what the right model is. And then we see, all right, now that we’ve trained the model, we’ll see how well it does at predicting things inside of the testing set, some set of data that we haven’t seen before. And the hope then is that we’re going to be able to predict the testing set pretty well if we’re able to generalize based on the training data that’s available to us. If we’ve overfit the training data, though, and we’re not able to generalize, well, then when we look at the testing set, it’s likely going to be the case that we’re not going to predict things in the testing set nearly as effectively. So this is one method of cross-validation, validating to make sure that the work we have done is actually going to generalize to other data sets as well. And there are other statistical techniques we can use as well. One of the downsides of this just hold out cross-validation is if you say I just split it 50-50, I train using 50% of the data and test using the other 50%, or you could choose other percentages as well, is that there is a fair amount of data that I am now not using to train, that I might be able to get a better model as a result, for example. So one approach is known as k-fold cross-validation. In k-fold cross-validation, rather than just divide things into two sets and run one experiment, we divide things into k different sets. So maybe I divide things up into 10 different sets and then run 10 different experiments. So if I split up my data into 10 different sets of data, then what I’ll do is each time for each of my 10 experiments, I will hold out one of those sets of data, where I’ll say, let me train my model on these nine sets, and then test to see how well it predicts on set number 10. And then pick another set of nine sets to train on, and then test it on the other one that I held out, where each time I train the model on everything minus the one set that I’m holding out, and then test to see how well our model performs on the test that I did hold out. And what you end up getting is 10 different results, 10 different answers for how accurately our model worked. And oftentimes, you could just take the average of those 10 to get an approximation for how well we think our model performs overall. But the key idea is separating the training data from the testing data, because you want to test your model on data that is different from what you trained the model on. Because the training, you want to avoid overfitting. You want to be able to generalize. And the way you test whether you’re able to generalize is by looking at some data that you haven’t seen before and seeing how well we’re actually able to perform. And so if we want to actually implement any of these techniques inside of a programming language like Python, number of ways we could do that. We could write this from scratch on our own, but there are libraries out there that allow us to take advantage of existing implementations of these algorithms, that we can use the same types of algorithms in a lot of different situations. And so there’s a library, very popular one, known as Scikit-learn, which allows us in Python to be able to very quickly get set up with a lot of these different machine learning models. This library has already written an algorithm for nearest neighbor classification, for doing perceptron learning, for doing a bunch of other types of inference and supervised learning that we haven’t yet talked about. But using it, we can begin to try actually testing how these methods work and how accurately they perform. So let’s go ahead and take a look at one approach to trying to solve this type of problem. All right, so I’m first going to pull up banknotes.csv, which is a whole bunch of data provided by UC Irvine, which is information about various different banknotes that people took pictures of various different banknotes and measured various different properties of those banknotes. And in particular, some human categorized each of those banknotes as either a counterfeit banknote or as not counterfeit. And so what you’re looking at here is each row represents one banknote. This is formatted as a CSV spreadsheet, where just comma separated values separating each of these various different fields. We have four different input values for each of these data points, just information, some measurement that was made on the banknote. And what those measurements exactly are aren’t as important as the fact that we do have access to this data. But more importantly, we have access for each of these data points to a label, where 0 indicates something like this was not a counterfeit bill, meaning it was an authentic bill. And a data point labeled 1 means that it is a counterfeit bill, at least according to the human researcher who labeled this particular data. So we have a whole bunch of data representing a whole bunch of different data points, each of which has these various different measurements that were made on that particular bill, and each of which has an output value, 0 or 1, 0 meaning it was a genuine bill, 1 meaning it was a counterfeit bill. And what we would like to do is use supervised learning to begin to predict or model some sort of function that can take these four values as input and predict what the output would be. We want our learning algorithm to find some sort of pattern that is able to predict based on these measurements, something that you could measure just by taking a photo of a bill, predict whether that bill is authentic or whether that bill is counterfeit. And so how can we do that? Well, I’m first going to open up banknote0.py and see how it is that we do this. I’m first importing a lot of things from Scikit-learn, but importantly, I’m going to set my model equal to the perceptron model, which is one of those models that we talked about before. We’re just going to try and figure out some setting of weights that is able to divide our data into two different groups. Then I’m going to go ahead and read data in for my file from banknotes.csv. And basically, for every row, I’m going to separate that row into the first four values of that row, which is the evidence for that row. And then the label, where if the final column in that row is a 0, the label is authentic. And otherwise, it’s going to be counterfeit. So I’m effectively reading data in from the CSV file, dividing into a whole bunch of rows where each row has some evidence, those four input values that are going to be inputs to my hypothesis function. And then the label, the output, whether it is authentic or counterfeit, that is the thing that I am then trying to predict. So the next step is that I would like to split up my data set into a training set and a testing set, some set of data that I would like to train my machine learning model on, and some set of data that I would like to use to test that model, see how well it performed. So what I’ll do is I’ll go ahead and figure out length of the data, how many data points do I have. I’ll go ahead and take half of them, save that number as a number called holdout. That is how many items I’m going to hold out for my data set to save for the testing phase. I’ll randomly shuffle the data so it’s in some random order. And then I’ll say my testing set will be all of the data up to the holdout. So I’ll take holdout many data items, and that will be my testing set. My training data will be everything else, the information that I’m going to train my model on. And then I’ll say I need to divide my training data into two different sets. I need to divide it into my x values, where x here represents the inputs. So the x values, the x values that I’m going to train on, are basically for every row in my training set, I’m going to get the evidence for that row, those four values, where it’s basically a vector of four numbers, where that is going to be all of the input. And then I need the y values. What are the outputs that I want to learn from, the labels that belong to each of these various different input points? Well, that’s going to be the same thing for each row in the training data. But this time, I take that row and get what its label is, whether it is authentic or counterfeit. So I end up with one list of all of these vectors of my input data, and one list, which follows the same order, but is all of the labels that correspond with each of those vectors. And then to train my model, which in this case is just this perceptron model, I just call model.fit, pass in the training data, and what the labels for those training data are. And scikit-learn will take care of fitting the model, will do the entire algorithm for me. And then when it’s done, I can then test to see how well that model performed. So I can say, let me get all of these input vectors for what I want to test on. So for each row in my testing data set, go ahead and get the evidence. And the y values, those are what the actual values were for each of the rows in the testing data set, what the actual label is. But then I’m going to generate some predictions. I’m going to use this model and try and predict, based on the testing vectors, I want to predict what the output is. And my goal then is to now compare y testing with predictions. I want to see how well my predictions, based on the model, actually reflect what the y values were, what the output is, that were actually labeled. Because I now have this label data, I can assess how well the algorithm worked. And so now I can just compute how well we did. I’m going to, this zip function basically just lets me look through two different lists, one by one at the same time. So for each actual value and for each predicted value, if the actual is the same thing as what I predicted, I’ll go ahead and increment the counter by one. Otherwise, I’ll increment my incorrect counter by one. And so at the end, I can print out, here are the results, here’s how many I got right, here’s how many I got wrong, and here was my overall accuracy, for example. So I can go ahead and run this. I can run python banknote0.py. And it’s going to train on half the data set and then test on half the data set. And here are the results for my perceptron model. In this case, it correctly was able to classify 679 bills as correctly either authentic or counterfeit and incorrectly classified seven of them for an overall accuracy of close to 99% accurate. So on this particular data set, using this perceptron model, we were able to predict very well what the output was going to be. And we can try different models, too, that scikit-learn makes it very easy just to swap out one model for another model. So instead of the perceptron model, I can use the support vector machine using the SVC, otherwise known as a support vector classifier, using a support vector machine to classify things into two different groups. And now see, all right, how well does this perform? And all right, this time, we were able to correctly predict 682 and incorrectly predicted four for accuracy of 99.4%. And we could even try the k-neighbors classifier as the model instead. And this takes a parameter, n neighbors, for how many neighbors do you want to look at? Let’s just look at one neighbor, the one nearest neighbor, and use that to predict. Go ahead and run this as well. And it looks like, based on the k-neighbors classifier, looking at just one neighbor, we were able to correctly classify 685 data points, incorrectly classified one. Maybe let’s try three neighbors instead, instead of just using one neighbor. Do more of a k-nearest neighbors approach, where I look at the three nearest neighbors and see how that performs. And that one, in this case, seems to have gotten 100% of all of the predictions correctly described as either authentic banknotes or as counterfeit banknotes. And we could run these experiments multiple times, because I’m randomly reorganizing the data every time. We’re technically training these on slightly different data sets. And so you might want to run multiple experiments to really see how well they’re actually going to perform. But in short, they all perform very well. And while some of them perform slightly better than others here, that might not always be the case for every data set. But you can begin to test now by very quickly putting together these machine learning models using Scikit-learn to be able to train on some training set and then test on some testing set as well. And this splitting up into training groups and testing groups and testing happens so often that Scikit-learn has functions built in for trying to do it. I did it all by hand just now. But if we take a look at banknotes one, we take advantage of some other features that exist in Scikit-learn, where we can really simplify a lot of our logic, that there is a function built into Scikit-learn called train test split, which will automatically split data into a training group and a testing group. I just have to say what proportion should be in the testing group, something like 0.5, half the data inside the testing group. Then I can fit the model on the training data, make the predictions on the testing data, and then just count up. And Scikit-learn has some nice methods for just counting up how many times our testing data match the predictions, how many times our testing data didn’t match the predictions. So very quickly, you can write programs with not all that many lines of code. It’s maybe like 40 lines of code to get through all of these predictions. And then as a result, see how well we’re able to do. So these types of libraries can allow us, without really knowing the implementation details of these algorithms, to be able to use the algorithms in a very practical way to be able to solve these types of problems. So that then was supervised learning, this task of given a whole set of data, some input output pairs, we would like to learn some function that maps those inputs to those outputs. But turns out there are other forms of learning as well. And another popular type of machine learning, especially nowadays, is known as reinforcement learning. And the idea of reinforcement learning is rather than just being given a whole data set at the beginning of input output pairs, reinforcement learning is all about learning from experience. In reinforcement learning, our agent, whether it’s like a physical robot that’s trying to make actions in the world or just some virtual agent that is a program running somewhere, our agent is going to be given a set of rewards or punishments in the form of numerical values. But you can think of them as reward or punishment. And based on that, it learns what actions to take in the future, that our agent, our AI, will be put in some sort of environment. It will make some actions. And based on the actions that it makes, it learns something. It either gets a reward when it does something well, it gets a punishment when it does something poorly, and it learns what to do or what not to do in the future based on those individual experiences. And so what this will often look like is it will often start with some agent, some AI, which might, again, be a physical robot, if you’re imagining a physical robot moving around, but it can also just be a program. And our agent is situated in their environment, where the environment is where they’re going to make their actions, and it’s what’s going to give them rewards or punishments for various actions that they’re in. So for example, the environment is going to start off by putting our agent inside of a state. Our agent has some state that, in a game, might be the state of the game that the agent is playing. In a world that the agent is exploring might be some position inside of a grid representing the world that they’re exploring. But the agent is in some sort of state. And in that state, the agent needs to choose to take an action. The agent likely has multiple actions they can choose from, but they pick an action. So they take an action in a particular state. And as a result of that, the agent will generally get two things in response as we model them. The agent gets a new state that they find themselves in. After being in this state, taking one action, they end up in some other state. And they’re also given some sort of numerical reward, positive meaning reward, meaning it was a good thing, negative generally meaning they did something bad, they received some sort of punishment. And that is all the information the agent has. It’s told what state it’s in. It makes some sort of action. And based on that, it ends up in another state. And it ends up getting some particular reward. And it needs to learn, based on that information, what actions to begin to take in the future. And so you could imagine generalizing this to a lot of different situations. This is oftentimes how you train if you’ve ever seen those robots that are now able to walk around the way humans do. It would be quite difficult to program the robot in exactly the right way to get it to walk the way humans do. You could instead train it through reinforcement learning, give it some sort of numerical reward every time it does something good, like take steps forward, and punish it every time it does something bad, like fall over, and then let the AI just learn based on that sequence of rewards, based on trying to take various different actions. You can begin to have the agent learn what to do in the future and what not to do. So in order to begin to formalize this, the first thing we need to do is formalize this notion of what we mean about states and actions and rewards, like what does this world look like? And oftentimes, we’ll formulate this world as what’s known as a Markov decision process, similar in spirit to Markov chains, which you might recall from before. But a Markov decision process is a model that we can use for decision making, for an agent trying to make decisions in its environment. And it’s a model that allows us to represent the various different states that an agent can be in, the various different actions that they can take, and also what the reward is for taking one action as opposed to another action. So what then does it actually look like? Well, if you recall a Markov chain from before, a Markov chain looked a little something like this, where we had a whole bunch of these individual states, and each state immediately transitioned to another state based on some probability distribution. We saw this in the context of the weather before, where if it was sunny, we said with some probability, it’ll be sunny the next day. With some other probability, it’ll be rainy, for example. But we could also imagine generalizing this. It’s not just sun and rain anymore. We just have these states, where one state leads to another state according to some probability distribution. But in this original model, there was no agent that had any control over this process. It was just entirely probability based, where with some probability, we moved to this next state. But maybe it’s going to be some other state with some other probability. What we’ll now have is the ability for the agent in this state to choose from a set of actions, where maybe instead of just one path forward, they have three different choices of actions that each lead up down different paths. And even this is a bit of an oversimplification, because in each of these states, you might imagine more branching points where there are more decisions that can be taken as well. So we’ve extended the Markov chain to say that from a state, you now have available action choices. And each of those actions might be associated with its own probability distribution of going to various different states. Then in addition, we’ll add another extension, where any time you move from a state, taking an action, going into this other state, we can associate a reward with that outcome, saying either r is positive, meaning some positive reward, or r is negative, meaning there was some sort of punishment. And this then is what we’ll consider to be a Markov decision process. That a Markov decision process has some initial set of states, of states in the world that we can be in. We have some set of actions that, given a state, I can say, what are the actions that are available to me in that state, an action that I can choose from? Then we have some transition model. The transition model before just said that, given my current state, what is the probability that I end up in that next state or this other state? The transition model now has effectively two things we’re conditioning on. We’re saying, given that I’m in this state and that I take this action, what’s the probability that I end up in this next state? Now maybe we live in a very deterministic world in this Markov decision process. We’re given a state and given an action. We know for sure what next state we’ll end up in. But maybe there’s some randomness in the world that when you take in a state and you take an action, you might not always end up in the exact same state. There might be some probabilities involved there as well. The Markov decision process can handle both of those possible cases. And then finally, we have a reward function, generally called r, that in this case says, what is the reward for being in this state, taking this action, and then getting to s prime this next state? So I’m in this original state. I take this action. I get to this next state. What is the reward for doing that process? And you can add up these rewards every time you take an action to get the total amount of rewards that an agent might get from interacting in a particular environment modeled using this Markov decision process. So what might this actually look like in practice? Well, let’s just create a little simulated world here where I have this agent that is just trying to navigate its way. This agent is this yellow dot here, like a robot in the world, trying to navigate its way through this grid. And ultimately, it’s trying to find its way to the goal. And if it gets to the green goal, then it’s going to get some sort of reward. But then we might also have some red squares that are places where you get some sort of punishment, some bad place where we don’t want the agent to go. And if it ends up in the red square, then our agent is going to get some sort of punishment as a result of that. But the agent originally doesn’t know all of these details. It doesn’t know that these states are associated with punishments. But maybe it does know that this state is associated with a reward. Maybe it doesn’t. But it just needs to sort of interact with the environment to try and figure out what to do and what not to do. So the first thing the agent might do is, given no additional information, if it doesn’t know what the punishments are, it doesn’t know where the rewards are, it just might try and take an action. And it takes an action and ends up realizing that it got some sort of punishment. And so what does it learn from that experience? Well, it might learn that when you’re in this state in the future, don’t take the action move to the right, that that is a bad action to take. That in the future, if you ever find yourself back in the state, don’t take this action of going to the right when you’re in this particular state, because that leads to punishment. That might be the intuition at least. And so you could try doing other actions. You move up, all right, that didn’t lead to any immediate rewards. Maybe try something else. Then maybe try something else. And all right, now you found that you got another punishment. And so you learn something from that experience. So the next time you do this whole process, you know that if you ever end up in this square, you shouldn’t take the down action, because being in this state and taking that action ultimately leads to some sort of punishment, a negative reward, in other words. And this process repeats. You might imagine just letting our agent explore the world, learning over time what states tend to correspond with poor actions, learning over time what states correspond with poor actions, until eventually, if it tries enough things randomly, it might find that eventually when you get to this state, if you take the up action in this state, it might find that you actually get a reward from that. And what it can learn from that is that if you’re in this state, you should take the up action, because that leads to a reward. And over time, you can also learn that if you’re in this state, you should take the left action, because that leads to this state that also lets you eventually get to the reward. So you begin to learn over time not only which actions are good in particular states, but also which actions are bad, such that once you know some sequence of good actions that leads you to some sort of reward, our agent can just follow those instructions, follow the experience that it has learned. We didn’t tell the agent what the goal was. We didn’t tell the agent where the punishments were. But the agent can begin to learn from this experience and learn to begin to perform these sorts of tasks better in the future. And so let’s now try to formalize this idea, formalize the idea that we would like to be able to learn in this state taking this action, is that a good thing or a bad thing? There are lots of different models for reinforcement learning. We’re just going to look at one of them today. And the one that we’re going to look at is a method known as Q-learning. And what Q-learning is all about is about learning a function, a function Q, that takes inputs S and A, where S is a state and A is an action that you take in that state. And what this Q function is going to do is it is going to estimate the value. How much reward will I get from taking this action in this state? Originally, we don’t know what this Q function should be. But over time, based on experience, based on trying things out and seeing what the result is, I would like to try and learn what Q of SA is for any particular state and any particular action that I might take in that state. So what is the approach? Well, the approach originally is we’ll start with Q SA equal to 0 for all states S and for all actions A. That initially, before I’ve ever started anything, before I’ve had any experiences, I don’t know the value of taking any action in any given state. So I’m going to assume that the value is just 0 all across the board. But then as I interact with the world, as I experience rewards or punishments, or maybe I go to a cell where I don’t get either reward or a punishment, I want to somehow update my estimate of Q SA. I want to continually update my estimate of Q SA based on the experiences and rewards and punishments that I’ve received, such that in the future, my knowledge of what actions are good and what states will be better. So when we take an action and receive some sort of reward, I want to estimate the new value of Q SA. And I estimate that based on a couple of different things. I estimate it based on the reward that I’m getting from taking this action and getting into the next state. But assuming the situation isn’t over, assuming there are still future actions that I might take as well, I also need to take into account the expected future rewards. That if you imagine an agent interacting with the environment, then sometimes you’ll take an action and get a reward, but then you can keep taking more actions and get more rewards, that these both are relevant, both the current reward I’m getting from this current step and also my future reward. And it might be the case that I’ll want to take a step that doesn’t immediately lead to a reward, because later on down the line, I know it will lead to more rewards as well. So there’s a balancing act between current rewards that the agent experiences and future rewards that the agent experiences as well. And then we need to update QSA. So we estimate the value of QSA based on the current reward and the expected future rewards. And then we need to update this Q function to take into account this new estimate. Now, we already, as we go through this process, we’ll already have an estimate for what we think the value is. Now we have a new estimate, and then somehow we need to combine these two estimates together, and we’ll look at more formal ways that we can actually begin to do that. So to actually show you what this formula looks like, here is the approach we’ll take with Q learning. We’re going to, again, start with Q of S and A being equal to 0 for all states. And then every time we take an action A in state S and observer reward R, we’re going to update our value, our estimate, for Q of SA. And the idea is that we’re going to figure out what the new value estimate is minus what our existing value estimate is. And so we have some preconceived notion for what the value is for taking this action in this state. Maybe our expectation is we currently think the value is 10. But then we’re going to estimate what we now think it’s going to be. Maybe the new value estimate is something like 20. So there’s a delta of 10 that our new value estimate is 10 points higher than what our current value estimate happens to be. And so we have a couple of options here. We need to decide how much we want to adjust our current expectation of what the value is of taking this action in this particular state. And what that difference is, how much we add or subtract from our existing notion of how much do we expect the value to be, is dependent on this parameter alpha, also called a learning rate. And alpha represents, in effect, how much we value new information compared to how much we value old information. An alpha value of 1 means we really value new information. But if we have a new estimate, then it doesn’t matter what our old estimate is. We’re only going to consider our new estimate because we always just want to take into consideration our new information. So the way that works is that if you imagine alpha being 1, well, then we’re taking the old value of QSA and then adding 1 times the new value minus the old value. And that just leaves us with the new value. So when alpha is 1, all we take into consideration is what our new estimate happens to be. But over time, as we go through a lot of experiences, we already have some existing information. We might have tried taking this action nine times already. And now we just tried it a 10th time. And we don’t only want to consider this 10th experience. I also want to consider the fact that my prior nine experiences, those were meaningful, too. And that’s data I don’t necessarily want to lose. And so this alpha controls that decision, controls how important is the new information. 0 would mean ignore all the new information. Just keep this Q value the same. 1 means replace the old information entirely with the new information. And somewhere in between, keep some sort of balance between these two values. We can put this equation a little bit more formally as well. The old value estimate is our old estimate for what the value is of taking this action in a particular state. That’s just Q of SNA. So we have it once here, and we’re going to add something to it. We’re going to add alpha times the new value estimate minus the old value estimate. But the old value estimate, we just look up by calling this Q function. And what then is the new value estimate? Based on this experience we have just taken, what is our new estimate for the value of taking this action in this particular state? Well, it’s going to be composed of two parts. It’s going to be composed of what reward did I just get from taking this action in this state. And then it’s going to be, what can I expect my future rewards to be from this point forward? So it’s going to be R, some reward I’m getting right now, plus whatever I estimate I’m going to get in the future. And how do I estimate what I’m going to get in the future? Well, it’s a bit of another call to this Q function. It’s going to be take the maximum across all possible actions I could take next and say, all right, of all of these possible actions I could take, which one is going to have the highest reward? And so this then looks a little bit complicated. This is going to be our notion for how we’re going to perform this kind of update. I have some estimate, some old estimate, for what the value is of taking this action in this state. And I’m going to update it based on new information that I experience some reward. I predict what my future reward is going to be. And using that I update what I estimate the reward will be for taking this action in this particular state. And there are other additions you might make to this algorithm as well. Sometimes it might not be the case that future rewards you want to wait equally to current rewards. Maybe you want an agent that values reward now over reward later. And so sometimes you can even add another term in here, some other parameter, where you discount future rewards and say future rewards are not as valuable as rewards immediately. That getting reward in the current time step is better than waiting a year and getting rewards later. But that’s something up to the programmer to decide what that parameter ought to be. But the big picture idea of this entire formula is to say that every time we experience some new reward, we take that into account. We update our estimate of how good is this action. And then in the future, we can make decisions based on that algorithm. Once we have some good estimate for every state and for every action, what the value is of taking that action, then we can do something like implement a greedy decision making policy. That if I am in a state and I want to know what action should I take in that state, well, then I consider for all of my possible actions, what is the value of QSA? What is my estimated value of taking that action in that state? And I will just pick the action that has the highest value after I evaluate that expression. So I pick the action that has the highest value. And based on that, that tells me what action I should take. At any given state that I’m in, I can just greedily say across all my actions, this action gives me the highest expected value. And so I’ll go ahead and choose that action as the action that I take as well. But there is a downside to this kind of approach. And then downside comes up in a situation like this, where we know that there is some solution that gets me to the reward. And our agent has been able to figure that out. But it might not necessarily be the best way or the fastest way. If the agent is allowed to explore a little bit more, it might find that it can get the reward faster by taking some other route instead, by going through this particular path that is a faster way to get to that ultimate goal. And maybe we would like for the agent to be able to figure that out as well. But if the agent always takes the actions that it knows to be best, well, when it gets to this particular square, it doesn’t know that this is a good action because it’s never really tried it. But it knows that going down eventually leads its way to this reward. So it might learn in the future that it should just always take this route and it’s never going to explore and go along that route instead. So in reinforcement learning, there is this tension between exploration and exploitation. And exploitation generally refers to using knowledge that the AI already has. The AI already knows that this is a move that leads to reward. So we’ll go ahead and use that move. And exploration is all about exploring other actions that we may not have explored as thoroughly before because maybe one of these actions, even if I don’t know anything about it, might lead to better rewards faster or to more rewards in the future. And so an agent that only ever exploits information and never explores might be able to get reward, but it might not maximize its rewards because it doesn’t know what other possibilities are out there, possibilities that we only know about by taking advantage of exploration. And so how can we try and address this? Well, one possible solution is known as the Epsilon greedy algorithm, where we set Epsilon equal to how often we want to just make a random move, where occasionally we will just make a random move in order to say, let’s try to explore and see what happens. And then the logic of the algorithm will be with probability 1 minus Epsilon, choose the estimated best move. In a greedy case, we’d always choose the best move. But in Epsilon greedy, we’re most of the time going to choose the best move or sometimes going to choose the best move. But sometimes with probability Epsilon, we’re going to choose a random move instead. So every time we’re faced with the ability to take an action, sometimes we’re going to choose the best move. Sometimes we’re just going to choose a random move. So this type of algorithm can be quite powerful in a reinforcement learning context by not always just choosing the best possible move right now, but sometimes, especially early on, allowing yourself to make random moves that allow you to explore various different possible states and actions more, and maybe over time, you might decrease your value of Epsilon. More and more often, choosing the best move after you’re more confident that you’ve explored what all of the possibilities actually are. So we can put this into practice. And one very common application of reinforcement learning is in game playing, that if you want to teach an agent how to play a game, you just let the agent play the game a whole bunch. And then the reward signal happens at the end of the game. When the game is over, if our AI won the game, it gets a reward of like 1, for example. And if it lost the game, it gets a reward of negative 1. And from that, it begins to learn what actions are good and what actions are bad. You don’t have to tell the AI what’s good and what’s bad, but the AI figures it out based on that reward. Winning the game is some signal, losing the game is some signal, and based on all of that, it begins to figure out what decisions it should actually make. So one very simple game, which you may have played before, is a game called Nim. And in the game of Nim, you’ve got a whole bunch of objects in a whole bunch of different piles, where here I’ve represented each pile as an individual row. So you’ve got one object in the first pile, three in the second pile, five in the third pile, seven in the fourth pile. And the game of Nim is a two player game where players take turns removing objects from piles. And the rule is that on any given turn, you were allowed to remove as many objects as you want from any one of these piles, any one of these rows. You have to remove at least one object, but you remove as many as you want from exactly one of the piles. And whoever takes the last object loses. So player one might remove four from this pile here. Player two might remove four from this pile here. So now we’ve got four piles left, one, three, one, and three. Player one might remove the entirety of the second pile. Player two, if they’re being strategic, might remove two from the third pile. Now we’ve got three piles left, each with one object left. Player one might remove one from one pile. Player two removes one from the other pile. And now player one is left with choosing this one object from the last pile, at which point player one loses the game. So fairly simple game. Piles of objects, any turn you choose how many objects to remove from a pile, whoever removes the last object loses. And this is the type of game you could encode into an AI fairly easily, because the states are really just four numbers. Every state is just how many objects in each of the four piles. And the actions are things like, how many am I going to remove from each one of these individual piles? And the reward happens at the end, that if you were the player that had to remove the last object, then you get some sort of punishment. But if you were not, and the other player had to remove the last object, well, then you get some sort of reward. So we could actually try and show a demonstration of this, that I’ve implemented an AI to play the game of Nim. All right, so here, what we’re going to do is create an AI as a result of training the AI on some number of games, that the AI is going to play against itself, where the idea is the AI will play games against itself, learn from each of those experiences, and learn what to do in the future. And then I, the human, will play against the AI. So initially, we’ll say train zero times, meaning we’re not going to let the AI play any practice games against itself in order to learn from its experiences. We’re just going to see how well it plays. And it looks like there are four piles. I can choose how many I remove from any one of the piles. So maybe from pile three, I will remove five objects, for example. So now, AI chose to take one item from pile zero. So I’m left with these piles now, for example. And so here, I could choose maybe to say, I would like to remove from pile two, I’ll remove all five of them, for example. And so AI chose to take two away from pile one. Now I’m left with one pile that has one object, one pile that has two objects. So from pile three, I will remove two objects. And now I’ve left the AI with no choice but to take that last one. And so the game is over, and I was able to win. But I did so because the AI was really just playing randomly. It didn’t have any prior experience that it was using in order to make these sorts of judgments. Now let me let the AI train itself on 10,000 games. I’m going to let the AI play 10,000 games of nim against itself. Every time it wins or loses, it’s going to learn from that experience and learn in the future what to do and what not to do. So here then, I’ll go ahead and run this again. And now you see the AI running through a whole bunch of training games, 10,000 training games against itself. And now it’s going to let me make these sorts of decisions. So now I’m going to play against the AI. Maybe I’ll remove one from pile three. And the AI took everything from pile three, so I’m left with three piles. I’ll go ahead and from pile two maybe remove three items. And the AI removes one item from pile zero. I’m left with two piles, each of which has two items in it. I’ll remove one from pile one, I guess. And the AI took two from pile two, leaving me with no choice but to take one away from pile one. So it seems like after playing 10,000 games of nim against itself, the AI has learned something about what states and what actions tend to be good and has begun to learn some sort of pattern for how to predict what actions are going to be good and what actions are going to be bad in any given state. So reinforcement learning can be a very powerful technique for achieving these sorts of game-playing agents, agents that are able to play a game well just by learning from experience, whether that’s playing against other people or by playing against itself and learning from those experiences as well. Now, nim is a bit of an easy game to use reinforcement learning for because there are so few states. There are only states that are as many as how many different objects are in each of these various different piles. You might imagine that it’s going to be harder if you think of a game like chess or games where there are many, many more states and many, many more actions that you can imagine taking, where it’s not going to be as easy to learn for every state and for every action what the value is going to be. So oftentimes in that case, we can’t necessarily learn exactly what the value is for every state and for every action, but we can approximate it. So much as we saw with minimax, so we could use a depth-limiting approach to stop calculating at a certain point in time, we can do a similar type of approximation known as function approximation in a reinforcement learning context where instead of learning a value of q for every state and every action, we just have some function that estimates what the value is for taking this action in this particular state that might be based on various different features of the state that the agent happens to be in, where you might have to choose what those features actually are. But you can begin to learn some patterns that generalize beyond one specific state and one specific action that you can begin to learn if certain features tend to be good things or bad things. Reinforcement learning can allow you, using a very similar mechanism, to generalize beyond one particular state and say, if this other state looks kind of like this state, then maybe the similar types of actions that worked in one state will also work in another state as well. And so this type of approach can be quite helpful as you begin to deal with reinforcement learning that exist in larger and larger state spaces where it’s just not feasible to explore all of the possible states that could actually exist. So there, then, are two of the main categories of reinforcement learning. Supervised learning, where you have labeled input and output pairs, and reinforcement learning, where an agent learns from rewards or punishments that it receives. The third major category of machine learning that we’ll just touch on briefly is known as unsupervised learning. And unsupervised learning happens when we have data without any additional feedback, without labels, that in the supervised learning case, all of our data had labels. We labeled the data point with whether that was a rainy day or not rainy day. And using those labels, we were able to infer what the pattern was. Or we labeled data as a counterfeit banknote or not a counterfeit. And using those labels, we were able to draw inferences and patterns to figure out what does a banknote look like versus not. In unsupervised learning, we don’t have any access to any of those labels. But we still would like to learn some of those patterns. And one of the tasks that you might want to perform in unsupervised learning is something like clustering, where clustering is just the task of, given some set of objects, organize it into distinct clusters, groups of objects that are similar to one another. And there’s lots of applications for clustering. It comes up in genetic research, where you might have a whole bunch of different genes and you want to cluster them into similar genes if you’re trying to analyze them across a population or across species. It comes up in an image if you want to take all the pixels of an image, cluster them into different parts of the image. Comes a lot up in market research if you want to divide your consumers into different groups so you know which groups to target with certain types of product advertisements, for example, and a number of other contexts as well in which clustering can be very applicable. One technique for clustering is an algorithm known as k-means clustering. And what k-means clustering is going to do is it is going to divide all of our data points into k different clusters. And it’s going to do so by repeating this process of assigning points to clusters and then moving around those clusters at centers. We’re going to define a cluster by its center, the middle of the cluster, and then assign points to that cluster based on which center is closest to that point. And I’ll show you an example of that now. Here, for example, I have a whole bunch of unlabeled data, just various data points that are in some sort of graphical space. And I would like to group them into various different clusters. But I don’t know how to do that originally. And let’s say I want to assign like three clusters to this group. And you have to choose how many clusters you want in k-means clustering that you could try multiple and see how well those values perform. But I’ll start just by randomly picking some places to put the centers of those clusters. Maybe I have a blue cluster, a red cluster, and a green cluster. And I’m going to start with the centers of those clusters just being in these three locations here. And what k-means clustering tells us to do is once I have the centers of the clusters, assign every point to a cluster based on which cluster center it is closest to. So we end up with something like this, where all of these points are closer to the blue cluster center than any other cluster center. All of these points here are closer to the green cluster center than any other cluster center. And then these two points plus these points over here, those are all closest to the red cluster center instead. So here then is one possible assignment of all these points to three different clusters. But it’s not great that it seems like in this red cluster, these points are kind of far apart. In this green cluster, these points are kind of far apart. It might not be my ideal choice of how I would cluster these various different data points. But k-means clustering is an iterative process that after I do this, there is a next step, which is that after I’ve assigned all of the points to the cluster center that it is nearest to, we are going to re-center the clusters, meaning take the cluster centers, these diamond shapes here, and move them to the middle, or the average, effectively, of all of the points that are in that cluster. So we’ll take this blue point, this blue center, and go ahead and move it to the middle or to the center of all of the points that were assigned to the blue cluster, moving it slightly to the right in this case. And we’ll do the same thing for red. We’ll move the cluster center to the middle of all of these points, weighted by how many points there are. There are more points over here, so the red center ends up moving a little bit further that way. And likewise, for the green center, there are many more points on this side of the green center. So the green center ends up being pulled a little bit further in this direction. So we re-center all of the clusters, and then we repeat the process. We go ahead and now reassign all of the points to the cluster center that they are now closest to. And now that we’ve moved around the cluster centers, these cluster assignments might change. That this point originally was closer to the red cluster center, but now it’s actually closer to the blue cluster center. Same goes for this point as well. And these three points that were originally closer to the green cluster center are now closer to the red cluster center instead. So we can reassign what colors or which clusters each of these data points belongs to, and then repeat the process again, moving each of these cluster means and the middles of the clusterism to the mean, the average, of all of the other points that happen to be there, and repeat the process again. Go ahead and assign each of the points to the cluster that they are closest to. So once we reach a point where we’ve assigned all the points to clusters to the cluster that they are nearest to, and nothing changed, we’ve reached a sort of equilibrium in this situation, where no points are changing their allegiance. And as a result, we can declare this algorithm is now over. And we now have some assignment of each of these points into three different clusters. And it looks like we did a pretty good job of trying to identify which points are more similar to one another than they are to points in other groups. So we have the green cluster down here, this blue cluster here, and then this red cluster over there as well. And we did so without any access to some labels to tell us what these various different clusters were. We just used an algorithm in an unsupervised sense without any of those labels to figure out which points belonged to which categories. And again, lots of applications for this type of clustering technique. And there are many more algorithms in each of these various different fields within machine learning, supervised and reinforcement and unsupervised. But those are many of the big picture foundational ideas that underlie a lot of these techniques, where these are the problems that we’re trying to solve. And we try and solve those problems using a number of different methods of trying to take data and learn patterns in that data, whether that’s trying to find neighboring data points that are similar or trying to minimize some sort of loss function or any number of other techniques that allow us to begin to try to solve these sorts of problems. That then was a look at some of the principles that are at the foundation of modern machine learning, this ability to take data and learn from that data so that the computer can perform a task even if they haven’t explicitly been given instructions in order to do so. Next time, we’ll continue this conversation about machine learning, looking at other techniques we can use for solving these sorts of problems. We’ll see you then. All right, welcome back, everyone, to an introduction to artificial intelligence with Python. Now, last time, we took a look at machine learning, a set of techniques that computers can use in order to take a set of data and learn some patterns inside of that data, learn how to perform a task even if we the programmers didn’t give the computer explicit instructions for how to perform that task. Today, we transition to one of the most popular techniques and tools within machine learning, that of neural networks. And neural networks were inspired as early as the 1940s by researchers who were thinking about how it is that humans learn, studying neuroscience in the human brain and trying to see whether or not we could apply those same ideas to computers as well and model computer learning off of human learning. So how is the brain structured? Well, very simply put, the brain consists of a whole bunch of neurons. And those neurons are connected to one another and communicate with one another in some way. In particular, if you think about the structure of a biological neural network, something like this, there are a couple of key properties that scientists observed. One was that these neurons are connected to each other and receive electrical signals from one another, that one neuron can propagate electrical signals to another neuron. And another point is that neurons process those input signals and then can be activated, that a neuron becomes activated at a certain point and then can propagate further signals onto neurons in the future. And so the question then became, could we take this biological idea of how it is that humans learn with brains and with neurons and apply that to a machine as well, in effect designing an artificial neural network, or an ANN, which will be a mathematical model for learning that is inspired by these biological neural networks? And what artificial neural networks will allow us to do is they will first be able to model some sort of mathematical function. Every time you look at a neural network, which we’ll see more of later today, each one of them is really just some mathematical function that is mapping certain inputs to particular outputs based on the structure of the network, that depending on where we place particular units inside of this neural network, that’s going to determine how it is that the network is going to function. And in particular, artificial neural networks are going to lend themselves to a way that we can learn what the network’s parameters should be. We’ll see more on that in just a moment. But in effect, we want a model such that it is easy for us to be able to write some code that allows for the network to be able to figure out how to model the right mathematical function given a particular set of input data. So in order to create our artificial neural network, instead of using biological neurons, we’re just going to use what we’re going to call units, units inside of a neural network, which we can represent kind of like a node in a graph, which will here be represented just by a blue circle like this. And these artificial units, these artificial neurons, can be connected to one another. So here, for instance, we have two units that are connected by this edge inside of this graph, effectively. And so what we’re going to do now is think of this idea as some sort of mapping from inputs to outputs. So we have one unit that is connected to another unit that we might think of this side of the input and that side of the output. And what we’re trying to do then is to figure out how to solve a problem, how to model some sort of mathematical function. And this might take the form of something we saw last time, which was something like we have certain inputs, like variables x1 and x2. And given those inputs, we want to perform some sort of task, a task like predicting whether or not it’s going to rain. And ideally, we’d like some way, given these inputs, x1 and x2, which stand for some sort of variables to do with the weather, we would like to be able to predict, in this case, a Boolean classification. Is it going to rain, or is it not going to rain? And we did this last time by way of a mathematical function. We defined some function, h, for our hypothesis function, that took as input x1 and x2, the two inputs that we cared about processing, in order to determine whether we thought it was going to rain or whether we thought it was not going to rain. The question then becomes, what does this hypothesis function do in order to make that determination? And we decided last time to use a linear combination of these input variables to determine what the output should be. So our hypothesis function was equal to something like this. Weight 0 plus weight 1 times x1 plus weight 2 times x2. So what’s going on here is that x1 and x2, those are input variables, the inputs to this hypothesis function. And each of those input variables is being multiplied by some weight, which is just some number. So x1 is being multiplied by weight 1, x2 is being multiplied by weight 2. And we have this additional weight, weight 0, that doesn’t get multiplied by an input variable at all, that just serves to either move the function up or move the function’s value down. You can think of this as either a weight that’s just multiplied by some dummy value, like the number 1. It’s multiplied by 1, and so it’s not multiplied by anything. Or sometimes, you’ll see in the literature, people call this variable weight 0 a bias, so that you can think of these variables as slightly different. We have weights that are multiplied by the input, and we separately add some bias to the result as well. You’ll hear both of those terminologies used when people talk about neural networks and machine learning. So in effect, what we’ve done here is that in order to define a hypothesis function, we just need to decide and figure out what these weights should be to determine what values to multiply by our inputs to get some sort of result. Of course, at the end of this, what we need to do is make some sort of classification, like rainy or not rainy. And to do that, we use some sort of function that defines some sort of threshold. And so we saw, for instance, the step function, which is defined as 1 if the result of multiplying the weights by the inputs is at least 0, otherwise it’s 0. And you can think of this line down the middle as kind of like a dotted line. Effectively, it stays at 0 all the way up to one point, and then the function steps or jumps up to 1. So it’s 0 before it reaches some threshold, and then it’s 1 after it reaches a particular threshold. And so this was one way we could define what will come to call an activation function, a function that determines when it is that this output becomes active, changes to 1 instead of being a 0. But we also saw that if we didn’t just want a purely binary classification, we didn’t want purely 1 or 0, but we wanted to allow for some in-between real numbered values, we could use a different function. And there are a number of choices, but the one that we looked at was the logistic sigmoid function that has sort of an s-shaped curve, where we could represent this as a probability that may be somewhere in between the probability of rain or something like 0.5. Maybe a little bit later, the probability of rain is 0.8. And so rather than just have a binary classification of 0 or 1, we could allow for numbers that are in between as well. And it turns out there are many other different types of activation functions, where an activation function just takes the output of multiplying the weights together and adding that bias, and then figuring out what the actual output should be. Another popular one is the rectified linear unit, otherwise known as ReLU. And the way that works is that it just takes its input and takes the maximum of that input and 0. So if it’s positive, it remains unchanged. But if it’s 0, if it’s negative, it goes ahead and levels out at 0. And there are other activation functions that we could choose as well. But in short, each of these activation functions, you can just think of as a function that gets applied to the result of all of this computation. We take some function g and apply it to the result of all of that calculation. And this then is what we saw last time, the way of defining some hypothesis function that takes in inputs, calculate some linear combination of those inputs, and then passes it through some sort of activation function to get our output. And this actually turns out to be the model for the simplest of neural networks, that we’re going to instead represent this mathematical idea graphically by using a structure like this. Here then is a neural network that has two inputs. We can think of this as x1 and this as x2. And then one output, which you can think of as classifying whether or not we think it’s going to rain or not rain, for example, in this particular instance. And so how exactly does this model work? Well, each of these two inputs represents one of our input variables, x1 and x2. And notice that these inputs are connected to this output via these edges, which are going to be defined by their weights. So these edges each have a weight associated with them, weight 1 and weight 2. And then this output unit, what it’s going to do is it is going to calculate an output based on those inputs and based on those weights. This output unit is going to multiply all the inputs by their weights, add in this bias term, which you can think of as an extra w0 term that gets added into it, and then we pass it through an activation function. So this then is just a graphical way of representing the same idea we saw last time just mathematically. And we’re going to call this a very simple neural network. And we’d like for this neural network to be able to learn how to calculate some function, that we want some function for the neural network to learn. And the neural network is going to learn what should the values of w0, w1, and w2 be? What should the activation function be in order to get the result that we would expect? So we can actually take a look at an example of this. What then is a very simple function that we might calculate? Well, if we recall back from when we were looking at propositional logic, one of the simplest functions we looked at was something like the or function that takes two inputs, x and y, and outputs 1, otherwise known as true, if either one of the inputs or both of them are 1, and outputs of 0 if both of the inputs are 0 or false. So this then is the or function. And this was the truth table for the or function, that as long as either of the inputs are 1, the output of the function is 1, and the only case where the output is 0 is where both of the inputs are 0. So the question is, how could we take this and train a neural network to be able to learn this particular function? What would those weights look like? Well, we could do something like this. Here’s our neural network. And I’ll propose that in order to calculate the or function, we’re going to use a value of 1 for each of the weights. And we’ll use a bias of negative 1. And then we’ll just use this step function as our activation function. How then does this work? Well, if I wanted to calculate something like 0 or 0, which we know to be 0 because false or false is false, then what are we going to do? Well, our output unit is going to calculate this input multiplied by the weight, 0 times 1, that’s 0. Same thing here, 0 times 1, that’s 0. And we’ll add to that the bias minus 1. So that’ll give us a result of negative 1. If we plot that on our activation function, negative 1 is here. It’s before the threshold, which means either 0 or 1. It’s only 1 after the threshold. Since negative 1 is before the threshold, the output that this unit provides is going to be 0. And that’s what we would expect it to be, that 0 or 0 should be 0. What if instead we had had 1 or 0, where this is the number 1? Well, in this case, in order to calculate what the output is going to be, we again have to do this weighted sum, 1 times 1, that’s 1. 0 times 1, that’s 0. Sum of that so far is 1. Add negative 1 to that. Well, then the output is 0. And if we plot 0 on the step function, 0 ends up being here. It’s just at the threshold. And so the output here is going to be 1, because the output of 1 or 0, that’s 1. So that’s what we would expect as well. And just for one more example, if I had 1 or 1, what would the result be? Well, 1 times 1 is 1. 1 times 1 is 1. The sum of those is 2. I add the bias term to that. I get the number 1. 1 plotted on this graph is way over there. That’s well beyond the threshold. And so this output is going to be 1 as well. The output is always 0 or 1, depending on whether or not we’re past the threshold. And this neural network then models the OR function, a very simple function, definitely. But it still is able to model it correctly. If I give it the inputs, it will tell me what x1 or x2 happens to be. And you could imagine trying to do this for other functions as well. A function like the AND function, for instance, that takes two inputs and calculates whether both x and y are true. So if x is 1 and y is 1, then the output of x and y is 1. But in all the other cases, the output is 0. How could we model that inside of a neural network as well? Well, it turns out we could do it in the same way, except instead of negative 1 as the bias, we can use negative 2 as the bias instead. What does that end up looking like? Well, if I had 1 and 1, that should be 1, because 1 true and true is equal to true. Well, I take 1 times 1, that’s 1. 1 times 1 is 1. I get a total sum of 2 so far. Now I add the bias of negative 2, and I get the value 0. And 0, when I plot it on the activation function, is just past that threshold, and so the output is going to be 1. But if I had any other input, for example, like 1 and 0, well, the weighted sum of these is 1 plus 0 is going to be 1. Minus 2 is going to give us negative 1, and negative 1 is not past that threshold, and so the output is going to be 0. So those then are some very simple functions that we can model using a neural network that has two inputs and one output, where our goal is to be able to figure out what those weights should be in order to determine what the output should be. And you could imagine generalizing this to calculate more complex functions as well, that maybe, given the humidity and the pressure, we want to calculate what’s the probability that it’s going to rain, for example. Or we might want to do a regression-style problem. We’re given some amount of advertising, and given what month it is maybe, we want to predict what our expected sales are going to be for that particular month. So you could imagine these inputs and outputs being different as well. And it turns out that in some problems, we’re not just going to have two inputs, and the nice thing about these neural networks is that we can compose multiple units together, make our networks more complex just by adding more units into this particular neural network. So the network we’ve been looking at has two inputs and one output. But we could just as easily say, let’s go ahead and have three inputs in there, or have even more inputs, where we could arbitrarily decide however many inputs there are to our problem, all going to be calculating some sort of output that we care about figuring out the value of. How then does the math work for figuring out that output? Well, it’s going to work in a very similar way. In the case of two inputs, we had two weights indicated by these edges, and we multiplied the weights by the numbers, adding this bias term. And we’ll do the same thing in the other cases as well. If I have three inputs, you’ll imagine multiplying each of these three inputs by each of these weights. If I had five inputs instead, we’re going to do the same thing. Here I’m saying sum up from 1 to 5, xi multiplied by weight i. So take each of the five input variables, multiply them by their corresponding weight, and then add the bias to that. So this would be a case where there are five inputs into this neural network, for example. But there could be more, arbitrarily many nodes that we want inside of this neural network, where each time we’re just going to sum up all of those input variables multiplied by their weight and then add the bias term at the very end. And so this allows us to be able to represent problems that have even more inputs just by growing the size of our neural network. Now, the next question we might ask is a question about how it is that we train these neural networks. In the case of the or function and the and function, they were simple enough functions that I could just tell you, like here, what the weights should be. And you could probably reason through it yourself what the weights should be in order to calculate the output that you want. But in general, with functions like predicting sales or predicting whether or not it’s going to rain, these are much trickier functions to be able to figure out. We would like the computer to have some mechanism of calculating what it is that the weights should be, how it is to set the weights so that our neural network is able to accurately model the function that we care about trying to estimate. And it turns out that the strategy for doing this, inspired by the domain of calculus, is a technique called gradient descent. And what gradient descent is, it is an algorithm for minimizing loss when you’re training a neural network. And recall that loss refers to how bad our hypothesis function happens to be, that we can define certain loss functions. And we saw some examples of loss functions last time that just give us a number for any particular hypothesis, saying, how poorly does it model the data? How many examples does it get wrong? How are they worse or less bad as compared to other hypothesis functions that we might define? And this loss function is just a mathematical function. And when you have a mathematical function, in calculus what you could do is calculate something known as the gradient, which you can think of as like a slope. It’s the direction the loss function is moving at any particular point. And what it’s going to tell us is, in which direction should we be moving these weights in order to minimize the amount of loss? And so generally speaking, we won’t get into the calculus of it. But the high level idea for gradient descent is going to look something like this. If we want to train a neural network, we’ll go ahead and start just by choosing the weights randomly. Just pick random weights for all of the weights in the neural network. And then we’ll use the input data that we have access to in order to train the network, in order to figure out what the weights should actually be. So we’ll repeat this process again and again. The first step is we’re going to calculate the gradient based on all of the data points. So we’ll look at all the data and figure out what the gradient is at the place where we currently are for the current setting of the weights, which means in which direction should we move the weights in order to minimize the total amount of loss, in order to make our solution better. And once we’ve calculated that gradient, which direction we should move in the loss function, well, then we can just update those weights according to the gradient. Take a small step in the direction of those weights in order to try to make our solution a little bit better. And the size of the step that we take, that’s going to vary. And you can choose that when you’re training a particular neural network. But in short, the idea is going to be take all the data points, figure out based on those data points in what direction the weights should move, and then move the weights one small step in that direction. And if you repeat that process over and over again, adjusting the weights a little bit at a time based on all the data points, eventually you should end up with a pretty good solution to trying to solve this sort of problem. At least that’s what we would hope to happen. Now, if you look at this algorithm, a good question to ask anytime you’re analyzing an algorithm is what is going to be the expensive part of doing the calculation? What’s going to take a lot of work to try to figure out? What is going to be expensive to calculate? And in particular, in the case of gradient descent, the really expensive part is this all data points part right here, having to take all of the data points and using all of those data points figure out what the gradient is at this particular setting of all of the weights. Because odds are in a big machine learning problem where you’re trying to solve a big problem with a lot of data, you have a lot of data points in order to calculate. And figuring out the gradient based on all of those data points is going to be expensive. And you’ll have to do it many times. You’ll likely repeat this process again and again and again, going through all the data points, taking one small step over and over as you try and figure out what the optimal setting of those weights happens to be. It turns out that we would ideally like to be able to train our neural networks faster, to be able to more quickly converge to some sort of solution that is going to be a good solution to the problem. So in that case, there are alternatives to just standard gradient descent, which looks at all of the data points at once. We can employ a method like stochastic gradient descent, which will randomly just choose one data point at a time to calculate the gradient based on, instead of calculating it based on all of the data points. So the idea there is that we have some setting of the weights. We pick a data point. And based on that one data point, we figure out in which direction should we move all of the weights and move the weights in that small direction, then take another data point and do that again and repeat this process again and again, maybe looking at each of the data points multiple times, but each time only using one data point to calculate the gradient, to calculate which direction we should move in. Now, just using one data point instead of all of the data points probably gives us a less accurate estimate of what the gradient actually is. But on the plus side, it’s going to be much faster to be able to calculate, that we can much more quickly calculate what the gradient is based on one data point, instead of calculating based on all of the data points and having to do all of that computational work again and again. So there are trade-offs here between looking at all of the data points and just looking at one data point. And it turns out that a middle ground that is also quite popular is a technique called mini-batch gradient descent, where the idea there is instead of looking at all of the data versus just a single point, we instead divide our data set up into small batches, groups of data points, where you can decide how big a particular batch is. But in short, you’re just going to look at a small number of points at any given time, hopefully getting a more accurate estimate of the gradient, but also not requiring all of the computational effort needed to look at every single one of these data points. So gradient descent, then, is this technique that we can use in order to train these neural networks, in order to figure out what the setting of all of these weights should be if we want some way to try and get an accurate notion of how it is that this function should work, some way of modeling how to transform the inputs into particular outputs. Now, so far, the networks that we’ve taken a look at have all been structured similar to this. We have some number of inputs, maybe two or three or five or more. And then we have one output that is just predicting like rain or no rain or just predicting one particular value. But often in machine learning problems, we don’t just care about one output. We might care about an output that has multiple different values associated with it. So in the same way that we could take a neural network and add units to the input layer, we can likewise add inputs or add outputs to the output layer as well. Instead of just one output, you could imagine we have two outputs, or we could have four outputs, for example, where in each case, as we add more inputs or add more outputs, if we want to keep this network fully connected between these two layers, we just need to add more weights, that now each of these input nodes has four weights associated with each of the four outputs. And that’s true for each of these various different input nodes. So as we add nodes, we add more weights in order to make sure that each of the inputs can somehow be connected to each of the outputs so that each output value can be calculated based on what the value of the input happens to be. So what might a case be where we want multiple different output values? Well, you might consider that in the case of weather predicting, for example, we might not just care whether it’s raining or not raining. There might be multiple different categories of weather that we would like to categorize the weather into. With just a single output variable, we can do a binary classification, like rain or no rain, for instance, 1 or 0. But it doesn’t allow us to do much more than that. With multiple output variables, I might be able to use each one to predict something a little different. Maybe I want to categorize the weather into one of four different categories, something like is it going to be raining or sunny or cloudy or snowy. And I now have four output variables that can be used to represent maybe the probability that it is rainy as opposed to sunny as opposed to cloudy or as opposed to snowy. How then would this neural network work? Well, we have some input variables that represent some data that we have collected about the weather. Each of those inputs gets multiplied by each of these various different weights. We have more multiplications to do, but these are fairly quick mathematical operations to perform. And then what we get is after passing them through some sort of activation function in the outputs, we end up getting some sort of number, where that number, you might imagine, you could interpret as a probability, like a probability that it is one category as opposed to another category. So here we’re saying that based on the inputs, we think there is a 10% chance that it’s raining, a 60% chance that it’s sunny, a 20% chance of cloudy, a 10% chance that it’s snowy. And given that output, if these represent a probability distribution, well, then you could just pick whichever one has the highest value, in this case, sunny, and say that, well, most likely, we think that this categorization of inputs means that the output should be snowy or should be sunny. And that is what we would expect the weather to be in this particular instance. And so this allows us to do these sort of multi-class classifications, where instead of just having a binary classification, 1 or 0, we can have as many different categories as we want. And we can have our neural network output these probabilities over which categories are more likely than other categories. And using that data, we’re able to draw some sort of inference on what it is that we should do. So this was sort of the idea of supervised machine learning. I can give this neural network a whole bunch of data, a whole bunch of input data corresponding to some label, some output data, like we know that it was raining on this day, we know that it was sunny on that day. And using all of that data, the algorithm can use gradient descent to figure out what all of the weights should be in order to create some sort of model that hopefully allows us a way to predict what we think the weather is going to be. But neural networks have a lot of other applications as well. You could imagine applying the same sort of idea to a reinforcement learning sort of example as well, where you remember that in reinforcement learning, what we wanted to do is train some sort of agent to learn what action to take, depending on what state they currently happen to be in. So depending on the current state of the world, we wanted the agent to pick from one of the available actions that is available to them. And you might model that by having each of these input variables represent some information about the state, some data about what state our agent is currently in. And then the output, for example, could be each of the various different actions that our agent could take, action 1, 2, 3, and 4. And you might imagine that this network would work in the same way, but based on these particular inputs, we go ahead and calculate values for each of these outputs. And those outputs could model which action is better than other actions. And we could just choose, based on looking at those outputs, which action we should take. And so these neural networks are very broadly applicable, that all they’re really doing is modeling some mathematical function. So anything that we can frame as a mathematical function, something like classifying inputs into various different categories or figuring out based on some input state what action we should take, these are all mathematical functions that we could attempt to model by taking advantage of this neural network structure, and in particular, taking advantage of this technique, gradient descent, that we can use in order to figure out what the weights should be in order to do this sort of calculation. Now, how is it that you would go about training a neural network that has multiple outputs instead of just one? Well, with just a single output, we could see what the output for that value should be, and then you update all of the weights that corresponded to it. And when we have multiple outputs, at least in this particular case, we can really think of this as four separate neural networks, that really we just have one network here that has these three inputs corresponding with these three weights corresponding to this one output value. And the same thing is true for this output value. This output value effectively defines yet another neural network that has these same three inputs, but a different set of weights that correspond to this output. And likewise, this output has its own set of weights as well, and same thing for the fourth output too. And so if you wanted to train a neural network that had four outputs instead of just one, in this case where the inputs are directly connected to the outputs, you could really think of this as just training four independent neural networks. We know what the outputs for each of these four should be based on our input data, and using that data, we can begin to figure out what all of these individual weights should be. And maybe there’s an additional step at the end to make sure that we turn these values into a probability distribution such that we can interpret which one is better than another or more likely than another as a category or something like that. So this then seems like it does a pretty good job of taking inputs and trying to predict what outputs should be. And we’ll see some real examples of this in just a moment as well. But it’s important then to think about what the limitations of this sort of approach is, of just taking some linear combination of inputs and passing it into some sort of activation function. And it turns out that when we do this in the case of binary classification, trying to predict does it belong to one category or another, we can only predict things that are linearly separable. Because we’re taking a linear combination of inputs and using that to define some decision boundary or threshold, then what we get is a situation where if we have this set of data, we can predict a line that separates linearly the red points from the blue points, but a single unit that is making a binary classification, otherwise known as a perceptron, can’t deal with a situation like this, where we’ve seen this type of situation before, where there is no straight line that just goes straight through the data that will divide the red points away from the blue points. It’s a more complex decision boundary. The decision boundary somehow needs to capture the things inside of this circle. And there isn’t really a line that will allow us to deal with that. So this is the limitation of the perceptron, these units that just make these binary decisions based on their inputs, that a single perceptron is only capable of learning a linearly separable decision boundary. All it can do is define a line. And sure, it can give us probabilities based on how close to that decision boundary we are, but it can only really decide based on a linear decision boundary. And so this doesn’t seem like it’s going to generalize well to situations where real world data is involved, because real world data often isn’t linearly separable. It often isn’t the case that we can just draw a line through the data and be able to divide it up into multiple groups. So what then is the solution to this? Well, what was proposed was the idea of a multilayer neural network, that so far all of the neural networks we’ve seen have had a set of inputs and a set of outputs, and the inputs are connected to those outputs. But in a multilayer neural network, this is going to be an artificial neural network that has an input layer still. It has an output layer, but also has one or more hidden layers in between. Other layers of artificial neurons or units that are going to calculate their own values as well. So instead of a neural network that looks like this with three inputs and one output, you might imagine in the middle here injecting a hidden layer, something like this. This is a hidden layer that has four nodes. You could choose how many nodes or units end up going into the hidden layer. You can have multiple hidden layers as well. And so now each of these inputs isn’t directly connected to the output. Each of the inputs is connected to this hidden layer. And then all of the nodes in the hidden layer, those are connected to the one output. And so this is just another step that we can take towards calculating more complex functions. Each of these hidden units will calculate its output value, otherwise known as its activation, based on a linear combination of all the inputs. And once we have values for all of these nodes, as opposed to this just being the output, we do the same thing again. Calculate the output for this node based on multiplying each of the values for these units by their weights as well. So in effect, the way this works is that we start with inputs. They get multiplied by weights in order to calculate values for the hidden nodes. Those get multiplied by weights in order to figure out what the ultimate output is going to be. And the advantage of layering things like this is it gives us an ability to model more complex functions, that instead of just having a single decision boundary, a single line dividing the red points from the blue points, each of these hidden nodes can learn a different decision boundary. And we can combine those decision boundaries to figure out what the ultimate output is going to be. And as we begin to imagine more complex situations, you could imagine each of these nodes learning some useful property or learning some useful feature of all of the inputs and us somehow learning how to combine those features together in order to get the output that we actually want. Now, the natural question when we begin to look at this now is to ask the question of, how do we train a neural network that has hidden layers inside of it? And this turns out to initially be a bit of a tricky question, because the input data that we are given is we are given values for all of the inputs, and we’re given what the value of the output should be, what the category is, for example. But the input data doesn’t tell us what the values for all of these nodes should be. So we don’t know how far off each of these nodes actually is because we’re only given data for the inputs and the outputs. The reason this is called the hidden layer is because the data that is made available to us doesn’t tell us what the values for all of these intermediate nodes should actually be. And so the strategy people came up with was to say that if you know what the error or the losses on the output node, well, then based on what these weights are, if one of these weights is higher than another, you can calculate an estimate for how much the error from this node was due to this part of the hidden node, or this part of the hidden layer, or this part of the hidden layer, based on the values of these weights, in effect saying that based on the error from the output, I can back propagate the error and figure out an estimate for what the error is for each of these nodes in the hidden layer as well. And there’s some more calculus here that we won’t get into the details of, but the idea of this algorithm is known as back propagation. It’s an algorithm for training a neural network with multiple different hidden layers. And the idea for this, the pseudocode for it, will again be if we want to run gradient descent with back propagation. We’ll start with a random choice of weights, as we did before. And now we’ll go ahead and repeat the training process again and again. But what we’re going to do each time is now we’re going to calculate the error for the output layer first. We know the output and what it should be, and we know what we calculated so we can figure out what the error there is. But then we’re going to repeat for every layer, starting with the output layer, moving back into the hidden layer, then the hidden layer before that if there are multiple hidden layers, going back all the way to the very first hidden layer, assuming there are multiple, we’re going to propagate the error back one layer. Whatever the error was from the output, figure out what the error should be a layer before that based on what the values of those weights are. And then we can update those weights. So graphically, the way you might think about this is that we first start with the output. We know what the output should be. We know what output we calculated. And based on that, we can figure out, all right, how do we need to update those weights? Backpropagating the error to these nodes. And using that, we can figure out how we should update these weights. And you might imagine if there are multiple layers, we could repeat this process again and again to begin to figure out how all of these weights should be updated. And this backpropagation algorithm is really the key algorithm that makes neural networks possible. It makes it possible to take these multi-level structures and be able to train those structures depending on what the values of these weights are in order to figure out how it is that we should go about updating those weights in order to create some function that is able to minimize the total amount of loss, to figure out some good setting of the weights that will take the inputs and translate it into the output that we expect. And this works, as we said, not just for a single hidden layer. But you can imagine multiple hidden layers, where each hidden layer we just define however many nodes we want, where each of the nodes in one layer, we can connect to the nodes in the next layer, defining more and more complex networks that are able to model more and more complex types of functions. And so this type of network is what we might call a deep neural network, part of a larger family of deep learning algorithms, if you’ve ever heard that term. And all deep learning is about is it’s using multiple layers to be able to predict and be able to model higher level features inside of the input, to be able to figure out what the output should be. And so a deep neural network is just a neural network that has multiple of these hidden layers, where we start at the input, calculate values for this layer, then this layer, then this layer, and then ultimately get an output. And this allows us to be able to model more and more sophisticated types of functions, that each of these layers can calculate something a little bit different, and we can combine that information to figure out what the output should be. Of course, as with any situation of machine learning, as we begin to make our models more and more complex, to model more and more complex functions, the risk we run is something like overfitting. And we talked about overfitting last time in the context of overfitting based on when we were training our models to be able to learn some sort of decision boundary, where overfitting happens when we fit too closely to the training data. And as a result, we don’t generalize well to other situations as well. And one of the risks we run with a far more complex neural network that has many, many different nodes is that we might overfit based on the input data. We might grow over reliant on certain nodes to calculate things just purely based on the input data that doesn’t allow us to generalize very well to the output. And there are a number of strategies for dealing with overfitting. But one of the most popular in the context of neural networks is a technique known as dropout. And what dropout does is it, when we’re training the neural network, what we’ll do in dropout is temporarily remove units, temporarily remove these artificial neurons from our network chosen at random. And the goal here is to prevent over-reliance on certain units. What generally happens in overfitting is that we begin to over-rely on certain units inside the neural network to be able to tell us how to interpret the input data. What dropout will do is randomly remove some of these units in order to reduce the chance that we over-rely on certain units to make our neural network more robust, to be able to handle the situations even when we just drop out particular neurons entirely. So the way that might work is we have a network like this. And as we’re training it, when we go about trying to update the weights the first time, we’ll just randomly pick some percentage of the nodes to drop out of the network. It’s as if those nodes aren’t there at all. It’s as if the weights associated with those nodes aren’t there at all. And we’ll train it this way. Then the next time we update the weights, we’ll pick a different set and just go ahead and train that way. And then again, randomly choose and train with other nodes that have been dropped out as well. And the goal of that is that after the training process, if you train by dropping out random nodes inside of this neural network, you hopefully end up with a network that’s a little bit more robust, that doesn’t rely too heavily on any one particular node, but more generally learns how to approximate a function in general. So that then is a look at some of these techniques that we can use in order to implement a neural network, to get at the idea of taking this input, passing it through these various different layers in order to produce some sort of output. And what we’d like to do now is take those ideas and put them into code. And to do that, there are a number of different machine learning libraries, neural network libraries that we can use that allow us to get access to someone’s implementation of back propagation and all of these hidden layers. And one of the most popular, developed by Google, is known as TensorFlow, a library that we can use for quickly creating neural networks and modeling them and running them on some sample data to see what the output is going to be. And before we actually start writing code, we’ll go ahead and take a look at TensorFlow’s playground, which will be an opportunity for us just to play around with this idea of neural networks in different layers, just to get a sense for what it is that we can do by taking advantage of neural networks. So let’s go ahead and go into TensorFlow’s playground, which you can go to by visiting that URL from before. And what we’re going to do now is we’re going to try and learn the decision boundary for this particular output. I want to learn to separate the orange points from the blue points. And I’d like to learn some sort of setting of weights inside of a neural network that will be able to separate those from each other. The features we have access to, our input data, are the x value and the y value, so the two values along each of the two axes. And what I’ll do now is I can set particular parameters, like what activation function I would like to use. And I’ll just go ahead and press play and see what happens. And what happens here is that you’ll see that just by using these two input features, the x value and the y value, with no hidden layers, just take the input, x and y values, and figure out what the decision boundary is. Our neural network learns pretty quickly that in order to divide these two points, we should just use this line. This line acts as a decision boundary that separates this group of points from that group of points, and it does it very well. You can see up here what the loss is. The training loss is 0, meaning we were able to perfectly model separating these two points from each other inside of our training data. So this was a fairly simple case of trying to apply a neural network because the data is very clean. It’s very nicely linearly separable. We could just draw a line that separates all of those points from each other. Let’s now consider a more complex case. So I’ll go ahead and pause the simulation, and we’ll go ahead and look at this data set here. This data set is a little bit more complex now. In this data set, we still have blue and orange points that we’d like to separate from each other. But there’s no single line that we can draw that is going to be able to figure out how to separate the blue from the orange, because the blue is located in these two quadrants, and the orange is located here and here. It’s a more complex function to be able to learn. So let’s see what happens. If we just try and predict based on those inputs, the x and y coordinates, what the output should be, I’ll press Play. And what you’ll notice is that we’re not really able to draw much of a conclusion, that we’re not able to very cleanly see how we should divide the orange points from the blue points, and you don’t see a very clean separation there. So it seems like we don’t have enough sophistication inside of our network to be able to model something that is that complex. We need a better model for this neural network. And I’ll do that by adding a hidden layer. So now I have a hidden layer that has two neurons inside of it. So I have two inputs that then go to two neurons inside of a hidden layer that then go to our output. And now I’ll press Play. And what you’ll notice here is that we’re able to do slightly better. We’re able to now say, all right, these points are definitely blue. These points are definitely orange. We’re still struggling a little bit with these points up here, though. And what we can do is we can see for each of these hidden neurons, what is it exactly that these hidden neurons are doing? Each hidden neuron is learning its own decision boundary. And we can see what that boundary is. This first neuron is learning, all right, this line that seems to separate some of the blue points from the rest of the points. This other hidden neuron is learning another line that seems to be separating the orange points in the lower right from the rest of the points. So that’s why we’re able to figure out these two areas in the bottom region. But we’re still not able to perfectly classify all of the points. So let’s go ahead and add another neuron. Now we’ve got three neurons inside of our hidden layer and see what we’re able to learn now. All right, well, now we seem to be doing a better job. By learning three different decision boundaries, which each of the three neurons inside of our hidden layer, we’re able to much better figure out how to separate these blue points from the orange points. And we can see what each of these hidden neurons is learning. Each one is learning a slightly different decision boundary. And then we’re combining those decision boundaries together to figure out what the overall output should be. And then we can try it one more time by adding a fourth neuron there and try learning that. And it seems like now we can do even better at trying to separate the blue points from the orange points. But we were only able to do this by adding a hidden layer, by adding some layer that is learning some other boundaries and combining those boundaries to determine the output. And the strength, the size and thickness of these lines indicate how high these weights are, how important each of these inputs is for making this sort of calculation. And we can do maybe one more simulation. Let’s go ahead and try this on a data set that looks like this. Go ahead and get rid of the hidden layer. Here now we’re trying to separate the blue points from the orange points where all the blue points are located, again, inside of a circle effectively. So we’re not going to be able to learn a line. Notice I press Play. And we’re really not able to draw any sort of classification at all because there is no line that cleanly separates the blue points from the orange points. So let’s try to solve this by introducing a hidden layer. I’ll go ahead and press Play. And all right, with two neurons in a hidden layer, we’re able to do a little better because we effectively learned two different decision boundaries. We learned this line here. And we learned this line on the right-hand side. And right now we’re just saying, all right, well, if it’s in between, we’ll call it blue. And if it’s outside, we’ll call it orange. So not great, but certainly better than before, that we’re learning one decision boundary and another. And based on those, we can figure out what the output should be. But let’s now go ahead and add a third neuron and see what happens now. I go ahead and train it. And now, using three different decision boundaries that are learned by each of these hidden neurons, we’re able to much more accurately model this distinction between blue points and orange points. We’re able to figure out maybe with these three decision boundaries, combining them together, you can imagine figuring out what the output should be and how to make that sort of classification. And so the goal here is just to get a sense for having more neurons in these hidden layers allows us to learn more structure in the data, allows us to figure out what the relevant and important decision boundaries are. And then using this backpropagation algorithm, we’re able to figure out what the values of these weights should be in order to train this network to be able to classify one category of points away from another category of points instead. And this is ultimately what we’re going to be trying to do whenever we’re training a neural network. So let’s go ahead and actually see an example of this. You’ll recall from last time that we had this banknotes file that included information about counterfeit banknotes as opposed to authentic banknotes, where I had four different values for each banknote and then a categorization of whether that banknote is considered to be authentic or a counterfeit note. And what I wanted to do was, based on that input information, figure out some function that could calculate based on the input information what category it belonged to. And what I’ve written here in banknotes.py is a neural network that will learn just that, a network that learns based on all of the input whether or not we should categorize a banknote as authentic or as counterfeit. The first step is the same as what we saw from last time. I’m really just reading the data in and getting it into an appropriate format. And so this is where more of the writing Python code on your own comes in, in terms of manipulating this data, massaging the data into a format that will be understood by a machine learning library like scikit-learn or like TensorFlow. And so here I separate it into a training and a testing set. And now what I’m doing down below is I’m creating a neural network. Here I’m using TF, which stands for TensorFlow. Up above, I said import TensorFlow as TF, TF just an abbreviation that we’ll often use so we don’t need to write out TensorFlow every time we want to use anything inside of the library. I’m using TF.keras. Keras is an API, a set of functions that we can use in order to manipulate neural networks inside of TensorFlow. And it turns out there are other machine learning libraries that also use the Keras API. But here I’m saying, all right, go ahead and give me a model that is a sequential model, a sequential neural network, meaning one layer after another. And now I’m going to add to that model what layers I want inside of my neural network. So here I’m saying model.add. Go ahead and add a dense layer. And when we say a dense layer, we mean a layer that is just each of the nodes inside of the layer is going to be connected to each of the nodes from the previous layer. So we have a densely connected layer. This layer is going to have eight units inside of it. So it’s going to be a hidden layer inside of a neural network with eight different units, eight artificial neurons, each of which might learn something different. And I just sort of chose eight arbitrarily. You could choose a different number of hidden nodes inside of the layer. And as we saw before, depending on the number of units there are inside of your hidden layer, more units means you can learn more complex functions. So maybe you can more accurately model the training data. But it comes at the cost. More units means more weights that you need to figure out how to update. So it might be more expensive to do that calculation. And you also run the risk of overfitting on the data. If you have too many units and you learn to just overfit on the training data, that’s not good either. So there is a balance. And there’s often a testing process where you’ll train on some data and maybe validate how well you’re doing on a separate set of data, often called a validation set, to see, all right, which setting of parameters. How many layers should I have? How many units should be in each layer? Which one of those performs the best on the validation set? So you can do some testing to figure out what these hyper parameters, so called, should be equal to. Next, I specify what the input shape is. Meaning, all right, what does my input look like? My input has four values. And so the input shape is just four, because we have four inputs. And then I specify what the activation function is. And the activation function, again, we can choose. There are a number of different activation functions. Here I’m using relu, which you might recall from earlier. And then I’ll add an output layer. So I have my hidden layer. Now I’m adding one more layer that will just have one unit, because all I want to do is predict something like counterfeit build or authentic build. So I just need a single unit. And the activation function I’m going to use here is that sigmoid activation function, which, again, was that S-shaped curve that just gave us a probability of what is the probability that this is a counterfeit build, as opposed to an authentic build. So that, then, is the structure of my neural network, a sequential neural network that has one hidden layer with eight units inside of it, and then one output layer that just has a single unit inside of it. And I can choose how many units there are. I can choose the activation function. Then I’m going to compile this model. TensorFlow gives you a choice of how you would like to optimize the weights. There are various different algorithms for doing that. What type of loss function you want to use. Again, many different options for doing that. And then how I want to evaluate my model, well, I care about accuracy. I care about how many of my points am I able to classify correctly versus not correctly as counterfeit or not counterfeit. And I would like it to report to me how accurate my model is performing. Then, now that I’ve defined that model, I call model.fit to say go ahead and train the model. Train it on all the training data plus all of the training labels. So labels for each of those pieces of training data. And I’m saying run it for 20 epics, meaning go ahead and go through each of these training points 20 times, effectively. Go through the data 20 times and keep trying to update the weights. If I did it for more, I could train for even longer and maybe get a more accurate result. But then after I fit it on all the data, I’ll go ahead and just test it. I’ll evaluate my model using model.evaluate built into TensorFlow that is just going to tell me how well do I perform on the testing data. So ultimately, this is just going to give me some numbers that tell me how well we did in this particular case. So now what I’m going to do is go into banknotes and go ahead and run banknotes.py. And what’s going to happen now is it’s going to read in all of that training data. It’s going to generate a neural network with all my inputs, my eight hidden units inside my layer, and then an output unit. And now what it’s doing is it’s training. It’s training 20 times. And each time you can see how my accuracy is increasing on my training data. It starts off the very first time not very accurate, though better than random, something like 79% of the time. It’s able to accurately classify one bill from another. But as I keep training, notice this accuracy value improves and improves and improves until after I’ve trained through all the data points 20 times, it looks like my accuracy is above 99% on the training data. And here’s where I tested it on a whole bunch of testing data. And it looks like in this case, I was also like 99.8% accurate. So just using that, I was able to generate a neural network that can detect counterfeit bills from authentic bills based on this input data 99.8% of the time, at least based on this particular testing data. And I might want to test it with more data as well, just to be confident about that. But this is really the value of using a machine learning library like TensorFlow. And there are others available for Python and other languages as well. But all I have to do is define the structure of the network and define the data that I’m going to pass into the network. And then TensorFlow runs the backpropagation algorithm for learning what all of those weights should be, for figuring out how to train this neural network to be able to accurately, as accurately as possible, figure out what the output values should be there as well. And so this then was a look at what it is that neural networks can do just using these sequences of layer after layer after layer. And you can begin to imagine applying these to much more general problems. And one big problem in computing and artificial intelligence more generally is the problem of computer vision. Computer vision is all about computational methods for analyzing and understanding images. You might have pictures that you want the computer to figure out how to deal with, how to process those images and figure out how to produce some sort of useful result out of this. You’ve seen this in the context of social media websites that are able to look at a photo that contains a whole bunch of faces. And it’s able to figure out what’s a picture of whom and label those and tag them with appropriate people. This is becoming increasingly relevant as we begin to discuss self-driving cars, that these cars now have cameras. And we would like for the computer to have some sort of algorithm that looks at the image and figures out what color is the light, what cars are around us and in what direction, for example. And so computer vision is all about taking an image and figuring out what sort of computation, what sort of calculation we can do with that image. It’s also relevant in the context of something like handwriting recognition. This, what you’re looking at, is an example of the MNIST data set. It’s a big data set just of handwritten digits that we could use to ideally try and figure out how to predict, given someone’s handwriting, given a photo of a digit that they have drawn, can you predict whether it’s a 0, 1, 2, 3, 4, 5, 6, 7, 8, or 9, for example. So this sort of handwriting recognition is yet another task that we might want to use computer vision tasks and tools to be able to apply it towards. This might be a task that we might care about. So how, then, can we use neural networks to be able to solve a problem like this? Well, neural networks rely upon some sort of input where that input is just numerical data. We have a whole bunch of units where each one of them just represents some sort of number. And so in the context of something like handwriting recognition or in the context of just an image, you might imagine that an image is really just a grid of pixels, grid of dots where each dot has some sort of color. And in the context of something like handwriting recognition, you might imagine that if you just fill in each of these dots in a particular way, you can generate a 2 or an 8, for example, based on which dots happen to be shaded in and which dots are not. And we can represent each of these pixel values just using numbers. So for a particular pixel, for example, 0 might represent entirely black. Depending on how you’re representing color, it’s often common to represent color values on a 0 to 255 range so that you can represent a color using 8 bits for a particular value, like how much white is in the image. So 0 might represent all black. 255 might represent entirely white as a pixel. And somewhere in between might represent some shade of gray, for example. But you might imagine not just having a single slider that determines how much white is in the image, but if you had a color image, you might imagine three different numerical values, a red, green, and blue value, where the red value controls how much red is in the image. We have one value for controlling how much green is in the pixel and one value for how much blue is in the pixel as well. And depending on how it is that you set these values of red, green, and blue, you can get a different color. And so any pixel can really be represented, in this case, by three numerical values, a red value, a green value, and a blue value. And if you take a whole bunch of these pixels, assemble them together inside of a grid of pixels, then you really just have a whole bunch of numerical values that you can use in order to perform some sort of prediction task. And so what you might imagine doing is using the same techniques we talked about before, just design a neural network with a lot of inputs, that for each of the pixels, we might have one or three different inputs in the case of a color image, a different input that is just connected to a deep neural network, for example. And this deep neural network might take all of the pixels inside of the image of what digit a person drew. And the output might be like 10 neurons that classify it as a 0, or a 1, or a 2, or a 3, or just tells us in some way what that digit happens to be. Now, there are a couple of drawbacks to this approach. The first drawback to the approach is just the size of this input array, that we have a whole bunch of inputs. If we have a big image that has a lot of different channels, we’re looking at a lot of inputs, and therefore a lot of weights that we have to calculate. And a second problem is the fact that by flattening everything into just this structure of all the pixels, we’ve lost access to a lot of the information about the structure of the image that’s relevant, that really, when a person looks at an image, they’re looking at particular features of the image. They’re looking at curves. They’re looking at shapes. They’re looking at what things can you identify in different regions of the image, and maybe put those things together in order to get a better picture of what the overall image is about. And by just turning it into pixel values for each of the pixels, sure, you might be able to learn that structure, but it might be challenging in order to do so. It might be helpful to take advantage of the fact that you can use properties of the image itself, the fact that it’s structured in a particular way, to be able to improve the way that we learn based on that image too. So in order to figure out how we can train our neural networks to better be able to deal with images, we’ll introduce a couple of ideas, a couple of algorithms that we can apply that allow us to take the image and extract some useful information out of that image. And the first idea we’ll introduce is the notion of image convolution. And what image convolution is all about is it’s about filtering an image, sort of extracting useful or relevant features out of the image. And the way we do that is by applying a particular filter that basically adds the value for every pixel with the values for all of the neighboring pixels to it, according to some sort of kernel matrix, which we’ll see in a moment, is going to allow us to weight these pixels in various different ways. And the goal of image convolution, then, is to extract some sort of interesting or useful features out of an image, to be able to take a pixel and, based on its neighboring pixels, maybe predict some sort of valuable information. Something like taking a pixel and looking at its neighboring pixels, you might be able to predict whether or not there’s some sort of curve inside the image, or whether it’s forming the outline of a particular line or a shape, for example. And that might be useful if you’re trying to use all of these various different features to combine them to say something meaningful about an image as a whole. So how, then, does image convolution work? Well, we start with a kernel matrix. And the kernel matrix looks something like this. And the idea of this is that, given a pixel that will be the middle pixel, we’re going to multiply each of the neighboring pixels by these values in order to get some sort of result by summing up all the numbers together. So if I take this kernel, which you can think of as a filter that I’m going to apply to the image, and let’s say that I take this image. This is a 4 by 4 image. We’ll think of it as just a black and white image, where each one is just a single pixel value. So somewhere between 0 and 255, for example. So we have a whole bunch of individual pixel values like this. And what I’d like to do is apply this kernel, this filter, so to speak, to this image. And the way I’ll do that is, all right, the kernel is 3 by 3. You can imagine a 5 by 5 kernel or a larger kernel, too. And I’ll take it and just first apply it to the first 3 by 3 section of the image. And what I’ll do is I’ll take each of these pixel values, multiply it by its corresponding value in the filter matrix, and add all of the results together. So here, for example, I’ll say 10 times 0, plus 20 times negative 1, plus 30 times 0, so on and so forth, doing all of this calculation. And at the end, if I take all these values, multiply them by their corresponding value in the kernel, add the results together, for this particular set of 9 pixels, I get the value of 10, for example. And then what I’ll do is I’ll slide this 3 by 3 grid, effectively, over. I’ll slide the kernel by 1 to look at the next 3 by 3 section. Here, I’m just sliding it over by 1 pixel. But you might imagine a different stride length, or maybe I jump by multiple pixels at a time if you really wanted to. You have different options here. But here, I’m just sliding over, looking at the next 3 by 3 section. And I’ll do the same math, 20 times 0, plus 30 times negative 1, plus 40 times 0, plus 20 times negative 1, so on and so forth, plus 30 times 5. And what I end up getting is the number 20. Then you can imagine shifting over to this one, doing the same thing, calculating the number 40, for example, and then doing the same thing here, and calculating a value there as well. And so what we have now is what we’ll call a feature map. We have taken this kernel, applied it to each of these various different regions, and what we get is some representation of a filtered version of that image. And so to give a more concrete example of why it is that this kind of thing could be useful, let’s take this kernel matrix, for example, which is quite a famous one, that has an 8 in the middle, and then all of the neighboring pixels get a negative 1. And let’s imagine we wanted to apply that to a 3 by 3 part of an image that looks like this, where all the values are the same. They’re all 20, for instance. Well, in this case, if you do 20 times 8, and then subtract 20, subtract 20, subtract 20 for each of the eight neighbors, well, the result of that is you just get that expression, which comes out to be 0. You multiplied 20 by 8, but then you subtracted 20 eight times, according to that particular kernel. The result of all that is just 0. So the takeaway here is that when a lot of the pixels are the same value, we end up getting a value close to 0. If, though, we had something like this, 20 is along this first row, then 50 is in the second row, and 50 is in the third row, well, then when you do this, because it’s the same kind of math, 20 times negative 1, 20 times negative 1, so on and so forth, then I get a higher value, a value like 90 in this particular case. And so the more general idea here is that by applying this kernel, negative 1s, 8 in the middle, and then negative 1s, what I get is when this middle value is very different from the neighboring values, like 50 is greater than these 20s, then you’ll end up with a value higher than 0. If this number is higher than its neighbors, you end up getting a bigger output. But if this value is the same as all of its neighbors, then you get a lower output, something like 0. And it turns out that this sort of filter can therefore be used in something like detecting edges in an image. Or I want to detect the boundaries between various different objects inside of an image. I might use a filter like this, which is able to tell whether the value of this pixel is different from the values of the neighboring pixel, if it’s greater than the values of the pixels that happen to surround it. And so we can use this in terms of image filtering. And so I’ll show you an example of that. I have here in filter.py a file that uses Python’s image library, or PIL, to do some image filtering. I go ahead and open an image. And then all I’m going to do is apply a kernel to that image. It’s going to be a 3 by 3 kernel, same kind of kernel we saw before. And here is the kernel. This is just a list representation of the same matrix that I showed you a moment ago. It’s negative 1, negative 1, negative 1. The second row is negative 1, 8, negative 1. And the third row is all negative 1s. And then at the end, I’m going to go ahead and show the filtered image. So if, for example, I go into convolution directory and I open up an image, like bridge.png, this is what an input image might look like, just an image of a bridge over a river. Now I’m going to go ahead and run this filter program on the bridge. And what I get is this image here. Just by taking the original image and applying that filter to each 3 by 3 grid, I’ve extracted all of the boundaries, all of the edges inside the image that separate one part of the image from another. So here I’ve got a representation of boundaries between particular parts of the image. And you might imagine that if a machine learning algorithm is trying to learn what an image is of, a filter like this could be pretty useful. Maybe the machine learning algorithm doesn’t care about all of the details of the image. It just cares about certain useful features. It cares about particular shapes that are able to help it determine that based on the image, this is going to be a bridge, for example. And so this type of idea of image convolution can allow us to apply filters to images that allow us to extract useful results out of those images, taking an image and extracting its edges, for example. And you might imagine many other filters that could be applied to an image that are able to extract particular values as well. And a filter might have separate kernels for the red values, the green values, and the blue values that are all summed together at the end, such that you could have particular filters looking for, is there red in this part of the image? Are there green in other parts of the image? You can begin to assemble these relevant and useful filters that are able to do these calculations as well. So that then was the idea of image convolution, applying some sort of filter to an image to be able to extract some useful features out of that image. But all the while, these images are still pretty big. There’s a lot of pixels involved in the image. And realistically speaking, if you’ve got a really big image, that poses a couple of problems. One, it means a lot of input going into the neural network. But two, it also means that we really have to care about what’s in each particular pixel. Whereas realistically, we often, if you’re looking at an image, you don’t care whether something is in one particular pixel versus the pixel immediately to the right of it. They’re pretty close together. You really just care about whether there’s a particular feature in some region of the image. And maybe you don’t care about exactly which pixel it happens to be in. And so there’s a technique we can use known as pooling. And what pooling is, is it means reducing the size of an input by sampling from regions inside of the input. So we’re going to take a big image and turn it into a smaller image by using pooling. And in particular, one of the most popular types of pooling is called max pooling. And what max pooling does is it pools just by choosing the maximum value in a particular region. So for example, let’s imagine I had this 4 by 4 image. But I wanted to reduce its dimensions. I wanted to make it a smaller image so that I have fewer inputs to work with. Well, what I could do is I could apply a 2 by 2 max pool, where the idea would be that I’m going to first look at this 2 by 2 region and say, what is the maximum value in that region? Well, it’s the number 50. So we’ll go ahead and just use the number 50. And then we’ll look at this 2 by 2 region. What is the maximum value here? It’s 110, so that’s going to be my value. Likewise here, the maximum value looks like 20. Go ahead and put that there. Then for this last region, the maximum value was 40. So we’ll go ahead and use that. And what I have now is a smaller representation of this same original image that I obtained just by picking the maximum value from each of these regions. So again, the advantages here are now I only have to deal with a 2 by 2 input instead of a 4 by 4. And you can imagine shrinking the size of an image even more. But in addition to that, I’m now able to make my analysis independent of whether a particular value was in this pixel or this pixel. I don’t care if the 50 was here or here. As long as it was generally in this region, I’ll still get access to that value. So it makes our algorithms a little bit more robust as well. So that then is pooling, taking the size of the image, reducing it a little bit by just sampling from particular regions inside of the image. And now we can put all of these ideas together, pooling, image convolution, and neural networks all together into another type of neural network called a convolutional neural network, or a CNN, which is a neural network that uses this convolution step usually in the context of analyzing an image, for example. And so the way that a convolutional neural network works is that we start with some sort of input image, some grid of pixels. But rather than immediately put that into the neural network layers that we’ve seen before, we’ll start by applying a convolution step, where the convolution step involves applying some number of different image filters to our original image in order to get what we call a feature map, the result of applying some filter to an image. And we could do this once, but in general, we’ll do this multiple times, getting a whole bunch of different feature maps, each of which might extract some different relevant feature out of the image, some different important characteristic of the image that we might care about using in order to calculate what the result should be. And in the same way that when we train neural networks, we can train neural networks to learn the weights between particular units inside of the neural networks, we can also train neural networks to learn what those filters should be, what the values of the filters should be in order to get the most useful, most relevant information out of the original image just by figuring out what setting of those filter values, the values inside of that kernel, results in minimizing the loss function, minimizing how poorly our hypothesis actually performs in figuring out the classification of a particular image, for example. So we first apply this convolution step, get a whole bunch of these various different feature maps. But these feature maps are quite large. There’s a lot of pixel values that happen to be here. And so a logical next step to take is a pooling step, where we reduce the size of these images by using max pooling, for example, extracting the maximum value from any particular region. There are other pooling methods that exist as well, depending on the situation. You could use something like average pooling, where instead of taking the maximum value from a region, you take the average value from a region, which has its uses as well. But in effect, what pooling will do is it will take these feature maps and reduce their dimensions so that we end up with smaller grids with fewer pixels. And this then is going to be easier for us to deal with. It’s going to mean fewer inputs that we have to worry about. And it’s also going to mean we’re more resilient, more robust against potential movements of particular values, just by one pixel, when ultimately we really don’t care about those one-pixel differences that might arise in the original image. And now, after we’ve done this pooling step, now we have a whole bunch of values that we can then flatten out and just put into a more traditional neural network. So we go ahead and flatten it, and then we end up with a traditional neural network that has one input for each of these values in each of these resulting feature maps after we do the convolution and after we do the pooling step. And so this then is the general structure of a convolutional network. We begin with the image, apply convolution, apply pooling, flatten the results, and then put that into a more traditional neural network that might itself have hidden layers. You can have deep convolutional networks that have hidden layers in between this flattened layer and the eventual output to be able to calculate various different features of those values. But this then can help us to be able to use convolution and pooling to use our knowledge about the structure of an image to be able to get better results, to be able to train our networks faster in order to better capture particular parts of the image. And there’s no reason necessarily why you can only use these steps once. In fact, in practice, you’ll often use convolution and pooling multiple times in multiple different steps. See, what you might imagine doing is starting with an image, first applying convolution to get a whole bunch of maps, then applying pooling, then applying convolution again, because these maps are still pretty big. You can apply convolution to try and extract relevant features out of this result. Then take those results, apply pooling in order to reduce their dimensions, and then take that and feed it into a neural network that maybe has fewer inputs. So here I have two different convolution and pooling steps. I do convolution and pooling once, and then I do convolution and pooling a second time, each time extracting useful features from the layer before it, each time using pooling to reduce the dimensions of what you’re ultimately looking at. And the goal now of this sort of model is that in each of these steps, you can begin to learn different types of features of the original image. That maybe in the first step, you learn very low level features. Just learn and look for features like edges and curves and shapes, because based on pixels and their neighboring values, you can figure out, all right, what are the edges? What are the curves? What are the various different shapes that might be present there? But then once you have a mapping that just represents where the edges and curves and shapes happen to be, you can imagine applying the same sort of process again to begin to look for higher level features, look for objects, maybe look for people’s eyes and facial recognition, for example. Maybe look for more complex shapes like the curves on a particular number if you’re trying to recognize a digit in a handwriting recognition sort of scenario. And then after all of that, now that you have these results that represent these higher level features, you can pass them into a neural network, which is really just a deep neural network that looks like this, where you might imagine making a binary classification or classifying into multiple categories or performing various different tasks on this sort of model. So convolutional neural networks can be quite powerful and quite popular when it comes towards trying to analyze images. We don’t strictly need them. We could have just used a vanilla neural network that just operates with layer after layer, as we’ve seen before. But these convolutional neural networks can be quite helpful, in particular, because of the way they model the way a human might look at an image, that instead of a human looking at every single pixel simultaneously and trying to convolve all of them by multiplying them together, you might imagine that what convolution is really doing is looking at various different regions of the image and extracting relevant information and features out of those parts of the image, the same way that a human might have visual receptors that are looking at particular parts of what they see and using those combining them to figure out what meaning they can draw from all of those various different inputs. And so you might imagine applying this to a situation like handwriting recognition. So we’ll go ahead and see an example of that now, where I’ll go ahead and open up handwriting.py. Again, what we do here is we first import TensorFlow. And then TensorFlow, it turns out, has a few data sets that are built into the library that you can just immediately access. And one of the most famous data sets in machine learning is the MNIST data set, which is just a data set of a whole bunch of samples of people’s handwritten digits. I showed you a slide of that a little while ago. And what we can do is just immediately access that data set which is built into the library so that if I want to do something like train on a whole bunch of handwritten digits, I can just use the data set that is provided to me. Of course, if I had my own data set of handwritten images, I can apply the same idea. I’d first just need to take those images and turn them into an array of pixels, because that’s the way that these are going to be formatted. They’re going to be formatted as, effectively, an array of individual pixels. Now there’s a bit of reshaping I need to do, just turning the data into a format that I can put into my convolutional neural network. So this is doing things like taking all the values and dividing them by 255. If you remember, these color values tend to range from 0 to 255. So I can divide them by 255 just to put them into 0 to 1 range, which might be a little bit easier to train on. And then doing various other modifications to the data just to get it into a nice usable format. But here’s the interesting and important part. Here is where I create the convolutional neural network, the CNN, where here I’m saying, go ahead and use a sequential model. And before I could use model.add to say add a layer, add a layer, add a layer, another way I could define it is just by passing as input to this sequential neural network a list of all of the layers that I want. And so here, the very first layer in my model is a convolution layer, where I’m first going to apply convolution to my image. I’m going to use 13 different filters. So my model is going to learn 32, rather, 32 different filters that I would like to learn on the input image, where each filter is going to be a 3 by 3 kernel. So we saw those 3 by 3 kernels before, where we could multiply each value in a 3 by 3 grid by a value, multiply it, and add all the results together. So here, I’m going to learn 32 different of these 3 by 3 filters. I can, again, specify my activation function. And I specify what my input shape is. My input shape in the banknotes case was just 4. I had 4 inputs. My input shape here is going to be 28, 28, 1, because for each of these handwritten digits, it turns out that the MNIST data set organizes their data. Each image is a 28 by 28 pixel grid. So we’re going to have a 28 by 28 pixel grid. And each one of those images only has one channel value. These handwritten digits are just black and white. So there’s just a single color value representing how much black or how much white. You might imagine that in a color image, if you were doing this sort of thing, you might have three different channels, a red, a green, and a blue channel, for example. But in the case of just handwriting recognition, recognizing a digit, we’re just going to use a single value for, like, shaded in or not shaded in. And it might range, but it’s just a single color value. And that, then, is the very first layer of our neural network, a convolutional layer that will take the input and learn a whole bunch of different filters that we can apply to the input to extract meaningful features. Next step is going to be a max pooling layer, also built right into TensorFlow, where this is going to be a layer that is going to use a pool size of 2 by 2, meaning we’re going to look at 2 by 2 regions inside of the image and just extract the maximum value. Again, we’ve seen why this can be helpful. It’ll help to reduce the size of our input. And once we’ve done that, we’ll go ahead and flatten all of the units just into a single layer that we can then pass into the rest of the neural network. And now, here’s the rest of the neural network. Here, I’m saying, let’s add a hidden layer to my neural network with 128 units, so a whole bunch of hidden units inside of the hidden layer. And just to prevent overfitting, I can add a dropout to that. Say, you know what, when you’re training, randomly dropout half of the nodes from this hidden layer just to make sure we don’t become over-reliant on any particular node, we begin to really generalize and stop ourselves from overfitting. So TensorFlow allows us, just by adding a single line, to add dropout into our model as well, such that when it’s training, it will perform this dropout step in order to help make sure that we don’t overfit on this particular data. And then finally, I add an output layer. The output layer is going to have 10 units, one for each category that I would like to classify digits into, so 0 through 9, 10 different categories. And the activation function I’m going to use here is called the softmax activation function. And in short, what the softmax activation function is going to do is it’s going to take the output and turn it into a probability distribution. So ultimately, it’s going to tell me, what did we estimate the probability is that this is a 2 versus a 3 versus a 4. And so it will turn it into that probability distribution for me. Next up, I’ll go ahead and compile my model and fit it on all of my training data. And then I can evaluate how well the neural network performs. And then I’ve added to my Python program, if I’ve provided a command line argument like the name of a file, I’m going to go ahead and save the model to a file. And so this can be quite useful too. Once you’ve done the training step, which could take some time in terms of taking all the time, going through the data, running back propagation with gradient descent to be able to say, all right, how should we adjust the weight to this particular model? You end up calculating values for these weights, calculating values for these filters. You’d like to remember that information so you can use it later. And so TensorFlow allows us to just save a model to a file, such that later, if we want to use the model we’ve learned, use the weights that we’ve learned to make some sort of new prediction, we can just use the model that already exists. So what we’re doing here is after we’ve done all the calculation, we go ahead and save the model to a file, such that we can use it a little bit later. So for example, if I go into digits, I’m going to run handwriting.py. I won’t save it this time. We’ll just run it and go ahead and see what happens. What will happen is we need to go through the model in order to train on all of these samples of handwritten digits. The MNIST data set gives us thousands and thousands of sample handwritten digits in the same format that we can use in order to train. And so now what you’re seeing is this training process. And unlike the banknotes case, where there was much fewer data points, the data was very, very simple, here this data is more complex and this training process takes time. And so this is another one of those cases where when training neural networks, this is why computational power is so important that oftentimes you see people wanting to use sophisticated GPUs in order to more efficiently be able to do this sort of neural network training. It also speaks to the reason why more data can be helpful. The more sample data points you have, the better you can begin to do this training. So here we’re going through 60,000 different samples of handwritten digits. And I said we’re going to go through them 10 times. We’re going to go through the data set 10 times, training each time, hopefully improving upon our weights with every time we run through this data set. And we can see over here on the right what the accuracy is each time we go ahead and run this model, that the first time it looks like we got an accuracy of about 92% of the digits correct based on this training set. We increased that to 96% or 97%. And every time we run this, we’re going to see hopefully the accuracy improve as we continue to try and use that gradient descent, that process of trying to run the algorithm, to minimize the loss that we get in order to more accurately predict what the output should be. And what this process is doing is it’s learning not only the weights, but it’s learning the features to use, the kernel matrix to use when performing that convolution step. Because this is a convolutional neural network, where I’m first performing those convolutions and then doing the more traditional neural network structure, this is going to learn all of those individual steps as well. And so here we see the TensorFlow provides me with some very nice output, telling me about how many seconds are left with each of these training runs that allows me to see just how well we’re doing. So we’ll go ahead and see how this network performs. It looks like we’ve gone through the data set seven times. We’re going through it an eighth time now. And at this point, the accuracy is pretty high. We saw we went from 92% up to 97%. Now it looks like 98%. And at this point, it seems like things are starting to level out. It’s probably a limit to how accurate we can ultimately be without running the risk of overfitting. Of course, with enough nodes, you would just memorize the input and overfit upon them. But we’d like to avoid doing that. And Dropout will help us with this. But now we see we’re almost done finishing our training step. We’re at 55,000. All right, we finished training. And now it’s going to go ahead and test for us on 10,000 samples. And it looks like on the testing set, we were at 98.8% accurate. So we ended up doing pretty well, it seems, on this testing set to see how accurately can we predict these handwritten digits. And so what we could do then is actually test it out. I’ve written a program called Recognition.py using PyGame. If you pass it a model that’s been trained, and I pre-trained an example model using this input data, what we can do is see whether or not we’ve been able to train this convolutional neural network to be able to predict handwriting, for example. So I can try, just like drawing a handwritten digit. I’ll go ahead and draw the number 2, for example. So there’s my number 2. Again, this is messy. If you tried to imagine, how would you write a program with just ifs and thens to be able to do this sort of calculation, it would be tricky to do so. But here I’ll press Classify, and all right, it seems I was able to correctly classify that what I drew was the number 2. I’ll go ahead and reset it, try it again. We’ll draw an 8, for example. So here is an 8. Press Classify. And all right, it predicts that the digit that I drew was an 8. And the key here is this really begins to show the power of what the neural network is doing, somehow looking at various different features of these different pixels, figuring out what the relevant features are, and figuring out how to combine them to get a classification. And this would be a difficult task to provide explicit instructions to the computer on how to do, to use a whole bunch of ifs ands to process all these pixel values to figure out what the handwritten digit is. Everyone’s going to draw their 8s a little bit differently. If I drew the 8 again, it would look a little bit different. And yet, ideally, we want to train a network to be robust enough so that it begins to learn these patterns on its own. All I said was, here is the structure of the network, and here is the data on which to train the network. And the network learning algorithm just tries to figure out what is the optimal set of weights, what is the optimal set of filters to use them in order to be able to accurately classify a digit into one category or another. Just going to show the power of these sorts of convolutional neural networks. And so that then was a look at how we can use convolutional neural networks to begin to solve problems with regards to computer vision, the ability to take an image and begin to analyze it. So this is the type of analysis you might imagine that’s happening in self-driving cars that are able to figure out what filters to apply to an image to understand what it is that the computer is looking at, or the same type of idea that might be applied to facial recognition and social media to be able to determine how to recognize faces in an image as well. You can imagine a neural network that instead of classifying into one of 10 different digits could instead classify like, is this person A or is this person B, trying to tell those people apart just based on convolution. And so now what we’ll take a look at is yet another type of neural network that can be quite popular for certain types of tasks. But to do so, we’ll try to generalize and think about our neural network a little bit more abstractly. That here we have a sample deep neural network where we have this input layer, a whole bunch of different hidden layers that are performing certain types of calculations, and then an output layer here that just generates some sort of output that we care about calculating. But we could imagine representing this a little more simply like this. Here is just a more abstract representation of our neural network. We have some input that might be like a vector of a whole bunch of different values as our input. That gets passed into a network that performs some sort of calculation or computation, and that network produces some sort of output. That output might be a single value. It might be a whole bunch of different values. But this is the general structure of the neural network that we’ve seen. There is some sort of input that gets fed into the network. And using that input, the network calculates what the output should be. And this sort of model for a neural network is what we might call a feed-forward neural network. Feed-forward neural networks have connections only in one direction. They move from one layer to the next layer to the layer after that, such that the inputs pass through various different hidden layers and then ultimately produce some sort of output. So feed-forward neural networks were very helpful for solving these types of classification problems that we saw before. We have a whole bunch of input. We want to learn what setting of weights will allow us to calculate the output effectively. But there are some limitations on feed-forward neural networks that we’ll see in a moment. In particular, the input needs to be of a fixed shape, like a fixed number of neurons are in the input layer. And there’s a fixed shape for the output, like a fixed number of neurons in the output layer. And that has some limitations of its own. And a possible solution to this, and we’ll see examples of the types of problems we can solve for this in just a second, is instead of just a feed-forward neural network, where there are only connections in one direction from left to right effectively across the network, we could also imagine a recurrent neural network, where a recurrent neural network generates output that gets fed back into itself as input for future runs of that network. So whereas in a traditional neural network, we have inputs that get fed into the network, that get fed into the output. And the only thing that determines the output is based on the original input and based on the calculation we do inside of the network itself. This goes in contrast with a recurrent neural network, where in a recurrent neural network, you can imagine output from the network feeding back to itself into the network again as input for the next time you do the calculations inside of the network. What this allows is it allows the network to maintain some sort of state, to store some sort of information that can be used on future runs of the network. Previously, the network just defined some weights, and we passed inputs through the network, and it generated outputs. But the network wasn’t saving any information based on those inputs to be able to remember for future iterations or for future runs. What a recurrent neural network will let us do is let the network store information that gets passed back in as input to the network again the next time we try and perform some sort of action. And this is particularly helpful when dealing with sequences of data. So we’ll see a real world example of this right now, actually. Microsoft has developed an AI known as the caption bot. And what the caption bot does is it says, I can understand the content of any photograph, and I’ll try to describe it as well as any human. I’ll analyze your photo, but I won’t store it or share it. And so what Microsoft’s caption bot seems to be claiming to do is it can take an image and figure out what’s in the image and just give us a caption to describe it. So let’s try it out. Here, for example, is an image of Harvard Square. It’s some people walking in front of one of the buildings at Harvard Square. I’ll go ahead and take the URL for that image, and I’ll paste it into caption bot and just press Go. So caption bot is analyzing the image, and then it says, I think it’s a group of people walking in front of a building, which seems amazing. The AI is able to look at this image and figure out what’s in the image. And the important thing to recognize here is that this is no longer just a classification task. We saw being able to classify images with a convolutional neural network where the job was take the image and then figure out, is it a 0 or a 1 or a 2, or is it this person’s face or that person’s face? What seems to be happening here is the input is an image, and we know how to get networks to take input of images, but the output is text. It’s a sentence. It’s a phrase, like a group of people walking in front of a building. And this would seem to pose a challenge for our more traditional feed-forward neural networks, for the reason being that in traditional neural networks, we just have a fixed-size input and a fixed-size output. There are a certain number of neurons in the input to our neural network and a certain number of outputs for our neural network, and then some calculation that goes on in between. But the size of the inputs and the number of values in the input and the number of values in the output, those are always going to be fixed based on the structure of the neural network. And that makes it difficult to imagine how a neural network could take an image like this and say it’s a group of people walking in front of the building because the output is text, like it’s a sequence of words. Now, it might be possible for a neural network to output one word, one word you could represent as a vector of values, and you can imagine ways of doing that. Next time, we’ll talk a little bit more about AI as it relates to language and language processing. But a sequence of words is much more challenging because depending on the image, you might imagine the output is a different number of words. We could have sequences of different lengths, and somehow we still want to be able to generate the appropriate output. And so the strategy here is to use a recurrent neural network, a neural network that can feed its own output back into itself as input for the next time. And this allows us to do what we call a one-to-many relationship for inputs to outputs, that in vanilla, more traditional neural networks, these are what we might consider to be one-to-one neural networks. You pass in one set of values as input. You get one vector of values as the output. But in this case, we want to pass in one value as input, the image, and we want to get a sequence, many values as output, where each value is like one of these words that gets produced by this particular algorithm. And so the way we might do this is we might imagine starting by providing input, the image, into our neural network. And the neural network is going to generate output, but the output is not going to be the whole sequence of words, because we can’t represent the whole sequence of words using just a fixed set of neurons. Instead, the output is just going to be the first word. We’re going to train the network to output what the first word of the caption should be. And you could imagine that Microsoft has trained this by running a whole bunch of training samples through the AI, giving it a whole bunch of pictures and what the appropriate caption was, and having the AI begin to learn from that. But now, because the network generates output that can be fed back into itself, you could imagine the output of the network being fed back into the same network. This here looks like a separate network, but it’s really the same network that’s just getting different input, that this network’s output gets fed back into itself, but it’s going to generate another output. And that other output is going to be the second word in the caption. And this recurrent neural network then, this network is going to generate other output that can be fed back into itself to generate yet another word, fed back into itself to generate another word. And so recurrent neural networks allow us to represent this one-to-many structure. You provide one image as input, and the neural network can pass data into the next run of the network, and then again and again, such that you could run the network multiple times, each time generating a different output still based on that original input. And this is where recurrent neural networks become particularly useful when dealing with sequences of inputs or outputs. And my output is a sequence of words, and since I can’t very easily represent outputting an entire sequence of words, I’ll instead output that sequence one word at a time by allowing my network to pass information about what still needs to be said about the photo into the next stage of running the network. So you could run the network multiple times, the same network with the same weights, just getting different input each time. First, getting input from the image, and then getting input from the network itself as additional information about what additionally needs to be given in a particular caption, for example. So this then is a one-to-many relationship inside of a recurrent neural network, but it turns out there are other models that we can use, other ways we can try and use recurrent neural networks to be able to represent data that might be stored in other forms as well. We saw how we could use neural networks in order to analyze images in the context of convolutional neural networks that take an image, figure out various different properties of the image, and are able to draw some sort of conclusion based on that. But you might imagine that something like YouTube, they need to be able to do a lot of learning based on video. They need to look through videos to detect if they’re like copyright violations, or they need to be able to look through videos to maybe identify what particular items are inside of the video, for example. And video, you might imagine, is much more difficult to put in as input to a neural network, because whereas an image, you could just treat each pixel as a different value, videos are sequences. They’re sequences of images, and each sequence might be of different length. And so it might be challenging to represent that entire video as a single vector of values that you could pass in to a neural network. And so here, too, recurrent neural networks can be a valuable solution for trying to solve this type of problem. Then instead of just passing in a single input into our neural network, we could pass in the input one frame at a time, you might imagine. First, taking the first frame of the video, passing it into the network, and then maybe not having the network output anything at all yet. Let it take in another input, and this time, pass it into the network. But the network gets information from the last time we provided an input into the network. Then we pass in a third input, and then a fourth input, where each time, what the network gets is it gets the most recent input, like each frame of the video. But it also gets information the network processed from all of the previous iterations. So on frame number four, you end up getting the input for frame number four plus information the network has calculated from the first three frames. And using all of that data combined, this recurrent neural network can begin to learn how to extract patterns from a sequence of data as well. And so you might imagine, if you want to classify a video into a number of different genres, like an educational video, or a music video, or different types of videos, that’s a classification task, where you want to take as input each of the frames of the video, and you want to output something like what it is, what category that it happens to belong to. And you can imagine doing this sort of thing, this sort of many-to-one learning, any time your input is a sequence. And so input is a sequence in the context of video. It could be in the context of, like, if someone has typed a message and you want to be able to categorize that message, like if you’re trying to take a movie review and trying to classify it as, is it a positive review or a negative review? That input is a sequence of words, and the output is a classification, positive or negative. There, too, a recurrent neural network might be helpful for analyzing sequences of words. And they’re quite popular when it comes to dealing with language. Could even be used for spoken language as well, that spoken language is an audio waveform that can be segmented into distinct chunks. And each of those could be passed in as an input into a recurrent neural network to be able to classify someone’s voice, for instance. If you want to do voice recognition to say, is this one person or is this another, here are also cases where you might want this many-to-one architecture for a recurrent neural network. And then as one final problem, just to take a look at in terms of what we can do with these sorts of networks, imagine what Google Translate is doing. So what Google Translate is doing is it’s taking some text written in one language and converting it into text written in some other language, for example, where now this input is a sequence of data. It’s a sequence of words. And the output is a sequence of words as well. It’s also a sequence. So here we want effectively a many-to-many relationship. Our input is a sequence and our output is a sequence as well. And it’s not quite going to work to just say, take each word in the input and translate it into a word in the output. Because ultimately, different languages put their words in different orders. And maybe one language uses two words for something, whereas another language only uses one. So we really want some way to take this information, this input, encode it somehow, and use that encoding to generate what the output ultimately should be. And this has been one of the big advancements in automated translation technology, is the ability to use the neural networks to do this instead of older, more traditional methods. And this has improved accuracy dramatically. And the way you might imagine doing this is, again, using a recurrent neural network with multiple inputs and multiple outputs. We start by passing in all the input. Input goes into the network. Another input, like another word, goes into the network. And we do this multiple times, like once for each word in the input that I’m trying to translate. And only after all of that is done does the network now start to generate output, like the first word of the translated sentence, and the next word of the translated sentence, so on and so forth, where each time the network passes information to itself by allowing for this model of giving some sort of state from one run in the network to the next run, assembling information about all the inputs, and then passing in information about which part of the output in order to generate next. And there are a number of different types of these sorts of recurrent neural networks. One of the most popular is known as the long short-term memory neural network, otherwise known as LSTM. But in general, these types of networks can be very, very powerful whenever we’re dealing with sequences, whether those are sequences of images or especially sequences of words when it comes towards dealing with natural language. And so that then were just some of the different types of neural networks that can be used to do all sorts of different computations. And these are incredibly versatile tools that can be applied to a number of different domains. We only looked at a couple of the most popular types of neural networks from more traditional feed-forward neural networks, convolutional neural networks, and recurrent neural networks. But there are other types as well. There are adversarial networks where networks compete with each other to try and be able to generate new types of data, as well as other networks that can solve other tasks based on what they happen to be structured and adapted for. And these are very powerful tools in machine learning from being able to very easily learn based on some set of input data and to be able to, therefore, figure out how to calculate some function from inputs to outputs, whether it’s input to some sort of classification like analyzing an image and getting a digit or machine translation where the input is in one language and the output is in another. These tools have a lot of applications for machine learning more generally. Next time, we’ll look at machine learning and AI in particular in the context of natural language. We talked a little bit about this today, but looking at how it is that our AI can begin to understand natural language and can begin to be able to analyze and do useful tasks with regards to human language, which turns out to be a challenging and interesting task. So we’ll see you next time. And welcome back, everybody, to our final class in an introduction to artificial intelligence with Python. Now, so far in this class, we’ve been taking problems that we want to solve intelligently and framing them in ways that computers are going to be able to make sense of. We’ve been taking problems and framing them as search problems or constraint satisfaction problems or optimization problems, for example. In essence, we have been trying to communicate about problems in ways that our computer is going to be able to understand. Today, the goal is going to be to get computers to understand the way you and I communicate naturally via our own natural languages, languages like English. But natural language contains a lot of nuance and complexity that’s going to make it challenging for computers to be able to understand. So we’ll need to explore some new tools and some new techniques to allow computers to make sense of natural language. So what is it exactly that we’re trying to get computers to do? Well, they all fall under this general heading of natural language processing, getting computers to work with natural language. And these tasks include tasks like automatic summarization. Given a long text, can we train the computer to be able to come up with a shorter representation of it? Information extraction, getting the computer to pull out relevant facts or details out of some text. Machine translation, like Google Translate, translating some text from one language into another language. Question answering, if you’ve ever asked a question to your phone or had a conversation with an AI chatbot where you provide some text to the computer, the computer is able to understand that text and then generate some text in response. Text classification, where we provide some text to the computer and the computer assigns it a label, positive or negative, inbox or spam, for example. And there are several other kinds of tasks that all fall under this heading of natural language processing. But before we take a look at how the computer might try to solve these kinds of tasks, it might be useful for us to think about language in general. What are the kinds of challenges that we might need to deal with as we start to think about language and getting a computer to be able to understand it? So one part of language that we’ll need to consider is the syntax of language. Syntax is all about the structure of language. Language is composed of individual words. And those words are composed together in some kind of structured whole. And if our computer is going to be able to understand language, it’s going to need to understand something about that structure. So let’s take a couple of examples. Here, for instance, is a sentence. Just before 9 o’clock, Sherlock Holmes stepped briskly into the room. That sentence is made up of words. And those words together form a structured whole. This is syntactically valid as a sentence. But we could take some of those same words, rearrange them, and come up with a sentence that is not syntactically valid. Here, for example, just before Sherlock Holmes 9 o’clock stepped briskly the room is still composed of valid words. But they’re not in any kind of logical whole. This is not a syntactically well-formed sentence. Another interesting challenge is that some sentences will have multiple possible valid structures. Here’s a sentence, for example. I saw the man on the mountain with a telescope. And here, this is a valid sentence. But it actually has two different possible structures that lend themselves to two different interpretations and two different meanings. Maybe I, the one doing the seeing, am the one with the telescope. Or maybe the man on the mountain is the one with the telescope. And so natural language is ambiguous. Sometimes the same sentence can be interpreted in multiple ways. And that’s something that we’ll need to think about as well. And this lends itself to another problem within language that we’ll need to think about, which is semantics. While syntax is all about the structure of language, semantics is about the meaning of language. It’s not enough for a computer just to know that a sentence is well-structured if it doesn’t know what that sentence means. And so semantics is going to concern itself with the meaning of words and the meaning of sentences. So if we go back to that same sentence as before, just before 9 o’clock, Sherlock Holmes stepped briskly into the room, I could come up with another sentence, say the sentence, a few minutes before 9, Sherlock Holmes walked quickly into the room. And those are two different sentences with some of the words the same and some of the words different. But the two sentences have essentially the same meaning. And so ideally, whatever model we build, we’ll be able to understand that these two sentences, while different, mean something very similar. Some syntactically well-formed sentences don’t mean anything at all. A famous example from linguist Noam Chomsky is the sentence, colorless green ideas sleep furiously. This is a syntactically, structurally well-formed sentence. We’ve got adjectives modifying a noun, ideas. We’ve got a verb and an adverb in the correct positions. But when taken as a whole, the sentence doesn’t really mean anything. And so if our computers are going to be able to work with natural language and perform tasks in natural language processing, these are some concerns we’ll need to think about. We’ll need to be thinking about syntax. And we’ll need to be thinking about semantics. So how could we go about trying to teach a computer how to understand the structure of natural language? Well, one approach we might take is by starting by thinking about the rules of natural language. Our natural languages have rules. In English, for example, nouns tend to come before verbs. Nouns can be modified by adjectives, for example. And so if only we could formalize those rules, then we could give those rules to a computer, and the computer would be able to make sense of them and understand them. And so let’s try to do exactly that. We’re going to try to define a formal grammar. Where a formal grammar is some system of rules for generating sentences in a language. This is going to be a rule-based approach to natural language processing. We’re going to give the computer some rules that we know about language and have the computer use those rules to make sense of the structure of language. And there are a number of different types of formal grammars. Each one of them has slightly different use cases. But today, we’re going to focus specifically on one kind of grammar known as a context-free grammar. So how does the context-free grammar work? Well, here is a sentence that we might want a computer to generate. She saw the city. And we’re going to call each of these words a terminal symbol. A terminal symbol, because once our computer has generated the word, there’s nothing else for it to generate. Once it’s generated the sentence, the computer is done. We’re going to associate each of these terminal symbols with a non-terminal symbol that generates it. So here we’ve got n, which stands for noun, like she or city. We’ve got v as a non-terminal symbol, which stands for a verb. And then we have d, which stands for determiner. A determiner is a word like the or a or an in English, for example. So each of these non-terminal symbols can generate the terminal symbols that we ultimately care about generating. But how do we know, or how does the computer know which non-terminal symbols are associated with which terminal symbols? Well, to do that, we need some kind of rule. Here are some what we call rewriting rules that have a non-terminal symbol on the left-hand side of an arrow. And on the right side is what that non-terminal symbol can be replaced with. So here we’re saying the non-terminal symbol n, again, which stands for noun, could be replaced by any of these options separated by vertical bars. n could be replaced by she or city or car or hairy. d for determiner could be replaced by the a or an and so forth. Each of these non-terminal symbols could be replaced by any of these words. We can also have non-terminal symbols that are replaced by other non-terminal symbols. Here is an interesting rule, np arrow n bar dn. So what does that mean? Well, np stands for a noun phrase. Sometimes when we have a noun phrase in a sentence, it’s not just a single word, it could be multiple words. And so here we’re saying a noun phrase could be just a noun, or it could be a determiner followed by a noun. So we might have a noun phrase that’s just a noun, like she, that’s a noun phrase. Or we could have a noun phrase that’s multiple words, something like the city also acts as a noun phrase. But in this case, it’s composed of two words, a determiner, the, and a noun city. We could do the same for verb phrases. A verb phrase, or VP, might be just a verb, or it might be a verb followed by a noun phrase. So we could have a verb phrase that’s just a single word, like the word walked, or we could have a verb phrase that is an entire phrase, something like saw the city, as an entire verb phrase. A sentence, meanwhile, we might then define as a noun phrase followed by a verb phrase. And so this would allow us to generate a sentence like she saw the city, an entire sentence made up of a noun phrase, which is just the word she, and then a verb phrase, which is saw the city, saw which is a verb, and then the city, which itself is also a noun phrase. And so if we could give these rules to a computer explaining to it what non-terminal symbols could be replaced by what other symbols, then a computer could take a sentence and begin to understand the structure of that sentence. And so let’s take a look at an example of how we might do that. And to do that, we’re going to use a Python library called NLTK, or the Natural Language Toolkit, which we’ll see a couple of times today. It contains a lot of helpful features and functions that we can use for trying to deal with and process natural language. So here we’ll take a look at how we can use NLTK in order to parse a context-free grammar. So let’s go ahead and open up cfg0.py, cfg standing for context-free grammar. And what you’ll see in this file is that I first import NLTK, the Natural Language Toolkit. And the first thing I do is define a context-free grammar, saying that a sentence is a noun phrase followed by a verb phrase. I’m defining what a noun phrase is, defining what a verb phrase is, and then giving some examples of what I can do with these non-terminal symbols, D for determiner, N for noun, and V for verb. We’re going to use NLTK to parse that grammar. Then we’ll ask the user for some input in the form of a sentence and split it into words. And then we’ll use this context-free grammar parser to try to parse that sentence and print out the resulting syntax tree. So let’s take a look at an example. We’ll go ahead and go into my cfg directory, and we’ll run cfg0.py. And here I’m asked to type in a sentence. Let’s say I type in she walked. And when I do that, I see that she walked is a valid sentence, where she is a noun phrase, and walked is the corresponding verb phrase. I could try to do this with a more complex sentence too. I could do something like she saw the city. And here we see that she is the noun phrase, and then saw the city is the entire verb phrase that makes up this sentence. So that was a very simple grammar. Let’s take a look at a slightly more complex grammar. Here is cfg1.py, where a sentence is still a noun phrase followed by a verb phrase, but I’ve added some other possible non-terminal symbols too. I have AP for adjective phrase and PP for prepositional phrase. And we specified that we could have an adjective phrase before a noun phrase or a prepositional phrase after a noun, for example. So lots of additional ways that we might try to structure a sentence and interpret and parse one of those resulting sentences. So let’s see that one in action. We’ll go ahead and run cfg1.py with this new grammar. And we’ll try a sentence like she saw the wide street. Here, Python’s NLTK is able to parse that sentence and identify that she saw the wide street has this particular structure, a sentence with a noun phrase and a verb phrase, where that verb phrase has a noun phrase that within it contains an adjective. And so it’s able to get some sense for what the structure of this language actually is. Let’s try another example. Let’s say she saw the dog with the binoculars. And we’ll try that sentence. And here, we get one possible syntax tree, she saw the dog with the binoculars. But notice that this sentence is actually a little bit ambiguous in our own natural language. Who has the binoculars? Is it she who has the binoculars or the dog who has the binoculars? And NLTK is able to identify both possible structures for the sentence. In this case, the dog with the binoculars is an entire noun phrase. It’s all underneath this NP here. So it’s the dog that has the binoculars. But we also got an alternative parse tree, where the dog is just the noun phrase. And with the binoculars is a prepositional phrase modifying saw. So she saw the dog and she used the binoculars in order to see the dog as well. So this allows us to get a sense for the structure of natural language. But it relies on us writing all of these rules. And it would take a lot of effort to write all of the rules for any possible sentence that someone might write or say in the English language. Language is complicated. And as a result, there are going to be some very complex rules. So what else might we try? We might try to take a statistical lens towards approaching this problem of natural language processing. If we were able to give the computer a lot of existing data of sentences written in the English language, what could we try to learn from that data? Well, it might be difficult to try and interpret long pieces of text all at once. So instead, what we might want to do is break up that longer text into smaller pieces of information instead. In particular, we might try to create n-grams out of a longer sequence of text. An n-gram is just some contiguous sequence of n items from a sample of text. It might be n characters in a row or n words in a row, for example. So let’s take a passage from Sherlock Holmes. And let’s look for all of the trigrams. A trigram is an n-gram where n is equal to 3. So in this case, we’re looking for sequences of three words in a row. So the trigrams here would be phrases like how often have. That’s three words in a row. Often have I is another trigram. Have I said, I said to, said to you, to you that. These are all trigrams, sequences of three words that appear in sequence. And if we could give the computer a large corpus of text and have it pull out all of the trigrams in this case, it could get a sense for what sequences of three words tend to appear next to each other in our own natural language and, as a result, get some sense for what the structure of the language actually is. So let’s take a look at an example of that. How can we use NLTK to try to get access to information about n-grams? So here, we’re going to open up ngrams.py. And this is a Python program that’s going to load a corpus of data, just some text files, into our computer’s memory. And then we’re going to use NLTK’s ngrams function, which is going to go through the corpus of text, pulling out all of the ngrams for a particular value of n. And then, by using Python’s counter class, we’re going to figure out what are the most common ngrams inside of this entire corpus of text. And we’re going to need a data set in order to do this. And I’ve prepared a data set of some of the stories of Sherlock Holmes. So it’s just a bunch of text files. A lot of words for it to analyze. And as a result, we’ll get a sense for what sequences of two words or three words that tend to be most common in natural language. So let’s give this a try. We’ll go into my ngrams directory. And we’ll run ngrams.py. We’ll try an n value of 2. So we’re looking for sequences of two words in a row. And we’ll use our corpus of stories from Sherlock Holmes. And when we run this program, we get a list of the most common ngrams where n is equal to 2, otherwise known as a bigram. So the most common one is of the. That’s a sequence of two words that appears quite frequently in natural language. Then in the. And it was. These are all common sequences of two words that appear in a row. Let’s instead now try running ngrams with n equal to 3. Let’s get all of the trigrams and see what we get. And now we see the most common trigrams are it was a. One of the. I think that. These are all sequences of three words that appear quite frequently. And we were able to do this essentially via a process known as tokenization. Tokenization is the process of splitting a sequence of characters into pieces. In this case, we’re splitting a long sequence of text into individual words and then looking at sequences of those words to get a sense for the structure of natural language. So once we’ve done this, once we’ve done the tokenization, once we’ve built up our corpus of ngrams, what can we do with that information? So the one thing that we might try is we could build a Markov chain, which you might recall from when we talked about probability. Recall that a Markov chain is some sequence of values where we can predict one value based on the values that came before it. And as a result, if we know all of the common ngrams in the English language, what words tend to be associated with what other words in sequence, we can use that to predict what word might come next in a sequence of words. And so we could build a Markov chain for language in order to try to generate natural language that follows the same statistical patterns as some input data. So let’s take a look at that and build a Markov chain for natural language. And as input, I’m going to use the works of William Shakespeare. So here I have a file Shakespeare.txt, which is just a bunch of the works of William Shakespeare. It’s a long text file, so plenty of data to analyze. And here in generator.py, I’m using a third party Python library in order to do this analysis. We’re going to read in the sample of text, and then we’re going to train a Markov model based on that text. And then we’re going to have the Markov chain generate some sentences. We’re going to generate a sentence that doesn’t appear in the original text, but that follows the same statistical patterns that’s generating it based on the ngrams trying to predict what word is likely to come next that we would expect based on those statistical patterns. So we’ll go ahead and go into our Markov directory, run this generator with the works of William Shakespeare’s input. And what we’re going to get are five new sentences, where these sentences are not necessarily sentences from the original input text itself, but just that follow the same statistical patterns. It’s predicting what word is likely to come next based on the input data that we’ve seen and the types of words that tend to appear in sequence there too. And so we’re able to generate these sentences. Of course, so far, there’s no guarantee that any of the sentences that are generated actually mean anything or make any sense. They just happen to follow the statistical patterns that our computer is already aware of. So we’ll return to this issue of how to generate text in perhaps a more accurate or more meaningful way a little bit later. So let’s now turn our attention to a slightly different problem, and that’s the problem of text classification. Text classification is the problem where we have some text and we want to put that text into some kind of category. We want to apply some sort of label to that text. And this kind of problem shows up in a wide variety of places. A commonplace might be your email inbox, for example. You get an email and you want your computer to be able to identify whether the email belongs in your inbox or whether it should be filtered out into spam. So we need to classify the text. Is it a good email or is it spam? Another common use case is sentiment analysis. We might want to know whether the sentiment of some text is positive or negative. And so how might we do that? This comes up in situations like product reviews, where we might have a bunch of reviews for a product on some website. My grandson loved it so much fun. Product broke after a few days. One of the best games I’ve played in a long time and kind of cheap and flimsy, not worth it. Here’s some example sentences that you might see on a product review website. And you and I could pretty easily look at this list of product reviews and decide which ones are positive and which ones are negative. We might say the first one and the third one, those seem like positive sentiment messages. But the second one and the fourth one seem like negative sentiment messages. But how did we know that? And how could we train a computer to be able to figure that out as well? Well, you might have clued your eye in on particular key words, where those particular words tend to mean something positive or negative. So you might have identified words like loved and fun and best tend to be associated with positive messages. And words like broke and cheap and flimsy tend to be associated with negative messages. So if only we could train a computer to be able to learn what words tend to be associated with positive versus negative messages, then maybe we could train a computer to do this kind of sentiment analysis as well. So we’re going to try to do just that. We’re going to use a model known as the bag of words model, which is a model that represents text as just an unordered collection of words. For the purpose of this model, we’re not going to worry about the sequence and the ordering of the words, which word came first, second, or third. We’re just going to treat the text as a collection of words in no particular order. And we’re losing information there, right? The order of words is important. And we’ll come back to that a little bit later. But for now, to simplify our model, it’ll help us tremendously just to think about text as some unordered collection of words. And in particular, we’re going to use the bag of words model to build something known as a naive Bayes classifier. So what is a naive Bayes classifier? Well, it’s a tool that’s going to allow us to classify text based on Bayes rule, again, which you might remember from when we talked about probability. Bayes rule says that the probability of B given A is equal to the probability of A given B multiplied by the probability of B divided by the probability of A. So how are we going to use this rule to be able to analyze text? Well, what are we interested in? We’re interested in the probability that a message has a positive sentiment and the probability that a message has a negative sentiment, which I’m here for simplicity going to represent just with these emoji, happy face and frown face, as positive and negative sentiment. And so if I had a review, something like my grandson loved it, then what I’m interested in is not just the probability that a message has positive sentiment, but the conditional probability that a message has positive sentiment given that this is the message my grandson loved it. But how do I go about calculating this value, the probability that the message is positive given that the review is this sequence of words? Well, here’s where the bag of words model comes in. Rather than treat this review as a string of a sequence of words in order, we’re just going to treat it as an unordered collection of words. We’re going to try to calculate the probability that the review is positive given that all of these words, my grandson loved it, are in the review in no particular order, just this unordered collection of words. And this is a conditional probability, which we can then apply Bayes rule to try to make sense of. And so according to Bayes rule, this conditional probability is equal to what? It’s equal to the probability that all of these four words are in the review given that the review is positive multiplied by the probability that the review is positive divided by the probability that all of these words happen to be in the review. So this is the value now that we’re going to try to calculate. Now, one thing you might notice is that the denominator here, the probability that all of these words appear in the review, doesn’t actually depend on whether or not we’re looking at the positive sentiment or negative sentiment case. So we can actually get rid of this denominator. We don’t need to calculate it. We can just say that this probability is proportional to the numerator. And then at the end, we’re going to need to normalize the probability distribution to make sure that all of the values sum up to the value 1. So now, how do we calculate this value? Well, this is the probability of all of these words given positive times probability of positive. And that, by the definition of joint probability, is just one big joint probability, the probability that all of these things are the case, that it’s a positive review, and that all four of these words are in the review. But still, it’s not entirely obvious how we calculate that value. And here is where we need to make one more assumption. And this is where the naive part of naive Bayes comes in. We’re going to make the assumption that all of the words are independent of each other. And by that, I mean that if the word grandson is in the review, that doesn’t change the probability that the word loved is in the review or that the word it is in the review, for example. And in practice, this assumption might not be true. It’s almost certainly the case that the probability of words do depend on each other. But it’s going to simplify our analysis and still give us reasonably good results just to assume that the words are independent of each other and they only depend on whether it’s positive or negative. You might, for example, expect the word loved to appear more often in a positive review than in a negative review. So what does that mean? Well, if we make this assumption, then we can say that this value, the probability we’re interested in, is not directly proportional to, but it’s naively proportional to this value. The probability that the review is positive times the probability that my is in the review, given that it’s positive, times the probability that grandson is in the review, given that it’s positive, and so on for the other two words that happen to be in this review. And now this value, which looks a little more complex, is actually a value that we can calculate pretty easily. So how are we going to estimate the probability that the review is positive? Well, if we have some training data, some example data of example reviews where each one has already been labeled as positive or negative, then we can estimate the probability that a review is positive just by counting the number of positive samples and dividing by the total number of samples that we have in our training data. And for the conditional probabilities, the probability of loved, given that it’s positive, well, that’s going to be the number of positive samples with loved in it divided by the total number of positive samples. So let’s take a look at an actual example to see how we could try to calculate these values. Here I’ve put together some sample data. The way to interpret the sample data is that based on the training data, 49% of the reviews are positive, 51% are negative. And then over here in this table, we have some conditional probabilities. And then we have if the review is positive, then there is a 30% chance that my appears in it. And if the review is negative, there is a 20% chance that my appears in it. And based on our training data among the positive reviews, 1% of them contain the word grandson. And among the negative reviews, 2% contain the word grandson. So using this data, let’s try to calculate this value, the value we’re interested in. And to do that, we’ll need to multiply all of these values together. The probability of positive, and then all of these positive conditional probabilities. And when we do that, we get some value. And then we can do the same thing for the negative case. We’re going to do the same thing, take the probability that it’s negative, multiply it by all of these conditional probabilities, and we’re going to get some other value. And now these values don’t sum to one. They’re not a probability distribution yet. But I can normalize them and get some values. And that tells me that we’re going to predict that my grandson loved it. We think there’s a 68% chance, probability 0.68, that that is a positive sentiment review, and 0.32 probability that it’s a negative review. So what problems might we run into here? What could potentially go wrong when doing this kind of analysis in order to analyze whether text has a positive or negative sentiment? Well, a couple of problems might arise. One problem might be, what if the word grandson never appears for any of the positive reviews? If that were the case, then when we try to calculate the value, the probability that we think the review is positive, we’re going to multiply all these values together, and we’re just going to get 0 for the positive case, because we’re all going to ultimately multiply by that 0 value. And so we’re going to say that we think there is no chance that the review is positive because it contains the word grandson. And in our training data, we’ve never seen the word grandson appear in a positive sentiment message before. And that’s probably not the right analysis, because in cases of rare words, it might be the case that in nowhere in our training data did we ever see the word grandson appear in a message that has positive sentiment. So what can we do to solve this problem? Well, one thing we’ll often do is some kind of additive smoothing, where we add some value alpha to each value in our distribution just to smooth out the data a little bit. And a common form of this is Laplace smoothing, where we add 1 to each value in our distribution. In essence, we pretend we’ve seen each value one more time than we actually have. So if we’ve never seen the word grandson for a positive review, we pretend we’ve seen it once. If we’ve seen it once, we pretend we’ve seen it twice, just to avoid the possibility that we might multiply by 0 and as a result, get some results we don’t want in our analysis. So let’s see what this looks like in practice. Let’s try to do some naive Bayes classification in order to classify text as either positive or negative. We’ll take a look at sentiment.py. And what this is going to do is load some sample data into memory, some examples of positive reviews and negative reviews. And then we’re going to train a naive Bayes classifier on all of this training data, training data that includes all of the words we see in positive reviews and all of the words we see in negative reviews. And then we’re going to try to classify some input. And so we’re going to do this based on a corpus of data. I have some example positive reviews. Here are some positive reviews. It was great, so much fun, for example. And then some negative reviews, not worth it, kind of cheap. These are some examples of negative reviews. So now let’s try to run this classifier and see how it would classify particular text as either positive or negative. We’ll go ahead and run our sentiment analysis on this corpus. And we need to provide it with a review. So I’ll say something like, I enjoyed it. And we see that the classifier says there is about a 0.92 probability that we think that this particular review is positive. Let’s try something negative. We’ll try kind of overpriced. And we see that there is a 0.96 probability now that we think that this particular review is negative. And so our naive Bayes classifier has learned what kinds of words tend to appear in positive reviews and what kinds of words tend to appear in negative reviews. And as a result of that, we’ve been able to design a classifier that can predict whether a particular review is positive or negative. And so this definitely is a useful tool that we can use to try and make some predictions. But we had to make some assumptions in order to get there. So what if we want to now try to build some more sophisticated models, use some tools from machine learning to try and take better advantage of language data to be able to draw more accurate conclusions and solve new kinds of tasks and new kinds of problems? Well, we’ve seen a couple of times now that when we want to take some data and take some input, put it in a way that the computer is going to be able to make sense of, it can be helpful to take that data and turn it into numbers, ultimately. And so what we might want to try to do is come up with some word representation, some way to take a word and translate its meaning into numbers. Because, for example, if we wanted to use a neural network to be able to process language, give our language to a neural network and have it make some predictions or perform some analysis there, a neural network takes its input and produces its output a vector of values, a vector of numbers. And so what we might want to do is take our data and somehow take words and convert them into some kind of numeric representation. So how might we do that? How might we take words and turn them into numbers? Let’s take a look at an example. Here’s a sentence, he wrote a book. And let’s say I wanted to take each of those words and turn it into a vector of values. Here’s one way I might do that. We’ll say he is going to be a vector that has a 1 in the first position and the rest of the values are 0. Wrote will have a 1 in the second position and the rest of the values are 0. A has a 1 in the third position with the rest of the value 0. And book has a 1 in the fourth position with the rest of the value 0. So each of these words now has a distinct vector representation. And this is what we often call a one-hot representation, a representation of the meaning of a word as a vector with a single 1 and all of the rest of the values are 0. And so when doing this, we now have a numeric representation for every word and we could pass in those vector representations into a neural network or other models that require some kind of numeric data as input. But this one-hot representation actually has a couple of problems and it’s not ideal for a few reasons. One reason is, here we’re just looking at four words. But if you imagine a vocabulary of thousands of words or more, these vectors are going to get quite long in order to have a distinct vector for every possible word in a vocabulary. And as a result of that, these longer vectors are going to be more difficult to deal with, more difficult to train, and so forth. And so that might be a problem. Another problem is a little bit more subtle. If we want to represent a word as a vector, and in particular the meaning of a word as a vector, then ideally it should be the case that words that have similar meanings should also have similar vector representations, so that they’re close to each other together inside a vector space. But that’s not really going to be the case with these one-hot representations, because if we take some similar words, say the word wrote and the word authored, which means similar things, they have entirely different vector representations. Likewise, book and novel, those two words mean somewhat similar things, but they have entirely different vector representations because they each have a one in some different position. And so that’s not ideal either. So what we might be interested in instead is some kind of distributed representation. A distributed representation is the representation of the meaning of a word distributed across multiple values, instead of just being one-hot with a one in one position. Here is what a distributed representation of words might be. Each word is associated with some vector of values, with the meaning distributed across multiple values, ideally in such a way that similar words have a similar vector representation. But how are we going to come up with those values? Where do those values come from? How can we define the meaning of a word in this distributed sequence of numbers? Well, to do that, we’re going to draw inspiration from a quote from British linguist J.R. Firth, who said, you shall know a word by the company it keeps. In other words, we’re going to define the meaning of a word based on the words that appear around it, the context words around it. Take, for example, this context, for blank he ate. You might wonder, what words could reasonably fill in that blank? Well, it might be words like breakfast or lunch or dinner. All of those could reasonably fill in that blank. And so what we’re going to say is because the words breakfast and lunch and dinner appear in a similar context, that they must have a similar meaning. And that’s something our computer could understand and try to learn. A computer could look at a big corpus of text, look at what words tend to appear in similar context to each other, and use that to identify which words have a similar meaning and should therefore appear close to each other inside a vector space. And so one common model for doing this is known as the word to vec model. It’s a model for generating word vectors, a vector representation for every word by looking at data and looking at the context in which a word appears. The idea is going to be this. If you start out with all of the words just in some random position in space and train it on some training data, what the word to vec model will do is start to learn what words appear in similar contexts. And it will move these vectors around in such a way that hopefully words with similar meanings, breakfast, lunch, and dinner, book, memoir, novel, will hopefully appear to be near to each other as vectors as well. So let’s now take a look at what word to vec might look like in practice when implemented in code. What I have here inside of words.txt is a pre-trained model where each of these words has some vector representation trained by word to vec. Each of these words has some sequence of values representing its meaning, hopefully in such a way that similar words are represented by similar vectors. I also have this file vectors.py, which is going to open up the words and form them into a dictionary. And we also define some useful functions like distance to get the distance between two word vectors and closest words to find which words are nearby in terms of having close vectors to each other. And so let’s give this a try. We’ll go ahead and open a Python interpreter. And I’m going to import these vectors. And we might say, all right, what is the vector representation of the word book? And we get this big long vector that represents the word book as a sequence of values. And this sequence of values by itself is not all that meaningful. But it is meaningful in the context of comparing it to other vectors for other words. So we could use this distance function, which is going to get us the distance between two word vectors. And we might say, what is the distance between the vector representation for the word book and the vector representation for the word novel? And we see that it’s 0.34. You can kind of interpret 0 as being really close together and 1 being very far apart. And so now, what is the distance between book and, let’s say, breakfast? Well, book and breakfast are more different from each other than book and novel are. So I would hopefully expect the distance to be larger. And in fact, it is 0.64 approximately. These two words are further away from each other. And what about now the distance between, let’s say, lunch and breakfast? Well, that’s about 0.2. Those are even closer together. They have a meaning that is closer to each other. Another interesting thing we might do is calculate the closest words. We might say, what are the closest words, according to Word2Vec, to the word book? And let’s say, let’s get the 10 closest words. What are the 10 closest vectors to the vector representation for the word book? And when we perform that analysis, we get this list of words. The closest one is book itself, but we also have books plural, and then essay, memoir, essays, novella, anthology, and so on. All of these words mean something similar to the word book, according to Word2Vec, at least, because they have a similar vector representation. So it seems like we’ve done a pretty good job of trying to capture this kind of vector representation of word meaning. One other interesting side effect of Word2Vec is that it’s also able to capture something about the relationships between words as well. Let’s take a look at an example. Here, for instance, are two words, man and king. And these are each represented by Word2Vec as vectors. So what might happen if I subtracted one from the other, calculated the value king minus man? Well, that will be the vector that will take us from man to king, somehow represent this relationship between the vector representation of the word man and the vector representation of the word king. And that’s what this value, king minus man, represents. So what would happen if I took the vector representation of the word woman and added that same value, king minus man, to it? What would we get as the closest word to that, for example? Well, we could try it. Let’s go ahead and go back to our Python interpreter and give this a try. I could say, what is the closest word to the vector representation of the word king minus the representation of the word man plus the representation of the word woman? And we see that the closest word is the word queen. We’ve somehow been able to capture the relationship between king and man. And then when we apply it to the word woman, we get, as the result, the word queen. So Word2Vec has been able to capture not just the words and how they’re similar to each other, but also something about the relationships between words and how those words are connected to each other. So now that we have this vector representation of words, what can we now do with it? Now we can represent words as numbers. And so we might try to pass those words as input to, say, a neural network. Neural networks we’ve seen are very powerful tools for identifying patterns and making predictions. Recall that a neural network you can think of as all of these units. But really what the neural network is doing is taking some input, passing it into the network, and then producing some output. And by providing the neural network with training data, we’re able to update the weights inside of the network so that the neural network can do a more accurate job of translating those inputs into those outputs. And now that we can represent words as numbers that could be the input or output, you could imagine passing a word in as input to a neural network and getting a word as output. And so when might that be useful? One common use for neural networks is in machine translation, when we want to translate text from one language into another, say translate English into French by passing English into the neural network and getting some French output. You might imagine, for instance, that we could take the English word for lamp, pass it into the neural network, get the French word for lamp as output. But in practice, when we’re translating text from one language to another, we’re usually not just interested in translating a single word from one language to another, but a sequence, say a sentence or a paragraph of words. Here, for example, is another paragraph, again taken from Sherlock Holmes, written in English. And what I might want to do is take that entire sentence, pass it into the neural network, and get as output a French translation of the same sentence. But recall that a neural network’s input and output needs to be of some fixed size. And a sentence is not a fixed size. It’s variable. You might have shorter sentences, and you might have longer sentences. So somehow, we need to solve the problem of translating a sequence into another sequence by means of a neural network. And that’s going to be true not only for machine translation, but also for other problems, problems like question answering. If I want to pass as input a question, something like what is the capital of Massachusetts, feed that as input into the neural network, I would hope that what I would get as output is a sentence like the capital is Boston, again, translating some sequence into some other sequence. And if you’ve ever had a conversation with an AI chatbot, or have ever asked your phone a question, it needs to do something like this. It needs to understand the sequence of words that you, the human, provided as input. And then the computer needs to generate some sequence of words as output. So how can we do this? Well, one tool that we can use is the recurrent neural network, which we took a look at last time, which is a way for us to provide a sequence of values to a neural network by running the neural network multiple times. And each time we run the neural network, what we’re going to do is we’re going to keep track of some hidden state. And that hidden state is going to be passed from one run of the neural network to the next run of the neural network, keeping track of all of the relevant information. And so let’s take a look at how we can apply that to something like this. And in particular, we’re going to look at an architecture known as an encoder-decoder architecture, where we’re going to encode this question into some kind of hidden state, and then use a decoder to decode that hidden state into the output that we’re interested in. So what’s that going to look like? We’ll start with the first word, the word what. That goes into our neural network, and it’s going to produce some hidden state. This is some information about the word what that our neural network is going to need to keep track of. Then when the second word comes along, we’re going to feed it into that same encoder neural network, but it’s going to get as input that hidden state as well. So we pass in the second word. We also get the information about the hidden state, and that’s going to continue for the other words in the input. This is going to produce a new hidden state. And so then when we get to the third word, the, that goes into the encoder. It also gets access to the hidden state, and then it produces a new hidden state that gets passed into the next run when we use the word capital. And the same thing is going to repeat for the other words that appear in the input. So of Massachusetts, that produces one final piece of hidden state. Now somehow, we need to signal the fact that we’re done. There’s nothing left in the input. And we typically do this by passing some kind of special token, say an end token, into the neural network. And now the decoding process is going to start. We’re going to generate the word the. But in addition to generating the word the, this decoder network is also going to generate some kind of hidden state. And so what happens the next time? Well, to generate the next word, it might be helpful to know what the first word was. So we might pass the first word the back into the decoder network. It’s going to get as input this hidden state, and it’s going to generate the next word capital. And that’s also going to generate some hidden state. And we’ll repeat that, passing capital into the network to generate the third word is, and then one more time in order to get the fourth word Boston. And at that point, we’re done. But how do we know we’re done? Usually, we’ll do this one more time, pass Boston into the decoder network, and get an output some end token to indicate that that is the end of our input. And so this then is how we could use a recurrent neural network to take some input, encode it into some hidden state, and then use that hidden state to decode it into the output we’re interested in. To visualize it in a slightly different way, we have some input sequence. This is just some sequence of words. That input sequence goes into the encoder, which in this case is a recurrent neural network generating these hidden states along the way until we generate some final hidden state, at which point we start the decoding process. Again, using a recurrent neural network, that’s going to generate the output sequence as well. So we’ve got the encoder, which is encoding the information about the input sequence into this hidden state, and then the decoder, which takes that hidden state and uses it in order to generate the output sequence. But there are some problems. And for many years, this was the state of the art. The recurrent neural network and variance on this approach were some of the best ways we knew in order to perform tasks in natural language processing. But there are some problems that we might want to try to deal with and that have been dealt with over the years to try and improve upon this kind of model. And one problem you might notice happens in this encoder stage. We’ve taken this input sequence, the sequence of words, and encoded it all into this final piece of hidden state. And that final piece of hidden state needs to contain all of the information from the input sequence that we need in order to generate the output sequence. And while that’s possible, it becomes increasingly difficult as the sequence gets larger and larger. For larger and larger input sequences, it’s going to become more and more difficult to store all of the information we need about the input inside this single hidden state piece of context. That’s a lot of information to pack into just a single value. It might be useful for us, when generating output, to not just refer to this one value, but to all of the previous hidden values that have been generated by the encoder. And so that might be useful, but how could we do that? We’ve got a lot of different values. We need to combine them somehow. So you could imagine adding them together, taking the average of them, for example. But doing that would assume that all of these pieces of hidden state are equally important. But that’s not necessarily true either. Some of these pieces of hidden state are going to be more important than others, depending on what word they most closely correspond to. This piece of hidden state very closely corresponds to the first word of the input sequence. This one very closely corresponds to the second word of the input sequence, for example. And some of those are going to be more important than others. To make matters more complicated, depending on which word of the output sequence we’re generating, different input words might be more or less important. And so what we really want is some way to decide for ourselves which of the input values are worth paying attention to, at what point in time. And this is the key idea behind a mechanism known as attention. Attention is all about letting us decide which values are important to pay attention to, when generating, in this case, the next word in our sequence. So let’s take a look at an example of that. Here’s a sentence. What is the capital of Massachusetts? Same sentence as before. And let’s imagine that we were trying to answer that question by generating tokens of output. So what would the output look like? Well, it’s going to look like something like the capital is. And let’s say we’re now trying to generate this last word here. What is that last word? How is the computer going to figure it out? Well, what it’s going to need to do is decide which values it’s going to pay attention to. And so the attention mechanism will allow us to calculate some attention scores for each word, some value corresponding to each word, determining how relevant is it for us to pay attention to that word right now? And in this case, when generating the fourth word of the output sequence, the most important words to pay attention to might be capital and Massachusetts, for example. That those words are going to be particularly relevant. And there are a number of different mechanisms that have been used in order to calculate these attention scores. It could be something as simple as a dot product to see how similar two vectors are, or we could train an entire neural network to calculate these attention scores. But the key idea is that during the training process for our neural network, we’re going to learn how to calculate these attention scores. Our model is going to learn what is important to pay attention to in order to decide what the next word should be. So the result of all of this, calculating these attention scores, is that we can calculate some value, some value for each input word, determining how important is it for us to pay attention to that particular value. And recall that each of these input words is also associated with one of these hidden state context vectors, capturing information about the sentence up to that point, but primarily focused on that word in particular. And so what we can now do is if we have all of these vectors and we have values representing how important is it for us to pay attention to those particular vectors, is we can take a weighted average. We can take all of these vectors, multiply them by their attention scores, and add them up to get some new vector value, which is going to represent the context from the input, but specifically paying attention to the words that we think are most important. And once we’ve done that, that context vector can be fed into our decoder in order to say that the word should be, in this case, Boston. So attention is this very powerful tool that allows any word when we’re trying to decode it to decide which words from the input should we pay attention to in order to determine what’s important for generating the next word of the output. And one of the first places this was really used was in the field of machine translation. Here’s an example of a diagram from the paper that introduced this idea, which was focused on trying to translate English sentences into French sentences. So we have an input English sentence up along the top, and then along the left side, the output French equivalent of that same sentence. And what you see in all of these squares are the attention scores visualized, where a lighter square indicates a higher attention score. And what you’ll notice is that there’s a strong correspondence between the French word and the equivalent English word, that the French word for agreement is really paying attention to the English word for agreement in order to decide what French word should be generated at that point in time. And sometimes you might pay attention to multiple words if you look at the French word for economic. That’s primarily paying attention to the English word for economic, but also paying attention to the English word for European in this case too. And so attention scores are very easy to visualize to get a sense for what is our machine learning model really paying attention to, what information is it using in order to determine what’s important and what’s not in order to determine what the ultimate output token should be. And so when we combine the attention mechanism with a recurrent neural network, we can get very powerful and useful results where we’re able to generate an output sequence by paying attention to the input sequence too. But there are other problems with this approach of using a recurrent neural network as well. In particular, notice that every run of the neural network depends on the output of the previous step. And that was important for getting a sense for the sequence of words and the ordering of those particular words. But we can’t run this unit of the neural network until after we’ve calculated the hidden state from the run before it from the previous input token. And what that means is that it’s very difficult to parallelize this process. That as the input sequence get longer and longer, we might want to use parallelism to try and speed up this process of training the neural network and making sense of all of this language data. But it’s difficult to do that. And it’s slow to do that with a recurrent neural network because all of it needs to be performed in sequence. And that’s become an increasing challenge as we’ve started to get larger and larger language models. The more language data that we have available to us to use to train our machine learning models, the more accurate it can be, the better representation of language it can have, the better understanding it can have, and the better results that we can see. And so we’ve seen this growth of large language models that are using larger and larger data sets. But as a result, they take longer and longer to train. And so this problem that recurrent neural networks are not easy to parallelize has become an increasing problem. And as a result of that, that was one of the main motivations for a different architecture, for thinking about how to deal with natural language. And that’s known as the transformer architecture. And this has been a significant milestone in the world of natural language processing for really increasing how well we can perform these kinds of natural language processing tasks, as well as how quickly we can train a machine learning model to be able to produce effective results. There are a number of different types of transformers in terms of how they work. But what we’re going to take a look at here is the basic architecture for how one might work with a transformer to get a sense for what’s involved and what we’re doing. So let’s start with the model we were looking at before, specifically at this encoder part of our encoder-decoder architecture, where we used a recurrent neural network to take this input sequence and capture all of this information about the hidden state and the information we need to know about that input sequence. Right now, it all needs to happen in this linear progression. But what the transformer is going to allow us to do is process each of the words independently in a way that’s easy to parallelize, rather than have each word wait for some other word. Each word is going to go through this same neural network and produce some kind of encoded representation of that particular input word. And all of this is going to happen in parallel. Now, it’s happening for all of the words at once, but we’re really just going to focus on what’s happening for one word to make it clear. But know that whatever you’re seeing happen for this one word is going to happen for all of the other input words, too. So what’s going on here? Well, we start with some input word. That input word goes into the neural network. And the output is hopefully some encoded representation of the input word, the information we need to know about the input word that’s going to be relevant to us as we’re generating the output. And because we’re doing this each word independently, it’s easy to parallelize. We don’t have to wait for the previous word before we run this word through the neural network. But what did we lose in this process by trying to parallelize this whole thing? Well, we’ve lost all notion of word ordering. The order of words is important. The sentence, Sherlock Holmes gave the book to Watson, has a different meaning than Watson gave the book to Sherlock Holmes. And so we want to keep track of that information about word position. In the recurrent neural network, that happened for us automatically because we could run each word one at a time through the neural network, get the hidden state, pass it on to the next run of the neural network. But that’s not the case here with the transformer, where each word is being processed independent of all of the other ones. So what are we going to do to try to solve that problem? One thing we can do is add some kind of positional encoding to the input word. The positional encoding is some vector that represents the position of the word in the sentence. This is the first word, the second word, the third word, and so forth. We’re going to add that to the input word. And the result of that is going to be a vector that captures multiple pieces of information. It captures the input word itself as well as where in the sentence it appears. The result of that is we can pass the output of that addition, the addition of the input word and the positional encoding into the neural network. That way, the neural network knows the word and where it appears in the sentence and can use both of those pieces of information to determine how best to represent the meaning of that word in the encoded representation at the end of it. In addition to what we have here, in addition to the positional encoding and this feed forward neural network, we’re also going to add one additional component, which is going to be a self-attention step. This is going to be attention where we’re paying attention to the other input words. Because the meaning or interpretation of an input word might vary depending on the other words in the input as well. And so we’re going to allow each word in the input to decide what other words in the input it should pay attention to in order to decide on its encoded representation. And that’s going to allow us to get a better encoded representation for each word because words are defined by their context, by the words around them and how they’re used in that particular context. This kind of self-attention is so valuable, in fact, that oftentimes the transformer will use multiple different self-attention layers at the same time to allow for this model to be able to pay attention to multiple facets of the input at the same time. And we call this multi-headed attention, where each attention head can pay attention to something different. And as a result, this network can learn to pay attention to many different parts of the input for this input word all at the same time. And in the spirit of deep learning, these two steps, this multi-headed self-attention layer and this neural network layer, that itself can be repeated multiple times, too, in order to get a deeper representation, in order to learn deeper patterns within the input text and ultimately get a better representation of language in order to get useful encoded representations of all of the input words. And so this is the process that a transformer might use in order to take an input word and get it its encoded representation. And the key idea is to really rely on this attention step in order to get information that’s useful in order to determine how to encode that word. And that process is going to repeat for all of the input words that are in the input sequence. We’re going to take all of the input words, encode them with some kind of positional encoding, feed those into these self-attention and feed-forward neural networks in order to ultimately get these encoded representations of the words. That’s the result of the encoder. We get all of these encoded representations that will be useful to us when it comes time then to try to decode all of this information into the output sequence we’re interested in. And again, this might take place in the context of machine translation, where the output is going to be the same sentence in a different language, or it might be an answer to a question in the case of an AI chatbot, for example. And so now let’s take a look at how that decoder is going to work. Ultimately, it’s going to have a very similar structure. Any time we’re trying to generate the next output word, we need to know what the previous output word is, as well as its positional encoding. Where in the output sequence are we? And we’re going to have these same steps, self-attention, because we might want an output word to be able to pay attention to other words in that same output, as well as a neural network. And that might itself repeat multiple times. But in this decoder, we’re going to add one additional step. We’re going to add an additional attention step, where instead of self-attention, where the output word is going to pay attention to other output words, in this step, we’re going to allow the output word to pay attention to the encoded representations. So recall that the encoder is taking all of the input words and transforming them into these encoded representations of all of the input words. But it’s going to be important for us to be able to decide which of those encoded representations we want to pay attention to when generating any particular token in the output sequence. And that’s what this additional attention step is going to allow us to do. It’s saying that every time we’re generating a word of the output, we can pay attention to the other words in the output, because we might want to know, what are the words we’ve generated previously? And we want to pay attention to some of them to decide what word is going to be next in the sequence. But we also care about paying attention to the input words, too. And we want the ability to decide which of these encoded representations of the input words are going to be relevant in order for us to generate the next step. And so these two pieces combine together. We have this encoder that takes all of the input words and produces this encoded representation. And we have this decoder that is able to take the previous output word, pay attention to that encoded input, and then generate the next output word. And this is one of the possible architectures we could use for a transformer, with the key idea being these attention steps that allow words to pay attention to each other. During the training process here, we can now much more easily parallelize this, because we don’t have to wait for all of the words to happen in sequence. And we can learn how we should perform these attention steps. The model is able to learn what is important to pay attention to, what things do I need to pay attention to, in order to be more accurate at predicting what the output word is. And this has proved to be a tremendously effective model for conversational AI agents, for building machine translation systems. And there have been many variants proposed on this model, too. Some transformers only use an encoder. Some only use a decoder. Some use some other combination of these different particular features. But the key ideas ultimately remain the same, this real focus on trying to pay attention to what is most important. And the world of natural language processing is fast growing and fast evolving. Year after year, we keep coming up with new models that allow us to do an even better job of performing these natural language related tasks, all on the surface of solving the tricky problem, which is our own natural language. We’ve seen how the syntax and semantics of our language is ambiguous, and it introduces all of these new challenges that we need to think about, if we’re going to be able to design AI agents that are able to work with language effectively. So as we think about where we’ve been in this class, all of the different types of artificial intelligence we’ve considered, we’ve looked at artificial intelligence in a wide variety of different forms now. We started by taking a look at search problems, where we looked at how AI can search for solutions, play games, and find the optimal decision to make. We talked about knowledge, how AI can represent information that it knows and use that information to generate new knowledge as well. Then we looked at what AI can do when it’s less certain, when it doesn’t know things for sure, and we have to represent things in terms of probability. We then took a look at optimization problems. We saw how a lot of problems in AI can be boiled down to trying to maximize or minimize some function. And we looked at strategies that AI can use in order to do that kind of maximizing and minimizing. We then looked at the world of machine learning, learning from data in order to figure out some patterns and identify how to perform a task by looking at the training data that we have available to it. And one of the most powerful tools there was the neural network, the sequence of units whose weights can be trained in order to allow us to really effectively go from input to output and predict how to get there by learning these underlying patterns. And then today, we took a look at language itself, trying to understand how can we train the computer to be able to understand our natural language, to be able to understand syntax and semantics, make sense of and generate natural language, which introduces a number of interesting problems too. And we’ve really just scratched the surface of artificial intelligence. There is so much interesting research and interesting new techniques and algorithms and ideas being introduced to try to solve these types of problems. So I hope you enjoyed this exploration into the world of artificial intelligence. A huge thanks to all of the course’s teaching staff and production team for making the class possible. This was an introduction to artificial intelligence with Python.

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog